git: aa8c1f8d84d2 - main - nfs client: block vnode_pager_setsize() calls from nfscl_loadattrcache in nfs_write

Konstantin Belousov kib at FreeBSD.org
Sat Jan 23 15:25:36 UTC 2021


The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=aa8c1f8d84d2638a354e71f9593e978d00878243

commit aa8c1f8d84d2638a354e71f9593e978d00878243
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-01-22 21:47:06 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-01-23 15:24:32 +0000

    nfs client: block vnode_pager_setsize() calls from nfscl_loadattrcache in nfs_write
    
    Otherwise writing thread might wait on sbusy state of the pages which were
    busied by itself, similarly to nfs_read().  But also we need to clear
    NVNSETSZKSIP flag possibly set by ncl_pager_setsize(), to not undo
    extension done by write.
    
    Reported by:    bdrewery
    Reviewed by:    rmacklem
    Tested by:      pho
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D28306
---
 sys/fs/nfsclient/nfs_clbio.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c
index 09fedaa47eb8..7d0ff0abff3d 100644
--- a/sys/fs/nfsclient/nfs_clbio.c
+++ b/sys/fs/nfsclient/nfs_clbio.c
@@ -893,7 +893,7 @@ ncl_write(struct vop_write_args *ap)
 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
 	daddr_t lbn;
 	int bcount, noncontig_write, obcount;
-	int bp_cached, n, on, error = 0, error1, wouldcommit;
+	int bp_cached, n, on, error = 0, error1, save2, wouldcommit;
 	size_t orig_resid, local_resid;
 	off_t orig_size, tmp_off;
 
@@ -985,6 +985,7 @@ ncl_write(struct vop_write_args *ap)
 	if (vn_rlimit_fsize(vp, uio, td))
 		return (EFBIG);
 
+	save2 = curthread_pflags2_set(TDP2_SBPAGES);
 	biosize = vp->v_bufobj.bo_bsize;
 	/*
 	 * Find all of this file's B_NEEDCOMMIT buffers.  If our writes
@@ -1023,7 +1024,7 @@ ncl_write(struct vop_write_args *ap)
 				error = ncl_vinvalbuf(vp, V_SAVE | ((ioflag &
 				    IO_VMIO) != 0 ? V_VMIO : 0), td, 1);
 				if (error != 0)
-					return (error);
+					goto out;
 				wouldcommit = biosize;
 			}
 		}
@@ -1063,6 +1064,7 @@ again:
 				NFSLOCKNODE(np);
 				np->n_size = uio->uio_offset + n;
 				np->n_flag |= NMODIFIED;
+				np->n_flag &= ~NVNSETSZSKIP;
 				vnode_pager_setsize(vp, np->n_size);
 				NFSUNLOCKNODE(np);
 
@@ -1092,6 +1094,7 @@ again:
 			if (uio->uio_offset + n > np->n_size) {
 				np->n_size = uio->uio_offset + n;
 				np->n_flag |= NMODIFIED;
+				np->n_flag &= ~NVNSETSZSKIP;
 				vnode_pager_setsize(vp, np->n_size);
 			}
 			NFSUNLOCKNODE(np);
@@ -1281,6 +1284,13 @@ again:
 		}
 	}
 
+out:
+	curthread_pflags2_restore(save2);
+	if ((curthread->td_pflags2 & TDP2_SBPAGES) == 0) {
+		NFSLOCKNODE(np);
+		ncl_pager_setsize(vp, NULL);
+	}
+
 	return (error);
 }
 


More information about the dev-commits-src-all mailing list