Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement zfs native ACL support #9709

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions config/kernel-acl.m4
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,82 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
])
])

dnl #
dnl # 3.17 API change,
dnl # check whether generic_key_instantiate() exists
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_KEY_INSTANTIATE], [
ZFS_LINUX_TEST_SRC([generic_key_instantiate], [
#include <linux/key-type.h>
],[
struct key_type k;

k.instantiate = generic_key_instantiate;
])
])

AC_DEFUN([ZFS_AC_KERNEL_GENERIC_KEY_INSTANTIATE], [
AC_MSG_CHECKING([whether generic_key_instantiate() exists])
ZFS_LINUX_TEST_RESULT([generic_key_instantiate], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KERNEL_GENERIC_KEY_INSTANTIATE, 1,
[generic_key_instantiate() exists])
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 3.17 API change,
dnl # check whether KEY_FLAG_ROOT_CAN_INVAL exists
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_KEY_FLAG_ROOT_CAN_INVAL_EXISTS], [
ZFS_LINUX_TEST_SRC([KEY_FLAG_ROOT_CAN_INVAL], [
#include <linux/key.h>
],[
unsigned long addr;

set_bit(KEY_FLAG_ROOT_CAN_INVAL, &addr);
])
])

AC_DEFUN([ZFS_AC_KERNEL_KEY_FLAG_ROOT_CAN_INVAL_EXISTS], [
AC_MSG_CHECKING([whether HAVE_KEY_FLAG_ROOT_CAN_INVAL exists])
ZFS_LINUX_TEST_RESULT([KEY_FLAG_ROOT_CAN_INVAL], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KERNEL_KEY_FLAG_ROOT_CAN_INVAL, 1,
[HAVE_KEY_FLAG_ROOT_CAN_INVAL exists])
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 4.4 API change,
dnl # check whether user_key_payload() exists
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_USER_KEY_PAYLOAD], [
ZFS_LINUX_TEST_SRC([user_key_payload], [
#include <keys/user-type.h>
],[
const struct user_key_payload *ukp;
const struct key *k = NULL;

ukp = user_key_payload(k);
])
])

AC_DEFUN([ZFS_AC_KERNEL_USER_KEY_PAYLOAD], [
AC_MSG_CHECKING([whether user_key_payload() exists])
ZFS_LINUX_TEST_RESULT([user_key_payload], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KERNEL_USER_KEY_PAYLOAD, 1,
[user_key_payload() exists])
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 4.7 API change,
dnl # The kernel get_acl will now check cache before calling i_op->get_acl and
Expand All @@ -239,6 +315,86 @@ AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [
])
])

dnl #
dnl # 4.7 API change,
dnl # keyring_alloc() takes 8 args instead of 7
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_KEYRING_ALLOC_8_ARGS], [
ZFS_LINUX_TEST_SRC([keyring_alloc_8_args], [
#include <linux/cred.h>
#include <linux/key.h>
],[
struct key *k;
struct cred c;

k = keyring_alloc("", GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, &c, 0,
0, NULL, NULL);
])
])

AC_DEFUN([ZFS_AC_KERNEL_KEYRING_ALLOC_8_ARGS], [
AC_MSG_CHECKING([whether keyring_alloc() takes 8 args])
ZFS_LINUX_TEST_RESULT([keyring_alloc_8_args], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KERNEL_KEYRING_ALLOC_WITH_8_ARGS, 1,
[keyring_alloc() takes 8 args])
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 4.11 API change,
dnl # check whether user_key_payload_rcu() exists
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_USER_KEY_PAYLOAD_RCU], [
ZFS_LINUX_TEST_SRC([user_key_payload_rcu], [
#include <keys/user-type.h>
],[
const struct user_key_payload *ukp;
const struct key *k = NULL;

ukp = user_key_payload_rcu(k);
])
])

AC_DEFUN([ZFS_AC_KERNEL_USER_KEY_PAYLOAD_RCU], [
AC_MSG_CHECKING([whether user_key_payload_rcu() exists])
ZFS_LINUX_TEST_RESULT([user_key_payload_rcu], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KERNEL_USER_KEY_PAYLOAD_RCU, 1,
[user_key_payload_rcu() exists])
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 4.13.10 API change,
dnl # check whether key_is_positive() exists
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_KEY_IS_POSITIVE], [
ZFS_LINUX_TEST_SRC([key_is_positive], [
#include <linux/key.h>
],[
struct key *k = NULL;
bool v;

v = key_is_positive(k);
])
])

AC_DEFUN([ZFS_AC_KERNEL_KEY_IS_POSITIVE], [
AC_MSG_CHECKING([whether key_is_positive() exists])
ZFS_LINUX_TEST_RESULT([key_is_positive], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_KERNEL_KEY_IS_POSITIVE, 1,
[key_is_positive() exists])
],[
AC_MSG_RESULT(no)
])
])

