Skip to content

Commit

Permalink
Improve zpl_permission performance
Browse files Browse the repository at this point in the history
This function can be frequently called with MAY_EXEC|MAY_NOT_BLOCK
during RCU path walk. Where possible we should try not to break
out of it. In this case we check whether flag ZFS_NO_EXECS_DENIED is
set and check mode (similar to fastexecute check in zfs_acl.c).

Signed-off-by: Andrew Walker <awalker@ixsystems.com>
  • Loading branch information
anodos325 committed May 1, 2023
1 parent cfaeccd commit f4f8a1f
Showing 1 changed file with 37 additions and 25 deletions.
62 changes: 37 additions & 25 deletions module/os/linux/zfs/zpl_xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,23 @@ zpl_permission(struct inode *ip, int mask)
#endif
}

/*
* Fast path for execute checks. This is not
* authoritative as user may have explicit entry granting
* execute or be member of group granting execute.
*/
if (to_check == ACE_EXECUTE) {
#if defined(HAVE_IOPS_PERMISSION_USERNS)
if ((ITOZ(ip)->z_pflags & ZFS_NO_EXECS_DENIED) ||
(generic_permission(userns, ip, mask) == 0)) {
#else
if ((ITOZ(ip)->z_pflags & ZFS_NO_EXECS_DENIED) ||
(generic_permission(ip, mask) == 0)) {
#endif
return (0);
}
}

/*
* Avoid potentially blocking in RCU walk.
*/
Expand All @@ -1514,16 +1531,25 @@ zpl_permission(struct inode *ip, int mask)

cr = CRED();
crhold(cr);
ret = -zfs_access(ITOZ(ip), to_check, V_ACE_MASK, cr);
if (ret != -EPERM && ret != -EACCES) {
crfree(cr);
return (ret);
}

/*
* There are some situations in which capabilities
* may allow overriding the DACL.
* may allow overriding the DACL. Skip reading ACL in
* this case.
*/

/*
* Read/write DACs are always overridable.
* Executable DACs are overridable when there is
* at least one exec bit set.
*/
if (!(mask & MAY_EXEC) || (ip->i_mode & S_IXUGO)) {
if (capable(CAP_DAC_OVERRIDE)) {
crfree(cr);
return (0);
}
}

if (S_ISDIR(ip->i_mode)) {
#ifdef SB_NFSV4ACL
if (!(mask & (MAY_WRITE | NFS41ACL_WRITE_ALL))) {
Expand All @@ -1535,29 +1561,15 @@ zpl_permission(struct inode *ip, int mask)
return (0);
}
}
if (capable(CAP_DAC_OVERRIDE)) {
crfree(cr);
return (0);
}
crfree(cr);
return (ret);
}

if (to_check == ACE_READ_DATA) {
if (capable(CAP_DAC_READ_SEARCH)) {
crfree(cr);
return (0);
}
}

if (!(mask & MAY_EXEC) ||
(zfs_fastaccesschk_execute(ITOZ(ip), cr) == 0)) {
if (capable(CAP_DAC_OVERRIDE)) {
crfree(cr);
return (0);
}
if ((to_check == ACE_READ_DATA) &&
capable(CAP_DAC_READ_SEARCH)) {
crfree(cr);
return (0);
}

ret = -zfs_access(ITOZ(ip), to_check, V_ACE_MASK, cr);
crfree(cr);
return (ret);
}
Expand Down

0 comments on commit f4f8a1f

Please sign in to comment.