svn commit: r302196 - head/sys/fs/nfsclient

Konstantin Belousov kib at FreeBSD.org
Sat Jun 25 11:34:07 UTC 2016


Author: kib
Date: Sat Jun 25 11:34:06 2016
New Revision: 302196
URL: https://svnweb.freebsd.org/changeset/base/302196

Log:
  Since VOP_INACTIVE() is not guaranteed to be called, all cleanups
  executed by inactive methods, must be repeated on reclaim.  In
  particular, unlink and free sillyrenamed vnode both on inactivation
  and reclaim.
  
  Reported and tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks
  Approved by:	re (gjb)

Modified:
  head/sys/fs/nfsclient/nfs_clnode.c

Modified: head/sys/fs/nfsclient/nfs_clnode.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clnode.c	Sat Jun 25 11:31:25 2016	(r302195)
+++ head/sys/fs/nfsclient/nfs_clnode.c	Sat Jun 25 11:34:06 2016	(r302196)
@@ -198,15 +198,41 @@ nfs_freesillyrename(void *arg, __unused 
 	free(sp, M_NEWNFSREQ);
 }
 
-int
-ncl_inactive(struct vop_inactive_args *ap)
+static void
+ncl_releasesillyrename(struct vnode *vp, struct thread *td)
 {
 	struct nfsnode *np;
 	struct sillyrename *sp;
-	struct vnode *vp = ap->a_vp;
-	boolean_t retv;
 
+	ASSERT_VOP_ELOCKED(vp, "releasesillyrename");
 	np = VTONFS(vp);
+	mtx_lock(&np->n_mtx);
+	if (vp->v_type != VDIR) {
+		sp = np->n_sillyrename;
+		np->n_sillyrename = NULL;
+	} else
+		sp = NULL;
+	if (sp != NULL) {
+		mtx_unlock(&np->n_mtx);
+		(void) ncl_vinvalbuf(vp, 0, td, 1);
+		/*
+		 * Remove the silly file that was rename'd earlier
+		 */
+		ncl_removeit(sp, vp);
+		crfree(sp->s_cred);
+		TASK_INIT(&sp->s_task, 0, nfs_freesillyrename, sp);
+		taskqueue_enqueue(taskqueue_thread, &sp->s_task);
+		mtx_lock(&np->n_mtx);
+	}
+	np->n_flag &= NMODIFIED;
+	mtx_unlock(&np->n_mtx);
+}
+
+int
+ncl_inactive(struct vop_inactive_args *ap)
+{
+	struct vnode *vp = ap->a_vp;
+	boolean_t retv;
 
 	if (NFS_ISV4(vp) && vp->v_type == VREG) {
 		/*
@@ -228,26 +254,7 @@ ncl_inactive(struct vop_inactive_args *a
 		}
 	}
 
-	mtx_lock(&np->n_mtx);
-	if (vp->v_type != VDIR) {
-		sp = np->n_sillyrename;
-		np->n_sillyrename = NULL;
-	} else
-		sp = NULL;
-	if (sp) {
-		mtx_unlock(&np->n_mtx);
-		(void) ncl_vinvalbuf(vp, 0, ap->a_td, 1);
-		/*
-		 * Remove the silly file that was rename'd earlier
-		 */
-		ncl_removeit(sp, vp);
-		crfree(sp->s_cred);
-		TASK_INIT(&sp->s_task, 0, nfs_freesillyrename, sp);
-		taskqueue_enqueue(taskqueue_thread, &sp->s_task);
-		mtx_lock(&np->n_mtx);
-	}
-	np->n_flag &= NMODIFIED;
-	mtx_unlock(&np->n_mtx);
+	ncl_releasesillyrename(vp, ap->a_td);
 	return (0);
 }
 
@@ -268,6 +275,8 @@ ncl_reclaim(struct vop_reclaim_args *ap)
 	if (nfs_reclaim_p != NULL)
 		nfs_reclaim_p(ap);
 
+	ncl_releasesillyrename(vp, ap->a_td);
+
 	/*
 	 * Destroy the vm object and flush associated pages.
 	 */


More information about the svn-src-head mailing list