Whamcloud - gitweb
LU-9183 llite: add support set_acl method in inode operations 65/25965/13
authorDmitry Eremin <dmitry.eremin@intel.com>
Sat, 10 Jun 2017 21:36:52 +0000 (17:36 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 19 Jul 2017 03:29:58 +0000 (03:29 +0000)
Linux kernel v3.14 adds set_acl method to inode operations.
See kernel commit 893d46e443346370cd4ea81d9d35f72952c62a37

Change-Id: Ia40d55364016fafa8633fdaecd317910505f8ad4
Signed-off-by: Dmitry Eremin <dmitry.eremin@intel.com>
Reviewed-on: https://review.whamcloud.com/25965
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/autoconf/lustre-core.m4
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c

index 1cde867..d6a0ad9 100644 (file)
@@ -1771,6 +1771,25 @@ have_bvec_iter, [
 ]) # LC_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 <linux/fs.h>
+],[
+       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
 # 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_HAVE_BVEC_ITER
        LC_HAVE_TRUNCATE_IPAGES_FINAL
        LC_IOPS_RENAME_WITH_FLAGS
+       LC_IOP_SET_ACL
 
        # 3.15
        LC_VFS_RENAME_6ARGS
 
        # 3.15
        LC_VFS_RENAME_6ARGS
index b5c5390..b14fcfe 100644 (file)
@@ -3889,6 +3889,59 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type)
        RETURN(acl);
 }
 
        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
 #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_GET_ACL
        .get_acl        = ll_get_acl,
 #endif
+#ifdef HAVE_IOP_SET_ACL
+       .set_acl        = ll_set_acl,
+#endif
 };
 
 /* dynamic ioctl number support routins */
 };
 
 /* dynamic ioctl number support routins */
index 75d7f1b..0d709cf 100644 (file)
@@ -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);
                               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,
 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,
index c6374c3..ba305aa 100644 (file)
@@ -1432,6 +1432,7 @@ void ll_clear_inode(struct inode *inode)
        ll_xattr_cache_destroy(inode);
 
 #ifdef CONFIG_FS_POSIX_ACL
        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);
        if (lli->lli_posix_acl) {
                LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1);
                posix_acl_release(lli->lli_posix_acl);
index a2f2dee..f53818a 100644 (file)
@@ -1479,30 +1479,33 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild,
 }
 
 const struct inode_operations ll_dir_inode_operations = {
 }
 
 const struct inode_operations ll_dir_inode_operations = {
-       .mknod              = ll_mknod,
+       .mknod          = ll_mknod,
 #ifdef HAVE_IOP_ATOMIC_OPEN
 #ifdef HAVE_IOP_ATOMIC_OPEN
-       .atomic_open        = ll_atomic_open,
+       .atomic_open    = ll_atomic_open,
 #endif
 #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. */
        /* 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
 #ifdef HAVE_IOP_XATTR
-       .setxattr           = ll_setxattr,
-       .getxattr           = ll_getxattr,
-       .removexattr        = ll_removexattr,
+       .setxattr       = ll_setxattr,
+       .getxattr       = ll_getxattr,
+       .removexattr    = ll_removexattr,
 #endif
 #endif
-       .listxattr          = ll_listxattr,
+       .listxattr      = ll_listxattr,
 #ifdef HAVE_IOP_GET_ACL
 #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
 };
 
 #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_GET_ACL
        .get_acl        = ll_get_acl,
 #endif
+#ifdef HAVE_IOP_SET_ACL
+       .set_acl        = ll_set_acl,
+#endif
 };
 };