The consequences are: - for nfs exports and fhopen(2), unlinked but still referenced inodes are accessible - for ffs_vput_pair() with unlock_vp = false, spurious ESTALE is not returned when the inode is still alive but unlinked Note that tmpfs does not return ESTALE for the unlinked nodes. The same behavior is claimed for Linux in https://github.com/openzfs/zfs/issues/18699
Details
Details
Diff Detail
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
Comment Actions
Test program
/* $Id: fhopen-unlink.c,v 1.1 2026/07/01 01:39:54 kostik Exp kostik $ */
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <err.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int
main(void)
{
fhandle_t fh;
struct stat st;
struct statfs fsst;
struct ufid ufh;
int fd, hfd;
static const char filename[] = "xXXXXx";
fd = open(filename, O_CREAT | O_RDWR, 0666);
if (fd == -1)
err(1, "creat");
if (unlink(filename) == -1)
err(1, "unlink");
if (fstat(fd, &st) == -1)
err(1, "stat");
if (fstatfs(fd, &fsst) == -1)
err(1, "fstatfs");
memset(&fh, 0, sizeof(fh));
memset(&ufh, 0, sizeof(ufh));
fh.fh_fsid = fsst.f_fsid;
ufh.ufid_len = sizeof(ufh);
ufh.ufid_ino = st.st_ino;
ufh.ufid_gen = st.st_gen;
memcpy(&fh.fh_fid, &ufh, sizeof(ufh));
hfd = fhopen(&fh, O_RDONLY);
if (hfd == -1)
err(1, "fhopen");
}Comment Actions
In the NFS game there are two things...
- The RFCs. They don't define exactly when an NFS server should return ESTALE, so I don't think either the current behaviour or the behaviour with this patch is incorrect.
- Linux. It has become the "defacto standard" for NFS. (Solaris once was the "defacto standard" but??)
So, if this patch results in behaviour consistent with
Linux, I think it is reasonable to do.
Comment Actions
This, and I believe that the patch improves the internal UFS behavior regardless of the NFS, as I mentioned in the commit message.