svn commit: r352621 - stable/12/sys/fs/nfsclient

Konstantin Belousov kib at FreeBSD.org
Mon Sep 23 13:45:50 UTC 2019


Author: kib
Date: Mon Sep 23 13:45:50 2019
New Revision: 352621
URL: https://svnweb.freebsd.org/changeset/base/352621

Log:
  MFC r352393, r352457:
  nfscl_loadattrcache: fix rest of the cases to not call
  vnode_pager_setsize() under the node mutex.

Modified:
  stable/12/sys/fs/nfsclient/nfs_clport.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- stable/12/sys/fs/nfsclient/nfs_clport.c	Mon Sep 23 13:24:31 2019	(r352620)
+++ stable/12/sys/fs/nfsclient/nfs_clport.c	Mon Sep 23 13:45:50 2019	(r352621)
@@ -414,12 +414,12 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvatt
 	struct nfsnode *np;
 	struct nfsmount *nmp;
 	struct timespec mtime_save;
+	vm_object_t object;
 	u_quad_t nsize;
-	int setnsize, error, force_fid_err;
+	int error, force_fid_err;
+	bool setnsize;
 
 	error = 0;
-	setnsize = 0;
-	nsize = 0;
 
 	/*
 	 * If v_type == VNON it is a new node, so fill in the v_type,
@@ -514,7 +514,6 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvatt
 				vap->va_size = np->n_size;
 				np->n_attrstamp = 0;
 				KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
-				vnode_pager_setsize(vp, np->n_size);
 			} else if (np->n_flag & NMODIFIED) {
 				/*
 				 * We've modified the file: Use the larger
@@ -526,21 +525,9 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvatt
 					np->n_size = vap->va_size;
 					np->n_flag |= NSIZECHANGED;
 				}
-				vnode_pager_setsize(vp, np->n_size);
-			} else if (vap->va_size < np->n_size) {
-				/*
-				 * When shrinking the size, the call to
-				 * vnode_pager_setsize() cannot be done
-				 * with the mutex held, so delay it until
-				 * after the mtx_unlock call.
-				 */
-				nsize = np->n_size = vap->va_size;
-				np->n_flag |= NSIZECHANGED;
-				setnsize = 1;
 			} else {
 				np->n_size = vap->va_size;
 				np->n_flag |= NSIZECHANGED;
-				vnode_pager_setsize(vp, np->n_size);
 			}
 		} else {
 			np->n_size = vap->va_size;
@@ -578,6 +565,23 @@ out:
 	if (np->n_attrstamp != 0)
 		KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error);
 #endif
+	nsize = vap->va_size;
+	object = vp->v_object;
+	setnsize = false;
+	if (object != NULL) {
+		if (OFF_TO_IDX(nsize + PAGE_MASK) < object->size) {
+			/*
+			 * When shrinking the size, the call to
+			 * vnode_pager_setsize() cannot be done with
+			 * the mutex held, because we might need to
+			 * wait for a busy page.  Delay it until after
+			 * the node is unlocked.
+			 */
+			setnsize = true;
+		} else {
+			vnode_pager_setsize(vp, nsize);
+		}
+	}
 	NFSUNLOCKNODE(np);
 	if (setnsize)
 		vnode_pager_setsize(vp, nsize);


More information about the svn-src-all mailing list