git: b82168e657d3 - main - nfscl: Fix another deadlock related to the NFSv4 clientID lock
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 13 Oct 2021 00:24:29 UTC
The branch main has been updated by rmacklem:
URL: https://cgit.FreeBSD.org/src/commit/?id=b82168e657d378ff86ea18c4f03b98aac9ee9bb3
commit b82168e657d378ff86ea18c4f03b98aac9ee9bb3
Author: Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-10-13 00:21:01 +0000
Commit: Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-10-13 00:21:01 +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.
MFC after: 1 week
---
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 6be06b556de8..9a7a879fffd3 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -4607,6 +4607,8 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
int igotlock = 0, triedrecall = 0, needsrecall, retcnt = 0, islept;
nmp = VFSTONFS(vp->v_mount);
+ if (NFSHASPNFS(nmp))
+ return (retcnt);
NFSLOCKMNT(nmp);
if ((nmp->nm_privflag & NFSMNTP_DELEGISSUED) == 0) {
NFSUNLOCKMNT(nmp);
@@ -4712,6 +4714,8 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
nmp = VFSTONFS(fvp->v_mount);
*gotfdp = 0;
*gottdp = 0;
+ if (NFSHASPNFS(nmp))
+ return (retcnt);
NFSLOCKCLSTATE();
/*
* Loop around waiting for: