Add VOP_VPUT_PAIR() with trivial default implementation.

The VOP is intended to be used in situations where VFS has two
referenced locked vnodes, typically a directory vnode dvp and a vnode
vp that is linked from the directory, and at least dvp is vput(9)ed.
The child vnode can be also vput-ed, but optionally left referenced and
locked.

There, at least UFS may need to do some actions with dvp which cannot be
done while vp is also locked, so its lock might be dropped temporary.
For instance, in some cases UFS needs to sync dvp to avoid filesystem
state that is currently not handled by either kernel nor fsck. Having
such VOP provides the neccessary context for filesystem which can do
correct locking and handle potential reclamation of vp after relock.

Trivial implementation does vput(dvp) and optionally vput(vp).

Reviewed by:	chs, mckusick
Tested by:	pho
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Konstantin Belousov 2021-01-29 00:30:53 +02:00
parent ee965dfa64
commit 49c117c193
2 changed files with 24 additions and 0 deletions

View File

@ -92,6 +92,7 @@ static int vop_stdfdatasync(struct vop_fdatasync_args *ap);
static int vop_stdgetpages_async(struct vop_getpages_async_args *ap);
static int vop_stdread_pgcache(struct vop_read_pgcache_args *ap);
static int vop_stdstat(struct vop_stat_args *ap);
static int vop_stdvput_pair(struct vop_vput_pair_args *ap);
/*
* This vnode table stores what we want to do if the filesystem doesn't
@ -151,6 +152,7 @@ struct vop_vector default_vnodeops = {
.vop_unset_text = vop_stdunset_text,
.vop_add_writecount = vop_stdadd_writecount,
.vop_copy_file_range = vop_stdcopy_file_range,
.vop_vput_pair = vop_stdvput_pair,
};
VFS_VOP_VECTOR_REGISTER(default_vnodeops);
@ -1592,3 +1594,16 @@ vop_stdread_pgcache(struct vop_read_pgcache_args *ap __unused)
{
return (EJUSTRETURN);
}
static int
vop_stdvput_pair(struct vop_vput_pair_args *ap)
{
struct vnode *dvp, *vp, **vpp;
dvp = ap->a_dvp;
vpp = ap->a_vpp;
vput(dvp);
if (vpp != NULL && ap->a_unlock_vp && (vp = *vpp) != NULL)
vput(vp);
return (0);
}

View File

@ -792,6 +792,15 @@ vop_copy_file_range {
};
%% vput_pair dvp E - -
vop_vput_pair {
IN struct vnode *dvp;
INOUT struct vnode **vpp;
IN bool unlock_vp;
};
# The VOPs below are spares at the end of the table to allow new VOPs to be
# added in stable branches without breaking the KBI. New VOPs in HEAD should
# be added above these spares. When merging a new VOP to a stable branch,