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)
This commit is contained in:
Konstantin Belousov 2016-06-25 11:34:06 +00:00
parent 8a06de9e92
commit 8f73d398ed
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=302196

View File

@ -198,16 +198,42 @@ 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;
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;
np = VTONFS(vp);
if (NFS_ISV4(vp) && vp->v_type == VREG) {
/*
* Since mmap()'d files do I/O after VOP_CLOSE(), the NFSv4
@ -228,26 +254,7 @@ ncl_inactive(struct vop_inactive_args *ap)
}
}
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.
*/