aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfsclient/nfs_clport.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2020-02-22 20:50:30 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2020-02-22 20:50:30 +0000
commit0ff51c98d19739ee1c1e0046ffaade5051d6b210 (patch)
tree9ade0faeb4aee4a4c3118471e4af6dc46c9f418f /sys/fs/nfsclient/nfs_clport.c
parent04869b812b8e19fbfbfd75299f3b00c186edb0d3 (diff)
downloadsrc-0ff51c98d19739ee1c1e0046ffaade5051d6b210.tar.gz
src-0ff51c98d19739ee1c1e0046ffaade5051d6b210.zip
Fix NFS client deadlock when read reports truncated node.
If node attribute returned in the reply for read rpc indicate truncation, and it happens that the vnode is exclusively locked, update of the node attributes would try to shrink vnode size. Since during the read some vnode pages were busied by the reading thread, vnode_pager_setsize() deadlocks waiting for the busy state owned by the caller. Use a thread-local flag to indicate that NFS read owns some (s)busy pages states and postpone the call to vnode_pager_setsize() until the thread relinguishes the ownership. Diagnosed by: rlibby Tested by: pho, rlibby Sponsored by: The FreeBSD Foundation MFC after: 1 week
Notes
Notes: svn path=/head/; revision=358252
Diffstat (limited to 'sys/fs/nfsclient/nfs_clport.c')
-rw-r--r--sys/fs/nfsclient/nfs_clport.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 77ecdd255ea2..017b81776579 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -597,7 +597,8 @@ ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep)
setnsize = false;
if (object != NULL && nsize != object->un_pager.vnp.vnp_size) {
- if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
+ if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE &&
+ (curthread->td_pflags2 & TDP2_SBPAGES) == 0)
setnsize = true;
else
np->n_flag |= NVNSETSZSKIP;