dnl #
dnl # 4.16 kernel: check if struct posix_acl acl.a_refcount is a refcount_t.
dnl # It's an atomic_t on older kernels.
Expand Down Expand Up @@ -272,7 +428,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [
ZFS_AC_KERNEL_SRC_POSIX_ACL_VALID_WITH_NS
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL
ZFS_AC_KERNEL_SRC_GENERIC_KEY_INSTANTIATE
ZFS_AC_KERNEL_SRC_KEY_FLAG_ROOT_CAN_INVAL_EXISTS
ZFS_AC_KERNEL_SRC_USER_KEY_PAYLOAD
ZFS_AC_KERNEL_SRC_GET_ACL_HANDLE_CACHE
ZFS_AC_KERNEL_SRC_KEYRING_ALLOC_8_ARGS
ZFS_AC_KERNEL_SRC_USER_KEY_PAYLOAD_RCU
ZFS_AC_KERNEL_SRC_KEY_IS_POSITIVE
ZFS_AC_KERNEL_SRC_ACL_HAS_REFCOUNT
])

Expand All @@ -284,6 +446,12 @@ AC_DEFUN([ZFS_AC_KERNEL_ACL], [
ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
ZFS_AC_KERNEL_GENERIC_KEY_INSTANTIATE
ZFS_AC_KERNEL_KEY_FLAG_ROOT_CAN_INVAL_EXISTS
ZFS_AC_KERNEL_USER_KEY_PAYLOAD
ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
ZFS_AC_KERNEL_KEYRING_ALLOC_8_ARGS
ZFS_AC_KERNEL_USER_KEY_PAYLOAD_RCU
ZFS_AC_KERNEL_KEY_IS_POSITIVE
ZFS_AC_KERNEL_ACL_HAS_REFCOUNT
])
35 changes: 35 additions & 0 deletions config/kernel-config-defined.m4
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEFINED], [
ZFS_AC_KERNEL_SRC_CONFIG_TRIM_UNUSED_KSYMS
ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_INFLATE
ZFS_AC_KERNEL_SRC_CONFIG_ZLIB_DEFLATE
ZFS_AC_KERNEL_SRC_ZFS_NFS4_ACL

AC_MSG_CHECKING([for kernel config option compatibility])
ZFS_LINUX_TEST_COMPILE_ALL([config])
Expand All @@ -34,6 +35,7 @@ AC_DEFUN([ZFS_AC_KERNEL_CONFIG_DEFINED], [
ZFS_AC_KERNEL_CONFIG_TRIM_UNUSED_KSYMS
ZFS_AC_KERNEL_CONFIG_ZLIB_INFLATE
ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE
ZFS_AC_KERNEL_ZFS_NFS4_ACL
])

dnl #
Expand Down Expand Up @@ -181,3 +183,36 @@ AC_DEFUN([ZFS_AC_KERNEL_CONFIG_ZLIB_DEFLATE], [
*** Rebuild the kernel with CONFIG_ZLIB_DEFLATE=y|m set.])
])
])

dnl #
dnl # Check if ZFS_NFS4_ACL should be defined
dnl #
dnl # This requires CONFIG_KEYS to be enabled and
dnl # CONFIG_PREEMPT_RCU to be disabled. The key subsystem is used
dnl # to map between uid/gid values and user/group names, and
dnl # if CONFIG_PREEMPT_RCU compiling will result in the error:
dnl #
dnl # FATAL: modpost: GPL-incompatible module zfs.ko uses GPL-only symbol
dnl # __rcu_read_lock'
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_ZFS_NFS4_ACL], [
ZFS_LINUX_TEST_SRC([zfs_nfs4_acl], [
#if !defined(CONFIG_KEYS)
#error CONFIG_KEYS required for ZFS ACL support
#endif
#if defined(CONFIG_PREEMPT_RCU)
#error CONFIG_PREEMPT_RCU not compatible with ZFS ACL support
#endif
],[])
])

AC_DEFUN([ZFS_AC_KERNEL_ZFS_NFS4_ACL], [
AC_MSG_CHECKING([whether kernel options for ZFS ACLs are set])
ZFS_LINUX_TEST_RESULT([zfs_nfs4_acl], [
AC_MSG_RESULT([yes])
AC_DEFINE(ZFS_NFS4_ACL, 1, [kernel options for ZFS ACLs are set])
],[
AC_MSG_RESULT([no])
])
])

17 changes: 17 additions & 0 deletions include/os/linux/kernel/linux/xattr_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
#ifndef _ZFS_XATTR_H
#define _ZFS_XATTR_H

#include <linux/key.h>
#include <linux/keyctl.h>
#include <linux/key-type.h>
#include <keys/user-type.h>
#include <linux/posix_acl_xattr.h>

