From c887ac83245115c57c0b8df29ce5048122a88418 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 2 Feb 2020 16:10:33 +0000 Subject: [PATCH] zfs: light refactor to indicate cachedlookup in zfs_lookup If we come from VOP_CACHEDLOOKUP, we must skip the VEXEC check as it will have been done in the caller (vfs_cache_lookup). This is a part of D23247, which may skip the earlier VEXEC check as well if the root fd was opened with O_SEARCH. This one required slightly more work as zfs_lookup may also be called indirectly as VOP_LOOKUP or a couple of other places where we must do the check. --- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 61cf98a39cad..1c2856a224b3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -1470,7 +1470,7 @@ zfs_lookup_lock(vnode_t *dvp, vnode_t *vp, const char *name, int lkflags) /* ARGSUSED */ static int zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, - int nameiop, cred_t *cr, kthread_t *td, int flags) + int nameiop, cred_t *cr, kthread_t *td, int flags, boolean_t cached) { znode_t *zdp = VTOZ(dvp); znode_t *zp; @@ -1542,9 +1542,12 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, /* * Check accessibility of directory. */ - if (error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr)) { - ZFS_EXIT(zfsvfs); - return (error); + if (!cached) { + error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); + if (error != 0) { + ZFS_EXIT(zfsvfs); + return (error); + } } if (zfsvfs->z_utf8 && u8_validate(nm, strlen(nm), @@ -4894,12 +4897,7 @@ zfs_freebsd_access(ap) } static int -zfs_freebsd_lookup(ap) - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap; +zfs_freebsd_lookup(struct vop_lookup_args *ap, boolean_t cached) { struct componentname *cnp = ap->a_cnp; char nm[NAME_MAX + 1]; @@ -4908,7 +4906,14 @@ zfs_freebsd_lookup(ap) strlcpy(nm, cnp->cn_nameptr, MIN(cnp->cn_namelen + 1, sizeof(nm))); return (zfs_lookup(ap->a_dvp, nm, ap->a_vpp, cnp, cnp->cn_nameiop, - cnp->cn_cred, cnp->cn_thread, 0)); + cnp->cn_cred, cnp->cn_thread, 0, cached)); +} + +static int +zfs_freebsd_cachedlookup(struct vop_cachedlookup_args *ap) +{ + + return (zfs_freebsd_lookup((struct vop_lookup_args *)ap, B_TRUE)); } static int @@ -4925,7 +4930,7 @@ zfs_cache_lookup(ap) if (zfsvfs->z_use_namecache) return (vfs_cache_lookup(ap)); else - return (zfs_freebsd_lookup(ap)); + return (zfs_freebsd_lookup(ap, B_FALSE)); } static int @@ -5507,7 +5512,7 @@ vop_getextattr { ZFS_ENTER(zfsvfs); error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, - LOOKUP_XATTR); + LOOKUP_XATTR, B_FALSE); if (error != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -5576,7 +5581,7 @@ vop_deleteextattr { ZFS_ENTER(zfsvfs); error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, - LOOKUP_XATTR); + LOOKUP_XATTR, B_FALSE); if (error != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -5644,7 +5649,7 @@ vop_setextattr { ZFS_ENTER(zfsvfs); error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, - LOOKUP_XATTR | CREATE_XATTR_DIR); + LOOKUP_XATTR | CREATE_XATTR_DIR, B_FALSE); if (error != 0) { ZFS_EXIT(zfsvfs); return (error); @@ -5721,7 +5726,7 @@ vop_listextattr { *sizep = 0; error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td, - LOOKUP_XATTR); + LOOKUP_XATTR, B_FALSE); if (error != 0) { ZFS_EXIT(zfsvfs); /* @@ -5982,7 +5987,7 @@ struct vop_vector zfs_vnodeops = { .vop_access = zfs_freebsd_access, .vop_allocate = VOP_EINVAL, .vop_lookup = zfs_cache_lookup, - .vop_cachedlookup = zfs_freebsd_lookup, + .vop_cachedlookup = zfs_freebsd_cachedlookup, .vop_getattr = zfs_freebsd_getattr, .vop_setattr = zfs_freebsd_setattr, .vop_create = zfs_freebsd_create,