|
@@ -49,3 +49,60 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type)
|
|
|
|
|
|
return acl;
|
|
|
}
|
|
|
+
|
|
|
+int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|
|
+{
|
|
|
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
|
|
|
+ struct ptlrpc_request *req = NULL;
|
|
|
+ const char *name = NULL;
|
|
|
+ size_t value_size = 0;
|
|
|
+ char *value = NULL;
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ switch (type) {
|
|
|
+ case ACL_TYPE_ACCESS:
|
|
|
+ name = XATTR_NAME_POSIX_ACL_ACCESS;
|
|
|
+ if (acl)
|
|
|
+ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case ACL_TYPE_DEFAULT:
|
|
|
+ name = XATTR_NAME_POSIX_ACL_DEFAULT;
|
|
|
+ if (!S_ISDIR(inode->i_mode))
|
|
|
+ rc = acl ? -EACCES : 0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ rc = -EINVAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ if (acl) {
|
|
|
+ value_size = posix_acl_xattr_size(acl->a_count);
|
|
|
+ value = kmalloc(value_size, GFP_NOFS);
|
|
|
+ if (!value) {
|
|
|
+ rc = -ENOMEM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = posix_acl_to_xattr(&init_user_ns, acl, value, value_size);
|
|
|
+ if (rc < 0)
|
|
|
+ goto out_value;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode),
|
|
|
+ value ? OBD_MD_FLXATTR : OBD_MD_FLXATTRRM,
|
|
|
+ name, value, value_size, 0, 0, 0, &req);
|
|
|
+
|
|
|
+ ptlrpc_req_finished(req);
|
|
|
+out_value:
|
|
|
+ kfree(value);
|
|
|
+out:
|
|
|
+ if (rc)
|
|
|
+ forget_cached_acl(inode, type);
|
|
|
+ else
|
|
|
+ set_cached_acl(inode, type, acl);
|
|
|
+ return rc;
|
|
|
+}
|