Whamcloud - gitweb
LU-9183 llite: add support set_acl method in inode operations
[fs/lustre-release.git] / lustre / llite / file.c
index b5c5390..b14fcfe 100644 (file)
@@ -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 */