Add a null_remove() function to nullfs, so that the v_usecount
of the lower level vnode is incremented to greater than 1 when the upper level vnode's v_usecount is greater than one. This is necessary for the NFS clients, so that they will do a silly rename of the file instead of actually removing it when the file is still in use. It is "racy", since the v_usecount is incremented in many places in the kernel with minimal synchronization, but an extraneous silly rename is preferred to not doing a silly rename when it is required. The only other file systems that currently check the value of v_usecount in their VOP_REMOVE() functions are nwfs and smbfs. These file systems choose to fail a remove when the v_usecount is greater than 1 and I believe will function more correctly with this patch, as well. Tested by: to.my.trociny at gmail.com Submitted by: to.my.trociny at gmail.com (earlier version) Reviewed by: kib MFC after: 2 weeks
This commit is contained in:
parent
5bdff860e7
commit
2d0c83b139
@ -498,6 +498,32 @@ null_accessx(struct vop_accessx_args *ap)
|
||||
return (null_bypass((struct vop_generic_args *)ap));
|
||||
}
|
||||
|
||||
/*
|
||||
* Increasing refcount of lower vnode is needed at least for the case
|
||||
* when lower FS is NFS to do sillyrename if the file is in use.
|
||||
* Unfortunately v_usecount is incremented in many places in
|
||||
* the kernel and, as such, there may be races that result in
|
||||
* the NFS client doing an extraneous silly rename, but that seems
|
||||
* preferable to not doing a silly rename when it is needed.
|
||||
*/
|
||||
static int
|
||||
null_remove(struct vop_remove_args *ap)
|
||||
{
|
||||
int retval, vreleit;
|
||||
struct vnode *lvp;
|
||||
|
||||
if (vrefcnt(ap->a_vp) > 1) {
|
||||
lvp = NULLVPTOLOWERVP(ap->a_vp);
|
||||
VREF(lvp);
|
||||
vreleit = 1;
|
||||
} else
|
||||
vreleit = 0;
|
||||
retval = null_bypass(&ap->a_gen);
|
||||
if (vreleit != 0)
|
||||
vrele(lvp);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* We handle this to eliminate null FS to lower FS
|
||||
* file moving. Don't know why we don't allow this,
|
||||
@ -809,6 +835,7 @@ struct vop_vector null_vnodeops = {
|
||||
.vop_open = null_open,
|
||||
.vop_print = null_print,
|
||||
.vop_reclaim = null_reclaim,
|
||||
.vop_remove = null_remove,
|
||||
.vop_rename = null_rename,
|
||||
.vop_setattr = null_setattr,
|
||||
.vop_strategy = VOP_EOPNOTSUPP,
|
||||
|
Loading…
x
Reference in New Issue
Block a user