linux/fs/nfs
NeilBrown f16857e62b NFS: unlink/rmdir shouldn't call d_delete() twice on ENOENT
nfs_unlink() calls d_delete() twice if it receives ENOENT from the
server - once in nfs_dentry_handle_enoent() from nfs_safe_remove and
once in nfs_dentry_remove_handle_error().

nfs_rmddir() also calls it twice - the nfs_dentry_handle_enoent() call
is direct and inside a region locked with ->rmdir_sem

It is safe to call d_delete() twice if the refcount > 1 as the dentry is
simply unhashed.
If the refcount is 1, the first call sets d_inode to NULL and the second
call crashes.

This patch guards the d_delete() call from nfs_dentry_handle_enoent()
leaving the one under ->remdir_sem in case that is important.

In mainline it would be safe to remove the d_delete() call.  However in
older kernels to which this might be backported, that would change the
behaviour of nfs_unlink().  nfs_unlink() used to unhash the dentry which
resulted in nfs_dentry_handle_enoent() not calling d_delete().  So in
older kernels we need the d_delete() in nfs_dentry_remove_handle_error()
when called from nfs_unlink() but not when called from nfs_rmdir().

To make the code work correctly for old and new kernels, and from both
nfs_unlink() and nfs_rmdir(), we protect the d_delete() call with
simple_positive().  This ensures it is never called in a circumstance
where it could crash.

