VFS: add VOP_GETLOWVNODE()

It is similar to VOP_GETWRITEMOUNT(), and for given vnode vp should
return the lower vnode which would actually handle write to vp.
Flags allow to specify FREAD or FWRITE for benefit of possible unionfs
implementation.

Reviewed by:	markj, Olivier Certner <olce.freebsd@certner.fr>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D42603
This commit is contained in:
Konstantin Belousov 2023-11-18 10:55:48 +02:00
parent 171f0832c5
commit 4cbe4c48a7
3 changed files with 35 additions and 0 deletions

View file

@ -1127,6 +1127,23 @@ null_vput_pair(struct vop_vput_pair_args *ap)
return (res);
}
static int
null_getlowvnode(struct vop_getlowvnode_args *ap)
{
struct vnode *vp, *vpl;
vp = ap->a_vp;
if (vn_lock(vp, LK_SHARED) != 0)
return (EBADF);
vpl = NULLVPTOLOWERVP(vp);
vhold(vpl);
VOP_UNLOCK(vp);
VOP_GETLOWVNODE(vpl, ap->a_vplp, ap->a_flags);
vdrop(vpl);
return (0);
}
/*
* Global vfs data structures
*/
@ -1139,6 +1156,7 @@ struct vop_vector null_vnodeops = {
.vop_bmap = VOP_EOPNOTSUPP,
.vop_stat = null_stat,
.vop_getattr = null_getattr,
.vop_getlowvnode = null_getlowvnode,
.vop_getwritemount = null_getwritemount,
.vop_inactive = null_inactive,
.vop_need_inactive = null_need_inactive,

View file

@ -82,6 +82,7 @@ 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);
static int vop_stdgetlowvnode(struct vop_getlowvnode_args *ap);
/*
* This vnode table stores what we want to do if the filesystem doesn't
@ -112,6 +113,7 @@ struct vop_vector default_vnodeops = {
.vop_fsync = VOP_NULL,
.vop_stat = vop_stdstat,
.vop_fdatasync = vop_stdfdatasync,
.vop_getlowvnode = vop_stdgetlowvnode,
.vop_getpages = vop_stdgetpages,
.vop_getpages_async = vop_stdgetpages_async,
.vop_getwritemount = vop_stdgetwritemount,
@ -1607,3 +1609,11 @@ vop_stdvput_pair(struct vop_vput_pair_args *ap)
vput(vp);
return (0);
}
static int
vop_stdgetlowvnode(struct vop_getlowvnode_args *ap)
{
vref(ap->a_vp);
*ap->a_vplp = ap->a_vp;
return (0);
}

View file

@ -468,6 +468,13 @@ vop_getwritemount {
OUT struct mount **mpp;
};
%% getwritevnode vp = = =
vop_getlowvnode {
IN struct vnode *vp;
OUT struct vnode **vplp;
IN int flags;
};
%% print vp - - -