/*
Expand Down Expand Up @@ -164,6 +168,19 @@ fn(struct dentry *dentry, const char *name, const void *buffer, \
#error "Unsupported kernel"
#endif

/*
* Linux 4.4 and 4.11 API changes; rcu_dereference_key became
* user_key_payload in 4.4 and then changed to user_key_payload_rcu
* in 4.11.
*/
#if defined(HAVE_KERNEL_USER_KEY_PAYLOAD)
#define zpl_user_key_payload_rcu(k) user_key_payload(k)
#elif defined(HAVE_KERNEL_USER_KEY_PAYLOAD_RCU)
#define zpl_user_key_payload_rcu(k) user_key_payload_rcu(k)
#else
#define zpl_user_key_payload_rcu(k) rcu_dereference_key(k)
#endif

/*
* Linux 3.7 API change. posix_acl_{from,to}_xattr gained the user_ns
* parameter. All callers are expected to pass the &init_user_ns which
Expand Down
25 changes: 25 additions & 0 deletions include/os/linux/spl/sys/acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ typedef struct ace_object {
#define ACE_READ_NAMED_ATTRS 0x00000008
#define ACE_WRITE_NAMED_ATTRS 0x00000010
#define ACE_EXECUTE 0x00000020
#define ACE_TRAVERSE 0x00000020
#define ACE_DELETE_CHILD 0x00000040
#define ACE_READ_ATTRIBUTES 0x00000080
#define ACE_WRITE_ATTRIBUTES 0x00000100
Expand Down Expand Up @@ -109,6 +110,30 @@ typedef struct ace_object {
ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \
ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_WRITE_ACL| \
ACE_WRITE_OWNER|ACE_SYNCHRONIZE)

#define ACE_ALL_WRITE_PERMS (ACE_WRITE_DATA|ACE_APPEND_DATA| \
ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS|ACE_WRITE_ACL| \
ACE_WRITE_OWNER|ACE_DELETE|ACE_DELETE_CHILD)

#define ACE_READ_PERMS (ACE_READ_DATA|ACE_READ_ACL|ACE_READ_ATTRIBUTES| \
ACE_READ_NAMED_ATTRS)

#define ACE_WRITE_PERMS (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES| \
ACE_WRITE_NAMED_ATTRS)

#define ACE_MODIFY_PERMS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_READ_NAMED_ATTRS| \
ACE_WRITE_NAMED_ATTRS|ACE_EXECUTE|ACE_DELETE_CHILD|ACE_READ_ATTRIBUTES| \
ACE_WRITE_ATTRIBUTES|ACE_DELETE|ACE_READ_ACL|ACE_SYNCHRONIZE)

/*
* The following flags are supported by both NFSv4 ACLs and ace_t.
*/
#define ACE_NFSV4_SUP_FLAGS (ACE_FILE_INHERIT_ACE | \
ACE_DIRECTORY_INHERIT_ACE | \
ACE_NO_PROPAGATE_INHERIT_ACE | \
ACE_INHERIT_ONLY_ACE | \
ACE_IDENTIFIER_GROUP)
/* END CSTYLED */

#define VSA_ACE 0x0010
Expand Down
1 change: 1 addition & 0 deletions include/os/linux/zfs/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ KERNEL_H = \
$(top_srcdir)/include/os/linux/zfs/sys/zfs_vfsops.h \
$(top_srcdir)/include/os/linux/zfs/sys/zfs_vnops.h \
$(top_srcdir)/include/os/linux/zfs/sys/zfs_znode_impl.h \
$(top_srcdir)/include/os/linux/zfs/sys/zpl_xattr.h \
$(top_srcdir)/include/os/linux/zfs/sys/zpl.h

if CONFIG_KERNEL
Expand Down
2 changes: 2 additions & 0 deletions include/os/linux/zfs/sys/zpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ zpl_chmod_acl(struct inode *ip)
}
#endif /* CONFIG_FS_POSIX_ACL */

extern int zpl_permission(struct inode *ip, int mask);

extern xattr_handler_t *zpl_xattr_handlers[];

/* zpl_ctldir.c */
Expand Down
28 changes: 28 additions & 0 deletions include/os/linux/zfs/sys/zpl_xattr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

#ifndef _ZPL_XATTR_H
#define _ZPL_XATTR_H

int zpl_xattr_init(void);
void zpl_xattr_fini(void);

#endif /* _ZPL_XATTR_H */
1 change: 1 addition & 0 deletions include/sys/zfs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern "C" {
*/
#define ZFS_ACLTYPE_OFF 0
#define ZFS_ACLTYPE_POSIXACL 1
#define ZFS_ACLTYPE_NFSV4 2

/*
* Field manipulation macros for the drr_versioninfo field of the
Expand Down
Loading