0001
0002
0003
0004
0005
0006
0007
0008 #include "protocol.h"
0009 #include "orangefs-kernel.h"
0010 #include "orangefs-bufmap.h"
0011 #include <linux/posix_acl_xattr.h>
0012
0013 struct posix_acl *orangefs_get_acl(struct inode *inode, int type, bool rcu)
0014 {
0015 struct posix_acl *acl;
0016 int ret;
0017 char *key = NULL, *value = NULL;
0018
0019 if (rcu)
0020 return ERR_PTR(-ECHILD);
0021
0022 switch (type) {
0023 case ACL_TYPE_ACCESS:
0024 key = XATTR_NAME_POSIX_ACL_ACCESS;
0025 break;
0026 case ACL_TYPE_DEFAULT:
0027 key = XATTR_NAME_POSIX_ACL_DEFAULT;
0028 break;
0029 default:
0030 gossip_err("orangefs_get_acl: bogus value of type %d\n", type);
0031 return ERR_PTR(-EINVAL);
0032 }
0033
0034
0035
0036
0037
0038
0039
0040 value = kmalloc(ORANGEFS_MAX_XATTR_VALUELEN, GFP_KERNEL);
0041 if (!value)
0042 return ERR_PTR(-ENOMEM);
0043
0044 gossip_debug(GOSSIP_ACL_DEBUG,
0045 "inode %pU, key %s, type %d\n",
0046 get_khandle_from_ino(inode),
0047 key,
0048 type);
0049 ret = orangefs_inode_getxattr(inode, key, value,
0050 ORANGEFS_MAX_XATTR_VALUELEN);
0051
0052 if (ret > 0) {
0053 acl = posix_acl_from_xattr(&init_user_ns, value, ret);
0054 } else if (ret == -ENODATA || ret == -ENOSYS) {
0055 acl = NULL;
0056 } else {
0057 gossip_err("inode %pU retrieving acl's failed with error %d\n",
0058 get_khandle_from_ino(inode),
0059 ret);
0060 acl = ERR_PTR(ret);
0061 }
0062
0063 kfree(value);
0064 return acl;
0065 }
0066
0067 static int __orangefs_set_acl(struct inode *inode, struct posix_acl *acl,
0068 int type)
0069 {
0070 int error = 0;
0071 void *value = NULL;
0072 size_t size = 0;
0073 const char *name = NULL;
0074
0075 switch (type) {
0076 case ACL_TYPE_ACCESS:
0077 name = XATTR_NAME_POSIX_ACL_ACCESS;
0078 break;
0079 case ACL_TYPE_DEFAULT:
0080 name = XATTR_NAME_POSIX_ACL_DEFAULT;
0081 break;
0082 default:
0083 gossip_err("%s: invalid type %d!\n", __func__, type);
0084 return -EINVAL;
0085 }
0086
0087 gossip_debug(GOSSIP_ACL_DEBUG,
0088 "%s: inode %pU, key %s type %d\n",
0089 __func__, get_khandle_from_ino(inode),
0090 name,
0091 type);
0092
0093 if (acl) {
0094 size = posix_acl_xattr_size(acl->a_count);
0095 value = kmalloc(size, GFP_KERNEL);
0096 if (!value)
0097 return -ENOMEM;
0098
0099 error = posix_acl_to_xattr(&init_user_ns, acl, value, size);
0100 if (error < 0)
0101 goto out;
0102 }
0103
0104 gossip_debug(GOSSIP_ACL_DEBUG,
0105 "%s: name %s, value %p, size %zd, acl %p\n",
0106 __func__, name, value, size, acl);
0107
0108
0109
0110
0111
0112
0113 error = orangefs_inode_setxattr(inode, name, value, size, 0);
0114
0115 out:
0116 kfree(value);
0117 if (!error)
0118 set_cached_acl(inode, type, acl);
0119 return error;
0120 }
0121
0122 int orangefs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
0123 struct posix_acl *acl, int type)
0124 {
0125 int error;
0126 struct iattr iattr;
0127 int rc;
0128
0129 memset(&iattr, 0, sizeof iattr);
0130
0131 if (type == ACL_TYPE_ACCESS && acl) {
0132
0133
0134
0135
0136
0137
0138
0139 error = posix_acl_update_mode(&init_user_ns, inode,
0140 &iattr.ia_mode, &acl);
0141 if (error) {
0142 gossip_err("%s: posix_acl_update_mode err: %d\n",
0143 __func__,
0144 error);
0145 return error;
0146 }
0147
0148 if (inode->i_mode != iattr.ia_mode)
0149 iattr.ia_valid = ATTR_MODE;
0150
0151 }
0152
0153 rc = __orangefs_set_acl(inode, acl, type);
0154
0155 if (!rc && (iattr.ia_valid == ATTR_MODE))
0156 rc = __orangefs_setattr(inode, &iattr);
0157
0158 return rc;
0159 }
0160
0161 int orangefs_init_acl(struct inode *inode, struct inode *dir)
0162 {
0163 struct posix_acl *default_acl, *acl;
0164 umode_t mode = inode->i_mode;
0165 struct iattr iattr;
0166 int error = 0;
0167
0168 error = posix_acl_create(dir, &mode, &default_acl, &acl);
0169 if (error)
0170 return error;
0171
0172 if (default_acl) {
0173 error = __orangefs_set_acl(inode, default_acl,
0174 ACL_TYPE_DEFAULT);
0175 posix_acl_release(default_acl);
0176 } else {
0177 inode->i_default_acl = NULL;
0178 }
0179
0180 if (acl) {
0181 if (!error)
0182 error = __orangefs_set_acl(inode, acl, ACL_TYPE_ACCESS);
0183 posix_acl_release(acl);
0184 } else {
0185 inode->i_acl = NULL;
0186 }
0187
0188
0189 if (mode != inode->i_mode) {
0190 memset(&iattr, 0, sizeof iattr);
0191 inode->i_mode = mode;
0192 iattr.ia_mode = mode;
0193 iattr.ia_valid |= ATTR_MODE;
0194 __orangefs_setattr(inode, &iattr);
0195 }
0196
0197 return error;
0198 }