Fixes: 3c59366c20 ("NFS: don't unhash dentry during unlink/rename")
Fixes: 9019fb391d ("NFS: Label the dentry with a verifier in nfs_rmdir() and nfs_unlink()")
Signed-off-by: NeilBrown <neilb@suse.de>
Tested-by: Olga Kornievskaia <aglo@umich.edu>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2022-08-19 20:31:36 -04:00
..
blocklayout nfs/blocklayout: refactor block device opening 2022-07-12 10:05:21 -04:00
filelayout pNFS/files: Handle RDMA connection errors correctly 2022-07-10 19:00:53 -04:00
flexfilelayout NFS: Allow setting rsize / wsize to a multiple of PAGE_SIZE 2022-07-12 10:53:10 -04:00
cache_lib.c
cache_lib.h
callback.c NFSD: Move svc_serv_ops::svo_function into struct svc_serv 2022-02-28 10:26:40 -05:00
callback.h NFSv4.1: Fix uninitialised variable in devicenotify 2022-01-06 14:00:20 -05:00
callback_proc.c pNFS: Avoid a live lock condition in pnfs_update_layout() 2022-06-06 11:53:55 -04:00
callback_xdr.c NFS: remove unneeded check in decode_devicenotify_args() 2022-03-13 12:59:34 -04:00
client.c NFS: Allow setting rsize / wsize to a multiple of PAGE_SIZE 2022-07-12 10:53:10 -04:00
delegation.c NFSv4: Charge NFSv4 open state trackers to kmemcg 2022-02-25 18:50:12 -05:00
delegation.h NFSv4: Fix delegation return in cases where we have to retry 2021-06-13 19:36:27 -04:00
dir.c NFS: unlink/rmdir shouldn't call d_delete() twice on ENOENT 2022-08-19 20:31:36 -04:00
direct.c nfs: only issue commit in DIO codepath if we have uncommitted data 2022-07-23 15:28:59 -04:00
dns_resolve.c NFS: remove duplicate headers 2020-05-27 10:10:12 -04:00
dns_resolve.h
export.c nfs: block notification on fs with its own ->lock 2022-01-08 14:42:01 -05:00
file.c NFS: Fix another fsync() issue after a server reboot 2022-08-13 13:02:13 -04:00
fs_context.c NFS: Replace fs_context-related dprintk() call sites with tracepoints 2022-07-23 15:34:40 -04:00
fscache.c NFS: Pass i_size to fscache_unuse_cookie() when a file is released 2022-05-17 15:39:45 -04:00
fscache.h nfs: Convert to release_folio 2022-05-09 23:12:33 -04:00
getroot.c NFS: Remove the nfs4_label argument from nfs_setsecurity 2021-11-05 14:54:40 -04:00
inode.c NFS: Fix another fsync() issue after a server reboot 2022-08-13 13:02:13 -04:00
internal.h nfs: add new nfs_direct_req tracepoint events 2022-07-23 15:28:59 -04:00
io.c NFS: Fix up incorrect documentation 2021-04-05 09:04:20 -04:00
iostat.h
Kconfig NFS: Replace readdir's use of xxhash() with hash_64() 2022-04-07 16:19:47 -04:00
Makefile nfs: Convert to new fscache volume/cookie API 2022-01-10 11:53:25 +00:00
mount_clnt.c nfs: hornor timeo and retrans option when mounting NFSv3 2021-04-05 09:04:21 -04:00
namespace.c NFS: Remove the label from the nfs4_lookup_res struct 2021-11-05 14:54:39 -04:00
netns.h NFS: Add sysfs support for per-container identifier 2019-07-06 14:54:49 -04:00
nfs.h
nfs2super.c
nfs2xdr.c NFS: Optimise away the previous cookie field 2022-03-02 08:43:39 -05:00
nfs3_fs.h vfs: add rcu argument to ->get_acl() callback 2021-08-18 22:08:24 +02:00
nfs3acl.c vfs: add rcu argument to ->get_acl() callback 2021-08-18 22:08:24 +02:00
nfs3client.c Revert "pNFS: nfs3_set_ds_client should set NFS_CS_NOPING" 2022-07-10 19:00:53 -04:00
nfs3proc.c NFS: pass cred explicitly for access tests 2022-01-06 14:00:20 -05:00
nfs3super.c
nfs3xdr.c NFS: Optimise away the previous cookie field 2022-03-02 08:43:39 -05:00
nfs4_fs.h NFSv4: keep state manager thread active if swap is enabled 2022-03-13 12:59:35 -04:00
nfs4client.c NFS: Allow setting rsize / wsize to a multiple of PAGE_SIZE 2022-07-12 10:53:10 -04:00
nfs4file.c NFSv4: Add FMODE_CAN_ODIRECT after successful open of a NFS4.x file 2022-06-15 15:03:12 -04:00
nfs4getroot.c
nfs4idmap.c NFSv4: Fix races in the legacy idmapper upcall 2022-07-13 17:46:52 -04:00
nfs4idmap.h
nfs4namespace.c NFSv4: Fix free of uninitialized nfs4_label on referral lookup. 2022-05-31 17:09:24 -04:00
nfs4proc.c NFSv4/pnfs: Fix a use-after-free bug in open 2022-08-02 16:04:29 -04:00
nfs4renewd.c treewide: remove editor modelines and cruft 2021-05-07 00:26:34 -07:00
nfs4session.c NFSv4: Sanity check the parameters in nfs41_update_target_slotid() 2021-11-07 09:23:14 -05:00
nfs4session.h NFSv4: Sanity check the parameters in nfs41_update_target_slotid() 2021-11-07 09:23:14 -05:00
nfs4state.c NFS: restore module put when manager exits. 2022-06-30 16:13:00 -04:00
nfs4super.c NFS: Adjust fs_context error logging 2021-01-10 13:32:39 -05:00
nfs4sysctl.c
nfs4trace.c pNFS/flexfiles: Add tracing for layout errors 2020-01-15 10:54:33 -05:00
nfs4trace.h NFSv4.2 add tracepoint to OFFLOAD_CANCEL 2021-11-04 19:43:30 -04:00
nfs4xdr.c NFSv4: Fix free of uninitialized nfs4_label on referral lookup. 2022-05-31 17:09:24 -04:00
nfs42.h NFSv4.2: add the extended attribute proc functions. 2020-07-13 17:52:45 -04:00
nfs42proc.c NFS: replace usage of found with dedicated list iterator variable 2022-03-24 12:06:07 -04:00
nfs42xattr.c NFSv4.2: Fix missing removal of SLAB_ACCOUNT on kmem_cache allocation 2022-04-07 16:20:00 -04:00
nfs42xdr.c NFS: Replace the READ_PLUS decoding code 2022-07-23 15:38:29 -04:00
nfsroot.c nfsroot: Default mount option should ask for built-in NFS version 2020-11-02 10:29:03 -05:00
nfstrace.c NFSv4: Catch and trace server filehandle encoding errors 2021-04-14 09:36:29 -04:00
nfstrace.h NFS: Improve readpage/writepage tracing 2022-08-09 14:11:34 -04:00
pagelist.c NFSv4.1 mark qualified async operations as MOVEABLE tasks 2022-05-31 17:09:30 -04:00
pnfs.c NFS: Remove a bogus flag setting in pnfs_write_done_resend_to_mds 2022-08-13 13:02:14 -04:00
pnfs.h pNFS: Avoid a live lock condition in pnfs_update_layout() 2022-06-06 11:53:55 -04:00
pnfs_dev.c NFSv4/pnfs: Add tracing for the deviceid cache 2020-12-16 17:25:24 -05:00
pnfs_nfs.c NFS: nfsiod should not block forever in mempool_alloc() 2022-03-22 15:52:56 -04:00
proc.c NFS: NFSv2/v3 clients should never be setting NFS_CAP_XATTR 2022-02-25 18:50:13 -05:00
read.c nfs: Convert nfs to read_folio 2022-05-09 16:21:46 -04:00
super.c nfs: Convert to new fscache volume/cookie API 2022-01-10 11:53:25 +00:00
symlink.c fs: Change the type of filler_t 2022-05-09 16:36:48 -04:00
sysctl.c
sysfs.c Revert "NFSv4: use unique client identifiers in network namespaces" 2022-02-28 10:09:23 -05:00
sysfs.h NFSv4: Fix up RCU annotations for struct nfs_netns_client 2020-10-15 13:31:08 -04:00
unlink.c NFSv4.1 mark qualified async operations as MOVEABLE tasks 2022-05-31 17:09:30 -04:00
write.c NFS: Fix another fsync() issue after a server reboot 2022-08-13 13:02:13 -04:00