From c8d56a664306c3ceb4e598999c41eb72ea46a68f Mon Sep 17 00:00:00 2001 From: Dmitry Eremin Date: Sat, 10 Jun 2017 17:36:52 -0400 Subject: [PATCH] LU-9183 llite: add support set_acl method in inode operations Linux kernel v3.14 adds set_acl method to inode operations. See kernel commit 893d46e443346370cd4ea81d9d35f72952c62a37 Change-Id: Ia40d55364016fafa8633fdaecd317910505f8ad4 Signed-off-by: Dmitry Eremin Reviewed-on: https://review.whamcloud.com/25965 Reviewed-by: Bob Glossman Reviewed-by: James Simmons Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/autoconf/lustre-core.m4 | 20 +++++++++++++++ lustre/llite/file.c | 56 ++++++++++++++++++++++++++++++++++++++++++ lustre/llite/llite_internal.h | 8 ++++++ lustre/llite/llite_lib.c | 1 + lustre/llite/namei.c | 42 +++++++++++++++++-------------- 5 files changed, 109 insertions(+), 18 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 1cde867..d6a0ad9 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1771,6 +1771,25 @@ have_bvec_iter, [ ]) # LC_HAVE_BVEC_ITER # +# LC_IOP_SET_ACL +# +# 3.14 adds set_acl method to inode_operations +# see kernel commit 893d46e443346370cd4ea81d9d35f72952c62a37 +# +AC_DEFUN([LC_IOP_SET_ACL], [ +LB_CHECK_COMPILE([if 'inode_operations' has '.set_acl' member function], +inode_ops_set_acl, [ + #include +],[ + struct inode_operations iop; + iop.set_acl = NULL; +],[ + AC_DEFINE(HAVE_IOP_SET_ACL, 1, + [inode_operations has .set_acl member function]) +]) +]) # LC_IOP_SET_ACL + +# # LC_HAVE_BI_CNT # # 4.4 redefined bi_cnt as __bi_cnt @@ -2751,6 +2770,7 @@ AC_DEFUN([LC_PROG_LINUX], [ LC_HAVE_BVEC_ITER LC_HAVE_TRUNCATE_IPAGES_FINAL LC_IOPS_RENAME_WITH_FLAGS + LC_IOP_SET_ACL # 3.15 LC_VFS_RENAME_6ARGS diff --git a/lustre/llite/file.c b/lustre/llite/file.c index b5c5390..b14fcfe 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -3889,6 +3889,59 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type) RETURN(acl); } +#ifdef HAVE_IOP_SET_ACL +#ifdef CONFIG_FS_POSIX_ACL +int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + const char *name = NULL; + char *value = NULL; + size_t size = 0; + int rc = 0; + ENTRY; + + switch (type) { + case ACL_TYPE_ACCESS: + if (acl) { + rc = posix_acl_update_mode(inode, &inode->i_mode, &acl); + if (rc) + GOTO(out, rc); + } + name = XATTR_NAME_POSIX_ACL_ACCESS; + break; + case ACL_TYPE_DEFAULT: + if (!S_ISDIR(inode->i_mode)) + GOTO(out, rc = acl ? -EACCES : 0); + name = XATTR_NAME_POSIX_ACL_DEFAULT; + break; + default: + GOTO(out, rc = -EINVAL); + } + + if (acl) { + size = posix_acl_xattr_size(acl->a_count); + value = kmalloc(size, GFP_NOFS); + if (value == NULL) + GOTO(out, rc = -ENOMEM); + + rc = posix_acl_to_xattr(&init_user_ns, acl, value, size); + if (rc < 0) + GOTO(out_free, rc); + } + + /* dentry is only used for *.lov attributes so it's safe to be NULL */ + rc = __vfs_setxattr(NULL, inode, name, value, size, XATTR_CREATE); +out_free: + kfree(value); +out: + if (!rc) + set_cached_acl(inode, type, acl); + else + forget_cached_acl(inode, type); + RETURN(rc); +} +#endif /* CONFIG_FS_POSIX_ACL */ +#endif /* HAVE_IOP_SET_ACL */ + #ifndef HAVE_GENERIC_PERMISSION_2ARGS static int # ifdef HAVE_GENERIC_PERMISSION_4ARGS @@ -4092,6 +4145,9 @@ struct inode_operations ll_file_inode_operations = { #ifdef HAVE_IOP_GET_ACL .get_acl = ll_get_acl, #endif +#ifdef HAVE_IOP_SET_ACL + .set_acl = ll_set_acl, +#endif }; /* dynamic ioctl number support routins */ diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 75d7f1b..0d709cf 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -824,6 +824,14 @@ extern void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid, size_t count, int rw); int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat); struct posix_acl *ll_get_acl(struct inode *inode, int type); +#ifdef HAVE_IOP_SET_ACL +#ifdef CONFIG_FS_POSIX_ACL +int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type); +#else /* !CONFIG_FS_POSIX_ACL */ +#define ll_set_acl NULL +#endif /* CONFIG_FS_POSIX_ACL */ + +#endif int ll_migrate(struct inode *parent, struct file *file, int mdtidx, const char *name, int namelen); int ll_get_fid_by_name(struct inode *parent, const char *name, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index c6374c3..ba305aa 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1432,6 +1432,7 @@ void ll_clear_inode(struct inode *inode) ll_xattr_cache_destroy(inode); #ifdef CONFIG_FS_POSIX_ACL + forget_all_cached_acls(inode); if (lli->lli_posix_acl) { LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); posix_acl_release(lli->lli_posix_acl); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index a2f2dee..f53818a 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -1479,30 +1479,33 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild, } const struct inode_operations ll_dir_inode_operations = { - .mknod = ll_mknod, + .mknod = ll_mknod, #ifdef HAVE_IOP_ATOMIC_OPEN - .atomic_open = ll_atomic_open, + .atomic_open = ll_atomic_open, #endif - .lookup = ll_lookup_nd, - .create = ll_create_nd, + .lookup = ll_lookup_nd, + .create = ll_create_nd, /* We need all these non-raw things for NFSD, to not patch it. */ - .unlink = ll_unlink, - .mkdir = ll_mkdir, - .rmdir = ll_rmdir, - .symlink = ll_symlink, - .link = ll_link, - .rename = ll_rename, - .setattr = ll_setattr, - .getattr = ll_getattr, - .permission = ll_inode_permission, + .unlink = ll_unlink, + .mkdir = ll_mkdir, + .rmdir = ll_rmdir, + .symlink = ll_symlink, + .link = ll_link, + .rename = ll_rename, + .setattr = ll_setattr, + .getattr = ll_getattr, + .permission = ll_inode_permission, #ifdef HAVE_IOP_XATTR - .setxattr = ll_setxattr, - .getxattr = ll_getxattr, - .removexattr = ll_removexattr, + .setxattr = ll_setxattr, + .getxattr = ll_getxattr, + .removexattr = ll_removexattr, #endif - .listxattr = ll_listxattr, + .listxattr = ll_listxattr, #ifdef HAVE_IOP_GET_ACL - .get_acl = ll_get_acl, + .get_acl = ll_get_acl, +#endif +#ifdef HAVE_IOP_SET_ACL + .set_acl = ll_set_acl, #endif }; @@ -1519,4 +1522,7 @@ const struct inode_operations ll_special_inode_operations = { #ifdef HAVE_IOP_GET_ACL .get_acl = ll_get_acl, #endif +#ifdef HAVE_IOP_SET_ACL + .set_acl = ll_set_acl, +#endif }; -- 1.8.3.1