linux/fs/nfsd
Li Lingfeng ba903539ff nfsd: decrease sc_count directly if fail to queue dl_recall
[ Upstream commit a1d14d931b ]

A deadlock warning occurred when invoking nfs4_put_stid following a failed
dl_recall queue operation:
            T1                            T2
                                nfs4_laundromat
                                 nfs4_get_client_reaplist
                                  nfs4_anylock_blockers
__break_lease
 spin_lock // ctx->flc_lock
                                   spin_lock // clp->cl_lock
                                   nfs4_lockowner_has_blockers
                                    locks_owner_has_blockers
                                     spin_lock // flctx->flc_lock
 nfsd_break_deleg_cb
  nfsd_break_one_deleg
   nfs4_put_stid
    refcount_dec_and_lock
     spin_lock // clp->cl_lock

When a file is opened, an nfs4_delegation is allocated with sc_count
initialized to 1, and the file_lease holds a reference to the delegation.
The file_lease is then associated with the file through kernel_setlease.

The disassociation is performed in nfsd4_delegreturn via the following
call chain:
nfsd4_delegreturn --> destroy_delegation --> destroy_unhashed_deleg -->
nfs4_unlock_deleg_lease --> kernel_setlease --> generic_delete_lease
The corresponding sc_count reference will be released after this
disassociation.

Since nfsd_break_one_deleg executes while holding the flc_lock, the
disassociation process becomes blocked when attempting to acquire flc_lock
in generic_delete_lease. This means:
1) sc_count in nfsd_break_one_deleg will not be decremented to 0;
2) The nfs4_put_stid called by nfsd_break_one_deleg will not attempt to
acquire cl_lock;
3) Consequently, no deadlock condition is created.

Given that sc_count in nfsd_break_one_deleg remains non-zero, we can
safely perform refcount_dec on sc_count directly. This approach
effectively avoids triggering deadlock warnings.

