diff options
author | kib <kib@FreeBSD.org> | 2016-07-08 02:34:04 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-07-08 02:34:04 +0000 |
commit | 4cd5553df9068f8cda61b9786a2a1950e2bf550d (patch) | |
tree | 46469a1a8325e09b68516d9f2c4c5e6264180756 | |
parent | c76a2efc4b0cf61a1053998dcfabdd094ae59166 (diff) | |
download | FreeBSD-src-4cd5553df9068f8cda61b9786a2a1950e2bf550d.zip FreeBSD-src-4cd5553df9068f8cda61b9786a2a1950e2bf550d.tar.gz |
MFC r302196
Since VOP_INACTIVE() is not guaranteed to be called, all cleanups
executed by inactive methods, must be repeated on reclaim.
MFC r302210:
Clean other flags in ncl_inactive, only.
-rw-r--r-- | sys/fs/nfsclient/nfs_clnode.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index 263185f..647b85d 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -200,15 +200,40 @@ nfs_freesillyrename(void *arg, __unused int pending) 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_assert(&np->n_mtx, MA_OWNED); + 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); + } +} + +int +ncl_inactive(struct vop_inactive_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct nfsnode *np; + boolean_t retv; if (NFS_ISV4(vp) && vp->v_type == VREG) { /* @@ -230,24 +255,15 @@ ncl_inactive(struct vop_inactive_args *ap) } } + 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) { - 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); - } + ncl_releasesillyrename(vp, ap->a_td); + + /* + * NMODIFIED means that there might be dirty/stale buffers + * associated with the NFS vnode. None of the other flags are + * meaningful after the vnode is unused. + */ np->n_flag &= NMODIFIED; mtx_unlock(&np->n_mtx); return (0); @@ -270,6 +286,10 @@ ncl_reclaim(struct vop_reclaim_args *ap) if (nfs_reclaim_p != NULL) nfs_reclaim_p(ap); + mtx_lock(&np->n_mtx); + ncl_releasesillyrename(vp, ap->a_td); + mtx_unlock(&np->n_mtx); + /* * Destroy the vm object and flush associated pages. */ |