1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <linux/fs.h>
34#include <linux/sched.h>
35#include <linux/mm.h>
36#include <linux/selinux.h>
37
38#define DEBUG_SUBSYSTEM S_LLITE
39
40#include "../include/obd_support.h"
41#include "../include/lustre_dlm.h"
42#include "../include/lustre_ver.h"
43#include "../include/lustre_eacl.h"
44
45#include "llite_internal.h"
46
47static
48int get_xattr_type(const char *name)
49{
50 if (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS))
51 return XATTR_ACL_ACCESS_T;
52
53 if (!strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT))
54 return XATTR_ACL_DEFAULT_T;
55
56 if (!strncmp(name, XATTR_USER_PREFIX,
57 sizeof(XATTR_USER_PREFIX) - 1))
58 return XATTR_USER_T;
59
60 if (!strncmp(name, XATTR_TRUSTED_PREFIX,
61 sizeof(XATTR_TRUSTED_PREFIX) - 1))
62 return XATTR_TRUSTED_T;
63
64 if (!strncmp(name, XATTR_SECURITY_PREFIX,
65 sizeof(XATTR_SECURITY_PREFIX) - 1))
66 return XATTR_SECURITY_T;
67
68 if (!strncmp(name, XATTR_LUSTRE_PREFIX,
69 sizeof(XATTR_LUSTRE_PREFIX) - 1))
70 return XATTR_LUSTRE_T;
71
72 return XATTR_OTHER_T;
73}
74
75static
76int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
77{
78 if ((xattr_type == XATTR_ACL_ACCESS_T ||
79 xattr_type == XATTR_ACL_DEFAULT_T) &&
80 !(sbi->ll_flags & LL_SBI_ACL))
81 return -EOPNOTSUPP;
82
83 if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
84 return -EOPNOTSUPP;
85 if (xattr_type == XATTR_TRUSTED_T && !capable(CFS_CAP_SYS_ADMIN))
86 return -EPERM;
87 if (xattr_type == XATTR_OTHER_T)
88 return -EOPNOTSUPP;
89
90 return 0;
91}
92
93static int
94ll_xattr_set_common(const struct xattr_handler *handler,
95 struct dentry *dentry, struct inode *inode,
96 const char *name, const void *value, size_t size,
97 int flags)
98{
99 char fullname[strlen(handler->prefix) + strlen(name) + 1];
100 struct ll_sb_info *sbi = ll_i2sbi(inode);
101 struct ptlrpc_request *req = NULL;
102 const char *pv = value;
103 __u64 valid;
104 int rc;
105
106 if (flags == XATTR_REPLACE) {
107 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
108 valid = OBD_MD_FLXATTRRM;
109 } else {
110 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
111 valid = OBD_MD_FLXATTR;
112 }
113
114 rc = xattr_type_filter(sbi, handler->flags);
115 if (rc)
116 return rc;
117
118 if ((handler->flags == XATTR_ACL_ACCESS_T ||
119 handler->flags == XATTR_ACL_DEFAULT_T) &&
120 !inode_owner_or_capable(inode))
121 return -EPERM;
122
123
124 if ((handler->flags == XATTR_TRUSTED_T && !strcmp(name, "lov")) ||
125 (handler->flags == XATTR_LUSTRE_T && !strcmp(name, "lov")))
126 return 0;
127
128
129 if ((handler->flags == XATTR_SECURITY_T &&
130 !strcmp(name, "capability")))
131 return 0;
132
133
134 if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
135 strcmp(name, "selinux") == 0)
136 return -EOPNOTSUPP;
137
138 sprintf(fullname, "%s%s\n", handler->prefix, name);
139 rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode),
140 valid, fullname, pv, size, 0, flags,
141 ll_i2suppgid(inode), &req);
142 if (rc) {
143 if (rc == -EOPNOTSUPP && handler->flags == XATTR_USER_T) {
144 LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n");
145 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
146 }
147 return rc;
148 }
149
150 ptlrpc_req_finished(req);
151 return 0;
152}
153
154static int ll_xattr_set(const struct xattr_handler *handler,
155 struct dentry *dentry, struct inode *inode,
156 const char *name, const void *value, size_t size,
157 int flags)
158{
159 LASSERT(inode);
160 LASSERT(name);
161
162 CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
163 PFID(ll_inode2fid(inode)), inode, name);
164
165 if (!strcmp(name, "lov")) {
166 struct lov_user_md *lump = (struct lov_user_md *)value;
167 int op_type = flags == XATTR_REPLACE ? LPROC_LL_REMOVEXATTR :
168 LPROC_LL_SETXATTR;
169 int rc = 0;
170
171 ll_stats_ops_tally(ll_i2sbi(inode), op_type, 1);
172
173 if (size != 0 && size < sizeof(struct lov_user_md))
174 return -EINVAL;
175
176
177
178
179
180 if (!size && lump)
181 lump = NULL;
182
183
184
185
186
187 if (lump && lump->lmm_stripe_offset == 0)
188 lump->lmm_stripe_offset = -1;
189
190 if (lump && S_ISREG(inode->i_mode)) {
191 __u64 it_flags = FMODE_WRITE;
192 int lum_size;
193
194 lum_size = ll_lov_user_md_size(lump);
195 if (lum_size < 0 || size < lum_size)
196 return 0;
197
198 rc = ll_lov_setstripe_ea_info(inode, dentry, it_flags,
199 lump, lum_size);
200
201 rc = 0;
202 } else if (S_ISDIR(inode->i_mode)) {
203 rc = ll_dir_setstripe(inode, lump, 0);
204 }
205
206 return rc;
207
208 } else if (!strcmp(name, "lma") || !strcmp(name, "link")) {
209 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
210 return 0;
211 }
212
213 return ll_xattr_set_common(handler, dentry, inode, name, value, size,
214 flags);
215}
216
217int
218ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer,
219 size_t size, __u64 valid)
220{
221 struct ll_inode_info *lli = ll_i2info(inode);
222 struct ll_sb_info *sbi = ll_i2sbi(inode);
223 struct ptlrpc_request *req = NULL;
224 struct mdt_body *body;
225 void *xdata;
226 int rc;
227
228 if (sbi->ll_xattr_cache_enabled && type != XATTR_ACL_ACCESS_T) {
229 rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
230 if (rc == -EAGAIN)
231 goto getxattr_nocache;
232 if (rc < 0)
233 goto out_xattr;
234
235
236 if (lli->lli_posix_acl && valid & OBD_MD_FLXATTRLS) {
237 if (size == 0) {
238 rc += sizeof(XATTR_NAME_ACL_ACCESS);
239 } else if (size - rc >= sizeof(XATTR_NAME_ACL_ACCESS)) {
240 memcpy(buffer + rc, XATTR_NAME_ACL_ACCESS,
241 sizeof(XATTR_NAME_ACL_ACCESS));
242 rc += sizeof(XATTR_NAME_ACL_ACCESS);
243 } else {
244 rc = -ERANGE;
245 goto out_xattr;
246 }
247 }
248 } else {
249getxattr_nocache:
250 rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode),
251 valid, name, NULL, 0, size, 0, &req);
252 if (rc < 0)
253 goto out_xattr;
254
255 body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
256 LASSERT(body);
257
258
259 if (size == 0) {
260 rc = body->mbo_eadatasize;
261 goto out;
262 }
263
264 if (size < body->mbo_eadatasize) {
265 CERROR("server bug: replied size %u > %u\n",
266 body->mbo_eadatasize, (int)size);
267 rc = -ERANGE;
268 goto out;
269 }
270
271 if (body->mbo_eadatasize == 0) {
272 rc = -ENODATA;
273 goto out;
274 }
275
276
277 xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
278 body->mbo_eadatasize);
279 if (!xdata) {
280 rc = -EFAULT;
281 goto out;
282 }
283
284 memcpy(buffer, xdata, body->mbo_eadatasize);
285 rc = body->mbo_eadatasize;
286 }
287
288out_xattr:
289 if (rc == -EOPNOTSUPP && type == XATTR_USER_T) {
290 LCONSOLE_INFO(
291 "%s: disabling user_xattr feature because it is not supported on the server: rc = %d\n",
292 ll_get_fsname(inode->i_sb, NULL, 0), rc);
293 sbi->ll_flags &= ~LL_SBI_USER_XATTR;
294 }
295out:
296 ptlrpc_req_finished(req);
297 return rc;
298}
299
300static int ll_xattr_get_common(const struct xattr_handler *handler,
301 struct dentry *dentry, struct inode *inode,
302 const char *name, void *buffer, size_t size)
303{
304 char fullname[strlen(handler->prefix) + strlen(name) + 1];
305 struct ll_sb_info *sbi = ll_i2sbi(inode);
306#ifdef CONFIG_FS_POSIX_ACL
307 struct ll_inode_info *lli = ll_i2info(inode);
308#endif
309 int rc;
310
311 CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
312 PFID(ll_inode2fid(inode)), inode);
313
314 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
315
316 rc = xattr_type_filter(sbi, handler->flags);
317 if (rc)
318 return rc;
319
320
321 if ((handler->flags == XATTR_SECURITY_T && !strcmp(name, "capability")))
322 return -ENODATA;
323
324
325 if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
326 !strcmp(name, "selinux"))
327 return -EOPNOTSUPP;
328
329#ifdef CONFIG_FS_POSIX_ACL
330
331
332
333
334 if (handler->flags == XATTR_ACL_ACCESS_T) {
335 struct posix_acl *acl;
336
337 spin_lock(&lli->lli_lock);
338 acl = posix_acl_dup(lli->lli_posix_acl);
339 spin_unlock(&lli->lli_lock);
340
341 if (!acl)
342 return -ENODATA;
343
344 rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
345 posix_acl_release(acl);
346 return rc;
347 }
348 if (handler->flags == XATTR_ACL_DEFAULT_T && !S_ISDIR(inode->i_mode))
349 return -ENODATA;
350#endif
351 sprintf(fullname, "%s%s\n", handler->prefix, name);
352 return ll_xattr_list(inode, fullname, handler->flags, buffer, size,
353 OBD_MD_FLXATTR);
354}
355
356static int ll_xattr_get(const struct xattr_handler *handler,
357 struct dentry *dentry, struct inode *inode,
358 const char *name, void *buffer, size_t size)
359{
360 LASSERT(inode);
361 LASSERT(name);
362
363 CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p), xattr %s\n",
364 PFID(ll_inode2fid(inode)), inode, name);
365
366 if (!strcmp(name, "lov")) {
367 struct lov_stripe_md *lsm;
368 struct lov_user_md *lump;
369 struct lov_mds_md *lmm = NULL;
370 struct ptlrpc_request *request = NULL;
371 int rc = 0, lmmsize = 0;
372
373 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
374
375 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
376 return -ENODATA;
377
378 lsm = ccc_inode_lsm_get(inode);
379 if (!lsm) {
380 if (S_ISDIR(inode->i_mode)) {
381 rc = ll_dir_getstripe(inode, (void **)&lmm,
382 &lmmsize, &request, 0);
383 } else {
384 rc = -ENODATA;
385 }
386 } else {
387
388
389
390 rc = obd_packmd(ll_i2dtexp(inode), &lmm, lsm);
391 lmmsize = rc;
392 }
393 ccc_inode_lsm_put(inode, lsm);
394
395 if (rc < 0)
396 goto out;
397
398 if (size == 0) {
399
400
401
402
403
404 rc = lmmsize;
405 goto out;
406 }
407
408 if (size < lmmsize) {
409 CERROR("server bug: replied size %d > %d for %pd (%s)\n",
410 lmmsize, (int)size, dentry, name);
411 rc = -ERANGE;
412 goto out;
413 }
414
415 lump = buffer;
416 memcpy(lump, lmm, lmmsize);
417
418
419
420
421 lump->lmm_layout_gen = 0;
422
423 rc = lmmsize;
424out:
425 if (request)
426 ptlrpc_req_finished(request);
427 else if (lmm)
428 obd_free_diskmd(ll_i2dtexp(inode), &lmm);
429 return rc;
430 }
431
432 return ll_xattr_get_common(handler, dentry, inode, name, buffer, size);
433}
434
435ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
436{
437 struct inode *inode = d_inode(dentry);
438 int rc = 0, rc2 = 0;
439 struct lov_mds_md *lmm = NULL;
440 struct ptlrpc_request *request = NULL;
441 int lmmsize;
442
443 LASSERT(inode);
444
445 CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
446 PFID(ll_inode2fid(inode)), inode);
447
448 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
449
450 rc = ll_xattr_list(inode, NULL, XATTR_OTHER_T, buffer, size,
451 OBD_MD_FLXATTRLS);
452 if (rc < 0)
453 goto out;
454
455 if (buffer) {
456 struct ll_sb_info *sbi = ll_i2sbi(inode);
457 char *xattr_name = buffer;
458 int xlen, rem = rc;
459
460 while (rem > 0) {
461 xlen = strnlen(xattr_name, rem - 1) + 1;
462 rem -= xlen;
463 if (xattr_type_filter(sbi,
464 get_xattr_type(xattr_name)) == 0) {
465
466
467
468 xattr_name += xlen;
469 continue;
470 }
471
472
473
474 memmove(xattr_name, xattr_name + xlen, rem);
475 rc -= xlen;
476 }
477 }
478 if (S_ISREG(inode->i_mode)) {
479 if (!ll_i2info(inode)->lli_has_smd)
480 rc2 = -1;
481 } else if (S_ISDIR(inode->i_mode)) {
482 rc2 = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize,
483 &request, 0);
484 }
485
486 if (rc2 < 0) {
487 rc2 = 0;
488 goto out;
489 } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) {
490 const int prefix_len = sizeof(XATTR_LUSTRE_PREFIX) - 1;
491 const size_t name_len = sizeof("lov") - 1;
492 const size_t total_len = prefix_len + name_len + 1;
493
494 if (((rc + total_len) > size) && buffer) {
495 ptlrpc_req_finished(request);
496 return -ERANGE;
497 }
498
499 if (buffer) {
500 buffer += rc;
501 memcpy(buffer, XATTR_LUSTRE_PREFIX, prefix_len);
502 memcpy(buffer + prefix_len, "lov", name_len);
503 buffer[prefix_len + name_len] = '\0';
504 }
505 rc2 = total_len;
506 }
507out:
508 ptlrpc_req_finished(request);
509 rc = rc + rc2;
510
511 return rc;
512}
513
514static const struct xattr_handler ll_user_xattr_handler = {
515 .prefix = XATTR_USER_PREFIX,
516 .flags = XATTR_USER_T,
517 .get = ll_xattr_get_common,
518 .set = ll_xattr_set_common,
519};
520
521static const struct xattr_handler ll_trusted_xattr_handler = {
522 .prefix = XATTR_TRUSTED_PREFIX,
523 .flags = XATTR_TRUSTED_T,
524 .get = ll_xattr_get,
525 .set = ll_xattr_set,
526};
527
528static const struct xattr_handler ll_security_xattr_handler = {
529 .prefix = XATTR_SECURITY_PREFIX,
530 .flags = XATTR_SECURITY_T,
531 .get = ll_xattr_get_common,
532 .set = ll_xattr_set_common,
533};
534
535static const struct xattr_handler ll_acl_access_xattr_handler = {
536 .prefix = XATTR_NAME_POSIX_ACL_ACCESS,
537 .flags = XATTR_ACL_ACCESS_T,
538 .get = ll_xattr_get_common,
539 .set = ll_xattr_set_common,
540};
541
542static const struct xattr_handler ll_acl_default_xattr_handler = {
543 .prefix = XATTR_NAME_POSIX_ACL_DEFAULT,
544 .flags = XATTR_ACL_DEFAULT_T,
545 .get = ll_xattr_get_common,
546 .set = ll_xattr_set_common,
547};
548
549static const struct xattr_handler ll_lustre_xattr_handler = {
550 .prefix = XATTR_LUSTRE_PREFIX,
551 .flags = XATTR_LUSTRE_T,
552 .get = ll_xattr_get,
553 .set = ll_xattr_set,
554};
555
556const struct xattr_handler *ll_xattr_handlers[] = {
557 &ll_user_xattr_handler,
558 &ll_trusted_xattr_handler,
559 &ll_security_xattr_handler,
560#ifdef CONFIG_FS_POSIX_ACL
561 &ll_acl_access_xattr_handler,
562 &ll_acl_default_xattr_handler,
563#endif
564 &ll_lustre_xattr_handler,
565 NULL,
566};
567