Fixes: 230ca75845 ("nfsd: put dl_stid if fail to queue dl_recall")
Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2025-04-25 10:43:53 +02:00
..
acl.h NFSD: add posix ACLs to struct nfsd_attrs 2022-08-04 10:28:03 -04:00
auth.c nfsd: auth: Fix gid sorting when rootsquash enabled 2018-01-22 20:13:07 -08:00
auth.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
blocklayout.c nfsd: move nfserrno() to vfs.c 2024-03-06 14:45:15 +00:00
blocklayoutxdr.c nfsd: move nfserrno() to vfs.c 2024-03-06 14:45:15 +00:00
blocklayoutxdr.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cache.h nfsd: make all of the nfsd stats per-network namespace 2024-08-19 06:00:05 +02:00
current_stateid.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
export.c nfsd: make sure exp active before svc_export_show 2024-12-14 19:54:16 +01:00
export.h NFSD: Fix frame size warning in svc_export_parse() 2024-08-19 06:00:04 +02:00
fault_inject.c nfsd: no need to check return value of debugfs_create functions 2019-07-03 16:57:17 +02:00
filecache.c nfsd: add list_head nf_gc to struct nfsd_file 2025-01-23 17:17:17 +01:00
filecache.h nfsd: add list_head nf_gc to struct nfsd_file 2025-01-23 17:17:17 +01:00
flexfilelayout.c nfsd: move nfserrno() to vfs.c 2024-03-06 14:45:15 +00:00
flexfilelayoutxdr.c NFSD: da_addr_body field missing in some GETDEVICEINFO replies 2023-09-13 09:42:49 +02:00
flexfilelayoutxdr.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
idmap.h nfsd: Remove duplicate define of IDMAP_NAMESZ/IDMAP_TYPE_xx 2015-07-20 14:58:46 -04:00
Kconfig nfs: add missing selections of CONFIG_CRC32 2025-04-25 10:43:52 +02:00
lockd.c NFSD: simplify struct nfsfh 2021-10-02 15:51:10 -04:00
Makefile nfsd: allow disabling NFSv2 at compile time 2024-03-06 14:45:15 +00:00
netns.h NFSD: Limit the number of concurrent async COPY operations 2024-11-22 15:37:32 +01:00
nfs2acl.c nfsd: clear acl_access/acl_default after releasing them 2025-02-21 13:49:55 +01:00
nfs3acl.c nfsd: clear acl_access/acl_default after releasing them 2025-02-21 13:49:55 +01:00
nfs3proc.c NFSD: Add an NFSD_FILE_GC flag to enable nfsd_file garbage collection 2023-01-18 11:58:25 +01:00
nfs3xdr.c NFSD: Clean up WRITE arg decoders 2022-09-26 14:02:47 -04:00
nfs4acl.c NFSD: add posix ACLs to struct nfsd_attrs 2022-08-04 10:28:03 -04:00
nfs4callback.c NFSD: fix hang in nfsd4_shutdown_callback 2025-02-21 13:49:56 +01:00
nfs4idmap.c nfsd: call cache_put if xdr_reserve_space returns NULL 2024-10-17 15:21:08 +02:00
nfs4layouts.c nfsd: fix race to check ls_layouts 2023-03-10 09:33:24 +01:00
nfs4proc.c NFSD: Fix nfsd4_shutdown_copy() 2024-12-14 19:53:48 +01:00
nfs4recover.c NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir() 2024-12-14 19:53:47 +01:00
nfs4state.c nfsd: decrease sc_count directly if fail to queue dl_recall 2025-04-25 10:43:53 +02:00
nfs4xdr.c NFSD: Fix NFSv4's PUTPUBFH operation 2024-10-17 15:21:58 +02:00
nfscache.c nfsd: make all of the nfsd stats per-network namespace 2024-08-19 06:00:05 +02:00
nfsctl.c nfsd: drop the nfsd_put helper 2024-08-29 17:30:53 +02:00
nfsd.h nfsd: drop the nfsd_put helper 2024-08-29 17:30:53 +02:00
nfsfh.c nfsd: make all of the nfsd stats per-network namespace 2024-08-19 06:00:05 +02:00
nfsfh.h nfs: add missing selections of CONFIG_CRC32 2025-04-25 10:43:52 +02:00
nfsproc.c NFSD: Use set_bit(RQ_DROPME) 2024-03-06 14:45:17 +00:00
nfssvc.c nfsd: call nfsd_last_thread() before final nfsd_put() 2024-08-29 17:30:52 +02:00
nfsxdr.c NFSD: Clean up WRITE arg decoders 2022-09-26 14:02:47 -04:00
pnfs.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
state.h NFSD: add delegation reaper to react to low memory condition 2024-03-06 14:45:17 +00:00
stats.c nfsd: make svc_stat per-network namespace instead of global 2024-08-19 06:00:05 +02:00
stats.h nfsd: make svc_stat per-network namespace instead of global 2024-08-19 06:00:05 +02:00
trace.c NFSD: Add SPDX header for fs/nfsd/trace.c 2020-11-30 13:00:24 -05:00
trace.h NFSD: Replace nfsd_prune_bucket() 2024-08-19 06:00:04 +02:00
vfs.c nfsd: map the EBADMSG to nfserr_io to avoid warning 2024-10-17 15:21:58 +02:00
vfs.h nfsd: move nfserrno() to vfs.c 2024-03-06 14:45:15 +00:00
xdr.h NFSD: prevent underflow in nfssvc_decode_writeargs() 2022-03-15 09:35:56 -04:00
xdr3.h SUNRPC: Change return value type of .pc_encode 2021-10-13 11:34:49 -04:00
xdr4.h NFSD: Limit the number of concurrent async COPY operations 2024-11-22 15:37:32 +01:00
xdr4cb.h NFSD: add support for sending CB_RECALL_ANY 2024-03-06 14:45:17 +00:00