svn commit: r357282 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Mateusz Guzik
mjg at FreeBSD.org
Thu Jan 30 02:16:18 UTC 2020
Author: mjg
Date: Thu Jan 30 02:16:17 2020
New Revision: 357282
URL: https://svnweb.freebsd.org/changeset/base/357282
Log:
zfs: fix spurious lock contention during path lookup
ZFS tracks if anything denies VEXEC to allow for a quick check for the
common case of path traversal. Use it.
Differential Revision: https://reviews.freebsd.org/D22224
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h Thu Jan 30 02:14:10 2020 (r357281)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h Thu Jan 30 02:16:17 2020 (r357282)
@@ -214,7 +214,10 @@ void zfs_oldace_byteswap(ace_t *, int);
void zfs_ace_byteswap(void *, size_t, boolean_t);
extern boolean_t zfs_has_access(struct znode *zp, cred_t *cr);
extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *);
+#ifdef illumos
int zfs_fastaccesschk_execute(struct znode *, cred_t *);
+#endif
+int zfs_freebsd_fastaccesschk_execute(struct vnode *, cred_t *);
extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *);
extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *);
extern int zfs_acl_access(struct znode *, int, cred_t *);
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c Thu Jan 30 02:14:10 2020 (r357281)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c Thu Jan 30 02:16:17 2020 (r357282)
@@ -2299,7 +2299,41 @@ zfs_zaccess_append(znode_t *zp, uint32_t *working_mode
check_privs, B_FALSE, cr));
}
+/*
+ * Check if VEXEC is allowed.
+ *
+ * This routine is based on zfs_fastaccesschk_execute which has slowpath
+ * calling zfs_zaccess. This would be incorrect on FreeBSD (see
+ * zfs_freebsd_access for the difference). Thus this variant let's the
+ * caller handle the slowpath (if necessary).
+ *
+ * We only check for ZFS_NO_EXECS_DENIED and fail early. This routine can
+ * be extended to cover more cases, but the flag covers the majority.
+ */
int
+zfs_freebsd_fastaccesschk_execute(struct vnode *vp, cred_t *cr)
+{
+ boolean_t is_attr;
+ znode_t *zdp = VTOZ(vp);
+
+ ASSERT_VOP_LOCKED(vp, __func__);
+
+ if (zdp->z_pflags & ZFS_AV_QUARANTINED)
+ return (1);
+
+ is_attr = ((zdp->z_pflags & ZFS_XATTR) &&
+ (ZTOV(zdp)->v_type == VDIR));
+ if (is_attr)
+ return (1);
+
+ if (zdp->z_pflags & ZFS_NO_EXECS_DENIED)
+ return (0);
+
+ return (1);
+}
+
+#ifdef illumos
+int
zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
{
boolean_t owner = B_FALSE;
@@ -2365,6 +2399,7 @@ slow:
ZFS_EXIT(zdp->z_zfsvfs);
return (error);
}
+#endif
/*
* Determine whether Access should be granted/denied.
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Jan 30 02:14:10 2020 (r357281)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Jan 30 02:16:17 2020 (r357282)
@@ -4858,6 +4858,11 @@ zfs_freebsd_access(ap)
accmode_t accmode;
int error = 0;
+ if (ap->a_accmode == VEXEC) {
+ if (zfs_freebsd_fastaccesschk_execute(ap->a_vp, ap->a_cred) == 0)
+ return (0);
+ }
+
/*
* ZFS itself only knowns about VREAD, VWRITE, VEXEC and VAPPEND,
*/
More information about the svn-src-all
mailing list