Page MenuHomeFreeBSD

ffs: do not return ESTALE on attempt to ffs_unotovp() on unlinked inode
ClosedPublic

Authored by kib on Wed, Jul 1, 1:47 AM.
Tags
None
Referenced Files
F161423052: D57982.diff
Fri, Jul 3, 2:48 PM
Unknown Object (File)
Thu, Jul 2, 1:07 PM
Unknown Object (File)
Thu, Jul 2, 1:07 PM
Unknown Object (File)
Thu, Jul 2, 1:07 PM
Unknown Object (File)
Thu, Jul 2, 1:06 PM
Unknown Object (File)
Thu, Jul 2, 1:06 PM
Unknown Object (File)
Thu, Jul 2, 1:06 PM
Unknown Object (File)
Thu, Jul 2, 1:06 PM
Subscribers

Details

Summary
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

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib requested review of this revision.Wed, Jul 1, 1:47 AM

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");
}

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.

This revision is now accepted and ready to land.Wed, Jul 1, 2:41 AM

So, if this patch results in behaviour consistent with
Linux, I think it is reasonable to do.

This, and I believe that the patch improves the internal UFS behavior regardless of the NFS, as I mentioned in the commit message.