Date: Tue, 19 Oct 2021 03:49:49 GMT From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 75d71cf8df8c - stable/12 - nfscl: Fix another deadlock related to the NFSv4 clientID lock Message-ID: <202110190349.19J3nnGH062149@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=75d71cf8df8c83b2b2bc3a16ef66a540a2ebac70 commit 75d71cf8df8c83b2b2bc3a16ef66a540a2ebac70 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2021-10-13 00:21:01 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2021-10-19 03:46:00 +0000 nfscl: Fix another deadlock related to the NFSv4 clientID lock Without this patch, it is possible to hang the NFSv4 client, when a rename/remove is being done on a file where the client holds a delegation, if pNFS is being used. For a delegation to be returned, dirty data blocks must be flushed to the NFSv4 server. When pNFS is in use, a shared lock on the clientID must be acquired while doing a write to the DS(s). However, if rename/remove is doing the delegation return an exclusive lock will be acquired on the clientID, preventing the write to the DS(s) from acquiring a shared lock on the clientID. This patch stops rename/remove from doing a delegation return if pNFS is enabled. Since doing delegation return in the same compound as rename/remove is only an optimization, not doing so should not cause problems. This problem was detected during a recent NFSv4 interoperability testing event held by the IETF working group. (cherry picked from commit b82168e657d378ff86ea18c4f03b98aac9ee9bb3) --- sys/fs/nfsclient/nfs_clstate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 92688fcfbe28..5f35e4e708e9 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -4480,6 +4480,8 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp) int igotlock = 0, triedrecall = 0, needsrecall, retcnt = 0, islept; nmp = VFSTONFS(vnode_mount(vp)); + if (NFSHASPNFS(nmp)) + return (retcnt); np = VTONFS(vp); NFSLOCKCLSTATE(); /* @@ -4579,6 +4581,8 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp, nmp = VFSTONFS(vnode_mount(fvp)); *gotfdp = 0; *gottdp = 0; + if (NFSHASPNFS(nmp)) + return (retcnt); NFSLOCKCLSTATE(); /* * Loop around waiting for:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202110190349.19J3nnGH062149>