0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/slab.h>
0010 #include <linux/fs.h>
0011 #include <linux/xattr.h>
0012 #include "internal.h"
0013
0014
0015
0016
0017 static void afs_acl_success(struct afs_operation *op)
0018 {
0019 afs_vnode_commit_status(op, &op->file[0]);
0020 }
0021
0022 static void afs_acl_put(struct afs_operation *op)
0023 {
0024 kfree(op->acl);
0025 }
0026
0027 static const struct afs_operation_ops afs_fetch_acl_operation = {
0028 .issue_afs_rpc = afs_fs_fetch_acl,
0029 .success = afs_acl_success,
0030 .put = afs_acl_put,
0031 };
0032
0033
0034
0035
0036 static int afs_xattr_get_acl(const struct xattr_handler *handler,
0037 struct dentry *dentry,
0038 struct inode *inode, const char *name,
0039 void *buffer, size_t size)
0040 {
0041 struct afs_operation *op;
0042 struct afs_vnode *vnode = AFS_FS_I(inode);
0043 struct afs_acl *acl = NULL;
0044 int ret;
0045
0046 op = afs_alloc_operation(NULL, vnode->volume);
0047 if (IS_ERR(op))
0048 return -ENOMEM;
0049
0050 afs_op_set_vnode(op, 0, vnode);
0051 op->ops = &afs_fetch_acl_operation;
0052
0053 afs_begin_vnode_operation(op);
0054 afs_wait_for_operation(op);
0055 acl = op->acl;
0056 op->acl = NULL;
0057 ret = afs_put_operation(op);
0058
0059 if (ret == 0) {
0060 ret = acl->size;
0061 if (size > 0) {
0062 if (acl->size <= size)
0063 memcpy(buffer, acl->data, acl->size);
0064 else
0065 ret = -ERANGE;
0066 }
0067 }
0068
0069 kfree(acl);
0070 return ret;
0071 }
0072
0073 static bool afs_make_acl(struct afs_operation *op,
0074 const void *buffer, size_t size)
0075 {
0076 struct afs_acl *acl;
0077
0078 acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL);
0079 if (!acl) {
0080 afs_op_nomem(op);
0081 return false;
0082 }
0083
0084 acl->size = size;
0085 memcpy(acl->data, buffer, size);
0086 op->acl = acl;
0087 return true;
0088 }
0089
0090 static const struct afs_operation_ops afs_store_acl_operation = {
0091 .issue_afs_rpc = afs_fs_store_acl,
0092 .success = afs_acl_success,
0093 .put = afs_acl_put,
0094 };
0095
0096
0097
0098
0099 static int afs_xattr_set_acl(const struct xattr_handler *handler,
0100 struct user_namespace *mnt_userns,
0101 struct dentry *dentry,
0102 struct inode *inode, const char *name,
0103 const void *buffer, size_t size, int flags)
0104 {
0105 struct afs_operation *op;
0106 struct afs_vnode *vnode = AFS_FS_I(inode);
0107
0108 if (flags == XATTR_CREATE)
0109 return -EINVAL;
0110
0111 op = afs_alloc_operation(NULL, vnode->volume);
0112 if (IS_ERR(op))
0113 return -ENOMEM;
0114
0115 afs_op_set_vnode(op, 0, vnode);
0116 if (!afs_make_acl(op, buffer, size))
0117 return afs_put_operation(op);
0118
0119 op->ops = &afs_store_acl_operation;
0120 return afs_do_sync_operation(op);
0121 }
0122
0123 static const struct xattr_handler afs_xattr_afs_acl_handler = {
0124 .name = "afs.acl",
0125 .get = afs_xattr_get_acl,
0126 .set = afs_xattr_set_acl,
0127 };
0128
0129 static const struct afs_operation_ops yfs_fetch_opaque_acl_operation = {
0130 .issue_yfs_rpc = yfs_fs_fetch_opaque_acl,
0131 .success = afs_acl_success,
0132
0133 };
0134
0135
0136
0137
0138 static int afs_xattr_get_yfs(const struct xattr_handler *handler,
0139 struct dentry *dentry,
0140 struct inode *inode, const char *name,
0141 void *buffer, size_t size)
0142 {
0143 struct afs_operation *op;
0144 struct afs_vnode *vnode = AFS_FS_I(inode);
0145 struct yfs_acl *yacl = NULL;
0146 char buf[16], *data;
0147 int which = 0, dsize, ret = -ENOMEM;
0148
0149 if (strcmp(name, "acl") == 0)
0150 which = 0;
0151 else if (strcmp(name, "acl_inherited") == 0)
0152 which = 1;
0153 else if (strcmp(name, "acl_num_cleaned") == 0)
0154 which = 2;
0155 else if (strcmp(name, "vol_acl") == 0)
0156 which = 3;
0157 else
0158 return -EOPNOTSUPP;
0159
0160 yacl = kzalloc(sizeof(struct yfs_acl), GFP_KERNEL);
0161 if (!yacl)
0162 goto error;
0163
0164 if (which == 0)
0165 yacl->flags |= YFS_ACL_WANT_ACL;
0166 else if (which == 3)
0167 yacl->flags |= YFS_ACL_WANT_VOL_ACL;
0168
0169 op = afs_alloc_operation(NULL, vnode->volume);
0170 if (IS_ERR(op))
0171 goto error_yacl;
0172
0173 afs_op_set_vnode(op, 0, vnode);
0174 op->yacl = yacl;
0175 op->ops = &yfs_fetch_opaque_acl_operation;
0176
0177 afs_begin_vnode_operation(op);
0178 afs_wait_for_operation(op);
0179 ret = afs_put_operation(op);
0180
0181 if (ret == 0) {
0182 switch (which) {
0183 case 0:
0184 data = yacl->acl->data;
0185 dsize = yacl->acl->size;
0186 break;
0187 case 1:
0188 data = buf;
0189 dsize = scnprintf(buf, sizeof(buf), "%u", yacl->inherit_flag);
0190 break;
0191 case 2:
0192 data = buf;
0193 dsize = scnprintf(buf, sizeof(buf), "%u", yacl->num_cleaned);
0194 break;
0195 case 3:
0196 data = yacl->vol_acl->data;
0197 dsize = yacl->vol_acl->size;
0198 break;
0199 default:
0200 ret = -EOPNOTSUPP;
0201 goto error_yacl;
0202 }
0203
0204 ret = dsize;
0205 if (size > 0) {
0206 if (dsize <= size)
0207 memcpy(buffer, data, dsize);
0208 else
0209 ret = -ERANGE;
0210 }
0211 } else if (ret == -ENOTSUPP) {
0212 ret = -ENODATA;
0213 }
0214
0215 error_yacl:
0216 yfs_free_opaque_acl(yacl);
0217 error:
0218 return ret;
0219 }
0220
0221 static const struct afs_operation_ops yfs_store_opaque_acl2_operation = {
0222 .issue_yfs_rpc = yfs_fs_store_opaque_acl2,
0223 .success = afs_acl_success,
0224 .put = afs_acl_put,
0225 };
0226
0227
0228
0229
0230 static int afs_xattr_set_yfs(const struct xattr_handler *handler,
0231 struct user_namespace *mnt_userns,
0232 struct dentry *dentry,
0233 struct inode *inode, const char *name,
0234 const void *buffer, size_t size, int flags)
0235 {
0236 struct afs_operation *op;
0237 struct afs_vnode *vnode = AFS_FS_I(inode);
0238 int ret;
0239
0240 if (flags == XATTR_CREATE ||
0241 strcmp(name, "acl") != 0)
0242 return -EINVAL;
0243
0244 op = afs_alloc_operation(NULL, vnode->volume);
0245 if (IS_ERR(op))
0246 return -ENOMEM;
0247
0248 afs_op_set_vnode(op, 0, vnode);
0249 if (!afs_make_acl(op, buffer, size))
0250 return afs_put_operation(op);
0251
0252 op->ops = &yfs_store_opaque_acl2_operation;
0253 ret = afs_do_sync_operation(op);
0254 if (ret == -ENOTSUPP)
0255 ret = -ENODATA;
0256 return ret;
0257 }
0258
0259 static const struct xattr_handler afs_xattr_yfs_handler = {
0260 .prefix = "afs.yfs.",
0261 .get = afs_xattr_get_yfs,
0262 .set = afs_xattr_set_yfs,
0263 };
0264
0265
0266
0267
0268 static int afs_xattr_get_cell(const struct xattr_handler *handler,
0269 struct dentry *dentry,
0270 struct inode *inode, const char *name,
0271 void *buffer, size_t size)
0272 {
0273 struct afs_vnode *vnode = AFS_FS_I(inode);
0274 struct afs_cell *cell = vnode->volume->cell;
0275 size_t namelen;
0276
0277 namelen = cell->name_len;
0278 if (size == 0)
0279 return namelen;
0280 if (namelen > size)
0281 return -ERANGE;
0282 memcpy(buffer, cell->name, namelen);
0283 return namelen;
0284 }
0285
0286 static const struct xattr_handler afs_xattr_afs_cell_handler = {
0287 .name = "afs.cell",
0288 .get = afs_xattr_get_cell,
0289 };
0290
0291
0292
0293
0294
0295 static int afs_xattr_get_fid(const struct xattr_handler *handler,
0296 struct dentry *dentry,
0297 struct inode *inode, const char *name,
0298 void *buffer, size_t size)
0299 {
0300 struct afs_vnode *vnode = AFS_FS_I(inode);
0301 char text[16 + 1 + 24 + 1 + 8 + 1];
0302 size_t len;
0303
0304
0305
0306
0307 len = scnprintf(text, sizeof(text), "%llx:", vnode->fid.vid);
0308 if (vnode->fid.vnode_hi)
0309 len += scnprintf(text + len, sizeof(text) - len, "%x%016llx",
0310 vnode->fid.vnode_hi, vnode->fid.vnode);
0311 else
0312 len += scnprintf(text + len, sizeof(text) - len, "%llx",
0313 vnode->fid.vnode);
0314 len += scnprintf(text + len, sizeof(text) - len, ":%x",
0315 vnode->fid.unique);
0316
0317 if (size == 0)
0318 return len;
0319 if (len > size)
0320 return -ERANGE;
0321 memcpy(buffer, text, len);
0322 return len;
0323 }
0324
0325 static const struct xattr_handler afs_xattr_afs_fid_handler = {
0326 .name = "afs.fid",
0327 .get = afs_xattr_get_fid,
0328 };
0329
0330
0331
0332
0333 static int afs_xattr_get_volume(const struct xattr_handler *handler,
0334 struct dentry *dentry,
0335 struct inode *inode, const char *name,
0336 void *buffer, size_t size)
0337 {
0338 struct afs_vnode *vnode = AFS_FS_I(inode);
0339 const char *volname = vnode->volume->name;
0340 size_t namelen;
0341
0342 namelen = strlen(volname);
0343 if (size == 0)
0344 return namelen;
0345 if (namelen > size)
0346 return -ERANGE;
0347 memcpy(buffer, volname, namelen);
0348 return namelen;
0349 }
0350
0351 static const struct xattr_handler afs_xattr_afs_volume_handler = {
0352 .name = "afs.volume",
0353 .get = afs_xattr_get_volume,
0354 };
0355
0356 const struct xattr_handler *afs_xattr_handlers[] = {
0357 &afs_xattr_afs_acl_handler,
0358 &afs_xattr_afs_cell_handler,
0359 &afs_xattr_afs_fid_handler,
0360 &afs_xattr_afs_volume_handler,
0361 &afs_xattr_yfs_handler,
0362 NULL
0363 };