Date: Sat, 25 Jun 2016 11:34:06 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302196 - head/sys/fs/nfsclient Message-ID: <201606251134.u5PBY6E2005551@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606251134.u5PBY6E2005551>