From 010df42bf56ec012dfcdf9ff984efc4843796b44 Mon Sep 17 00:00:00 2001 From: Mauricio Faria de Oliveira Date: Tue, 19 Nov 2019 20:05:54 +0000 Subject: [PATCH] Check for unlinked znodes after igrab() The changes in commit 41e1aa2a / PR#9583 introduced a regression on tmpfile_001_pos: fsetxattr() on a O_TMPFILE file descriptor started to fail with errno ENODATA: openat(AT_FDCWD, "/test", O_RDWR|O_TMPFILE, 0666) = 3 <...> fsetxattr(3, "user.test", <...>, 64, 0) = -1 ENODATA The originally proposed change on PR#9583 is not susceptible to it, so just move the code/if-checks around back in that way, to fix it. $ export TESTDIR="/test" # zfs mountpoint Before that commit: $ cat /sys/module/zfs/version 0.8.0-401_gcc1a1e17 $ /usr/share/zfs/zfs-tests/tests/functional/tmpfile/tmpfile_001_pos Verify O_TMPFILE is working properly. $ echo $? 0 After that commit: $ cat /sys/module/zfs/version 0.8.0-402_g41e1aa2a $ /usr/share/zfs/zfs-tests/tests/functional/tmpfile/tmpfile_001_pos Verify O_TMPFILE is working properly. fsetxattr: No data available $ echo $? 6 With this commit: $ cat /sys/module/zfs/version 0.8.0-405_g... $ /usr/share/zfs/zfs-tests/tests/functional/tmpfile/tmpfile_001_pos Verify O_TMPFILE is working properly. $ echo $? 0 Original-patch-by: Heitor Alves de Siqueira Signed-off-by: Mauricio Faria de Oliveira --- module/os/linux/zfs/zfs_znode.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c index c623d61f7066..30ceccc2b57b 100644 --- a/module/os/linux/zfs/zfs_znode.c +++ b/module/os/linux/zfs/zfs_znode.c @@ -1095,7 +1095,8 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) ASSERT3U(zp->z_id, ==, obj_num); /* * If zp->z_unlinked is set, the znode is already marked - * for deletion and should not be discovered. + * for deletion and should not be discovered. Check this + * after checking igrab() due to fsetxattr() & O_TMPFILE. * * If igrab() returns NULL the VFS has independently * determined the inode should be evicted and has @@ -1110,10 +1111,11 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) * need to detect the active SA hold thereby informing * the VFS that this inode should not be evicted. */ - if (zp->z_unlinked) { - err = SET_ERROR(ENOENT); - } else if (igrab(ZTOI(zp)) == NULL) { - err = SET_ERROR(EAGAIN); + if (igrab(ZTOI(zp)) == NULL) { + if (zp->z_unlinked) + err = SET_ERROR(ENOENT); + else + err = SET_ERROR(EAGAIN); } else { *zpp = zp; err = 0;