1 #include <linux/ceph/ceph_debug.h> 2 3 #include "super.h" 4 #include "mds_client.h" 5 6 #include <linux/ceph/decode.h> 7 8 #include <linux/xattr.h> 9 #include <linux/posix_acl_xattr.h> 10 #include <linux/slab.h> 11 12 #define XATTR_CEPH_PREFIX "ceph." 13 #define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1) 14 15 /* 16 * List of handlers for synthetic system.* attributes. Other 17 * attributes are handled directly. 18 */ 19 const struct xattr_handler *ceph_xattr_handlers[] = { 20 #ifdef CONFIG_CEPH_FS_POSIX_ACL 21 &posix_acl_access_xattr_handler, 22 &posix_acl_default_xattr_handler, 23 #endif 24 NULL, 25 }; 26 27 static bool ceph_is_valid_xattr(const char *name) 28 { 29 return !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) || 30 !strncmp(name, XATTR_SECURITY_PREFIX, 31 XATTR_SECURITY_PREFIX_LEN) || 32 !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) || 33 !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || 34 !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 35 } 36 37 /* 38 * These define virtual xattrs exposing the recursive directory 39 * statistics and layout metadata. 40 */ 41 struct ceph_vxattr { 42 char *name; 43 size_t name_size; /* strlen(name) + 1 (for '\0') */ 44 size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val, 45 size_t size); 46 bool readonly, hidden; 47 bool (*exists_cb)(struct ceph_inode_info *ci); 48 }; 49 50 /* layouts */ 51 52 static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci) 53 { 54 size_t s; 55 char *p = (char *)&ci->i_layout; 56 57 for (s = 0; s < sizeof(ci->i_layout); s++, p++) 58 if (*p) 59 return true; 60 return false; 61 } 62 63 static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, 64 size_t size) 65 { 66 int ret; 67 struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); 68 struct ceph_osd_client *osdc = &fsc->client->osdc; 69 s64 pool = ceph_file_layout_pg_pool(ci->i_layout); 70 const char *pool_name; 71 72 dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode); 73 down_read(&osdc->map_sem); 74 pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool); 75 if (pool_name) 76 ret = snprintf(val, size, 77 "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%s", 78 (unsigned long long)ceph_file_layout_su(ci->i_layout), 79 (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), 80 (unsigned long long)ceph_file_layout_object_size(ci->i_layout), 81 pool_name); 82 else 83 ret = snprintf(val, size, 84 "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%lld", 85 (unsigned long long)ceph_file_layout_su(ci->i_layout), 86 (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), 87 (unsigned long long)ceph_file_layout_object_size(ci->i_layout), 88 (unsigned long long)pool); 89 90 up_read(&osdc->map_sem); 91 return ret; 92 } 93 94 static size_t ceph_vxattrcb_layout_stripe_unit(struct ceph_inode_info *ci, 95 char *val, size_t size) 96 { 97 return snprintf(val, size, "%lld", 98 (unsigned long long)ceph_file_layout_su(ci->i_layout)); 99 } 100 101 static size_t ceph_vxattrcb_layout_stripe_count(struct ceph_inode_info *ci, 102 char *val, size_t size) 103 { 104 return snprintf(val, size, "%lld", 105 (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout)); 106 } 107 108 static size_t ceph_vxattrcb_layout_object_size(struct ceph_inode_info *ci, 109 char *val, size_t size) 110 { 111 return snprintf(val, size, "%lld", 112 (unsigned long long)ceph_file_layout_object_size(ci->i_layout)); 113 } 114 115 static size_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci, 116 char *val, size_t size) 117 { 118 int ret; 119 struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); 120 struct ceph_osd_client *osdc = &fsc->client->osdc; 121 s64 pool = ceph_file_layout_pg_pool(ci->i_layout); 122 const char *pool_name; 123 124 down_read(&osdc->map_sem); 125 pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool); 126 if (pool_name) 127 ret = snprintf(val, size, "%s", pool_name); 128 else 129 ret = snprintf(val, size, "%lld", (unsigned long long)pool); 130 up_read(&osdc->map_sem); 131 return ret; 132 } 133 134 /* directories */ 135 136 static size_t ceph_vxattrcb_dir_entries(struct ceph_inode_info *ci, char *val, 137 size_t size) 138 { 139 return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs); 140 } 141 142 static size_t ceph_vxattrcb_dir_files(struct ceph_inode_info *ci, char *val, 143 size_t size) 144 { 145 return snprintf(val, size, "%lld", ci->i_files); 146 } 147 148 static size_t ceph_vxattrcb_dir_subdirs(struct ceph_inode_info *ci, char *val, 149 size_t size) 150 { 151 return snprintf(val, size, "%lld", ci->i_subdirs); 152 } 153 154 static size_t ceph_vxattrcb_dir_rentries(struct ceph_inode_info *ci, char *val, 155 size_t size) 156 { 157 return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs); 158 } 159 160 static size_t ceph_vxattrcb_dir_rfiles(struct ceph_inode_info *ci, char *val, 161 size_t size) 162 { 163 return snprintf(val, size, "%lld", ci->i_rfiles); 164 } 165 166 static size_t ceph_vxattrcb_dir_rsubdirs(struct ceph_inode_info *ci, char *val, 167 size_t size) 168 { 169 return snprintf(val, size, "%lld", ci->i_rsubdirs); 170 } 171 172 static size_t ceph_vxattrcb_dir_rbytes(struct ceph_inode_info *ci, char *val, 173 size_t size) 174 { 175 return snprintf(val, size, "%lld", ci->i_rbytes); 176 } 177 178 static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val, 179 size_t size) 180 { 181 return snprintf(val, size, "%ld.09%ld", (long)ci->i_rctime.tv_sec, 182 (long)ci->i_rctime.tv_nsec); 183 } 184 185 186 #define CEPH_XATTR_NAME(_type, _name) XATTR_CEPH_PREFIX #_type "." #_name 187 #define CEPH_XATTR_NAME2(_type, _name, _name2) \ 188 XATTR_CEPH_PREFIX #_type "." #_name "." #_name2 189 190 #define XATTR_NAME_CEPH(_type, _name) \ 191 { \ 192 .name = CEPH_XATTR_NAME(_type, _name), \ 193 .name_size = sizeof (CEPH_XATTR_NAME(_type, _name)), \ 194 .getxattr_cb = ceph_vxattrcb_ ## _type ## _ ## _name, \ 195 .readonly = true, \ 196 .hidden = false, \ 197 .exists_cb = NULL, \ 198 } 199 #define XATTR_LAYOUT_FIELD(_type, _name, _field) \ 200 { \ 201 .name = CEPH_XATTR_NAME2(_type, _name, _field), \ 202 .name_size = sizeof (CEPH_XATTR_NAME2(_type, _name, _field)), \ 203 .getxattr_cb = ceph_vxattrcb_ ## _name ## _ ## _field, \ 204 .readonly = false, \ 205 .hidden = true, \ 206 .exists_cb = ceph_vxattrcb_layout_exists, \ 207 } 208 209 static struct ceph_vxattr ceph_dir_vxattrs[] = { 210 { 211 .name = "ceph.dir.layout", 212 .name_size = sizeof("ceph.dir.layout"), 213 .getxattr_cb = ceph_vxattrcb_layout, 214 .readonly = false, 215 .hidden = false, 216 .exists_cb = ceph_vxattrcb_layout_exists, 217 }, 218 XATTR_LAYOUT_FIELD(dir, layout, stripe_unit), 219 XATTR_LAYOUT_FIELD(dir, layout, stripe_count), 220 XATTR_LAYOUT_FIELD(dir, layout, object_size), 221 XATTR_LAYOUT_FIELD(dir, layout, pool), 222 XATTR_NAME_CEPH(dir, entries), 223 XATTR_NAME_CEPH(dir, files), 224 XATTR_NAME_CEPH(dir, subdirs), 225 XATTR_NAME_CEPH(dir, rentries), 226 XATTR_NAME_CEPH(dir, rfiles), 227 XATTR_NAME_CEPH(dir, rsubdirs), 228 XATTR_NAME_CEPH(dir, rbytes), 229 XATTR_NAME_CEPH(dir, rctime), 230 { .name = NULL, 0 } /* Required table terminator */ 231 }; 232 static size_t ceph_dir_vxattrs_name_size; /* total size of all names */ 233 234 /* files */ 235 236 static struct ceph_vxattr ceph_file_vxattrs[] = { 237 { 238 .name = "ceph.file.layout", 239 .name_size = sizeof("ceph.file.layout"), 240 .getxattr_cb = ceph_vxattrcb_layout, 241 .readonly = false, 242 .hidden = false, 243 .exists_cb = ceph_vxattrcb_layout_exists, 244 }, 245 XATTR_LAYOUT_FIELD(file, layout, stripe_unit), 246 XATTR_LAYOUT_FIELD(file, layout, stripe_count), 247 XATTR_LAYOUT_FIELD(file, layout, object_size), 248 XATTR_LAYOUT_FIELD(file, layout, pool), 249 { .name = NULL, 0 } /* Required table terminator */ 250 }; 251 static size_t ceph_file_vxattrs_name_size; /* total size of all names */ 252 253 static struct ceph_vxattr *ceph_inode_vxattrs(struct inode *inode) 254 { 255 if (S_ISDIR(inode->i_mode)) 256 return ceph_dir_vxattrs; 257 else if (S_ISREG(inode->i_mode)) 258 return ceph_file_vxattrs; 259 return NULL; 260 } 261 262 static size_t ceph_vxattrs_name_size(struct ceph_vxattr *vxattrs) 263 { 264 if (vxattrs == ceph_dir_vxattrs) 265 return ceph_dir_vxattrs_name_size; 266 if (vxattrs == ceph_file_vxattrs) 267 return ceph_file_vxattrs_name_size; 268 BUG(); 269 270 return 0; 271 } 272 273 /* 274 * Compute the aggregate size (including terminating '\0') of all 275 * virtual extended attribute names in the given vxattr table. 276 */ 277 static size_t __init vxattrs_name_size(struct ceph_vxattr *vxattrs) 278 { 279 struct ceph_vxattr *vxattr; 280 size_t size = 0; 281 282 for (vxattr = vxattrs; vxattr->name; vxattr++) 283 if (!vxattr->hidden) 284 size += vxattr->name_size; 285 286 return size; 287 } 288 289 /* Routines called at initialization and exit time */ 290 291 void __init ceph_xattr_init(void) 292 { 293 ceph_dir_vxattrs_name_size = vxattrs_name_size(ceph_dir_vxattrs); 294 ceph_file_vxattrs_name_size = vxattrs_name_size(ceph_file_vxattrs); 295 } 296 297 void ceph_xattr_exit(void) 298 { 299 ceph_dir_vxattrs_name_size = 0; 300 ceph_file_vxattrs_name_size = 0; 301 } 302 303 static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode, 304 const char *name) 305 { 306 struct ceph_vxattr *vxattr = ceph_inode_vxattrs(inode); 307 308 if (vxattr) { 309 while (vxattr->name) { 310 if (!strcmp(vxattr->name, name)) 311 return vxattr; 312 vxattr++; 313 } 314 } 315 316 return NULL; 317 } 318 319 static int __set_xattr(struct ceph_inode_info *ci, 320 const char *name, int name_len, 321 const char *val, int val_len, 322 int dirty, 323 int should_free_name, int should_free_val, 324 struct ceph_inode_xattr **newxattr) 325 { 326 struct rb_node **p; 327 struct rb_node *parent = NULL; 328 struct ceph_inode_xattr *xattr = NULL; 329 int c; 330 int new = 0; 331 332 p = &ci->i_xattrs.index.rb_node; 333 while (*p) { 334 parent = *p; 335 xattr = rb_entry(parent, struct ceph_inode_xattr, node); 336 c = strncmp(name, xattr->name, min(name_len, xattr->name_len)); 337 if (c < 0) 338 p = &(*p)->rb_left; 339 else if (c > 0) 340 p = &(*p)->rb_right; 341 else { 342 if (name_len == xattr->name_len) 343 break; 344 else if (name_len < xattr->name_len) 345 p = &(*p)->rb_left; 346 else 347 p = &(*p)->rb_right; 348 } 349 xattr = NULL; 350 } 351 352 if (!xattr) { 353 new = 1; 354 xattr = *newxattr; 355 xattr->name = name; 356 xattr->name_len = name_len; 357 xattr->should_free_name = should_free_name; 358 359 ci->i_xattrs.count++; 360 dout("__set_xattr count=%d\n", ci->i_xattrs.count); 361 } else { 362 kfree(*newxattr); 363 *newxattr = NULL; 364 if (xattr->should_free_val) 365 kfree((void *)xattr->val); 366 367 if (should_free_name) { 368 kfree((void *)name); 369 name = xattr->name; 370 } 371 ci->i_xattrs.names_size -= xattr->name_len; 372 ci->i_xattrs.vals_size -= xattr->val_len; 373 } 374 ci->i_xattrs.names_size += name_len; 375 ci->i_xattrs.vals_size += val_len; 376 if (val) 377 xattr->val = val; 378 else 379 xattr->val = ""; 380 381 xattr->val_len = val_len; 382 xattr->dirty = dirty; 383 xattr->should_free_val = (val && should_free_val); 384 385 if (new) { 386 rb_link_node(&xattr->node, parent, p); 387 rb_insert_color(&xattr->node, &ci->i_xattrs.index); 388 dout("__set_xattr_val p=%p\n", p); 389 } 390 391 dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n", 392 ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val); 393 394 return 0; 395 } 396 397 static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci, 398 const char *name) 399 { 400 struct rb_node **p; 401 struct rb_node *parent = NULL; 402 struct ceph_inode_xattr *xattr = NULL; 403 int name_len = strlen(name); 404 int c; 405 406 p = &ci->i_xattrs.index.rb_node; 407 while (*p) { 408 parent = *p; 409 xattr = rb_entry(parent, struct ceph_inode_xattr, node); 410 c = strncmp(name, xattr->name, xattr->name_len); 411 if (c == 0 && name_len > xattr->name_len) 412 c = 1; 413 if (c < 0) 414 p = &(*p)->rb_left; 415 else if (c > 0) 416 p = &(*p)->rb_right; 417 else { 418 dout("__get_xattr %s: found %.*s\n", name, 419 xattr->val_len, xattr->val); 420 return xattr; 421 } 422 } 423 424 dout("__get_xattr %s: not found\n", name); 425 426 return NULL; 427 } 428 429 static void __free_xattr(struct ceph_inode_xattr *xattr) 430 { 431 BUG_ON(!xattr); 432 433 if (xattr->should_free_name) 434 kfree((void *)xattr->name); 435 if (xattr->should_free_val) 436 kfree((void *)xattr->val); 437 438 kfree(xattr); 439 } 440 441 static int __remove_xattr(struct ceph_inode_info *ci, 442 struct ceph_inode_xattr *xattr) 443 { 444 if (!xattr) 445 return -EOPNOTSUPP; 446 447 rb_erase(&xattr->node, &ci->i_xattrs.index); 448 449 if (xattr->should_free_name) 450 kfree((void *)xattr->name); 451 if (xattr->should_free_val) 452 kfree((void *)xattr->val); 453 454 ci->i_xattrs.names_size -= xattr->name_len; 455 ci->i_xattrs.vals_size -= xattr->val_len; 456 ci->i_xattrs.count--; 457 kfree(xattr); 458 459 return 0; 460 } 461 462 static int __remove_xattr_by_name(struct ceph_inode_info *ci, 463 const char *name) 464 { 465 struct rb_node **p; 466 struct ceph_inode_xattr *xattr; 467 int err; 468 469 p = &ci->i_xattrs.index.rb_node; 470 xattr = __get_xattr(ci, name); 471 err = __remove_xattr(ci, xattr); 472 return err; 473 } 474 475 static char *__copy_xattr_names(struct ceph_inode_info *ci, 476 char *dest) 477 { 478 struct rb_node *p; 479 struct ceph_inode_xattr *xattr = NULL; 480 481 p = rb_first(&ci->i_xattrs.index); 482 dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count); 483 484 while (p) { 485 xattr = rb_entry(p, struct ceph_inode_xattr, node); 486 memcpy(dest, xattr->name, xattr->name_len); 487 dest[xattr->name_len] = '\0'; 488 489 dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name, 490 xattr->name_len, ci->i_xattrs.names_size); 491 492 dest += xattr->name_len + 1; 493 p = rb_next(p); 494 } 495 496 return dest; 497 } 498 499 void __ceph_destroy_xattrs(struct ceph_inode_info *ci) 500 { 501 struct rb_node *p, *tmp; 502 struct ceph_inode_xattr *xattr = NULL; 503 504 p = rb_first(&ci->i_xattrs.index); 505 506 dout("__ceph_destroy_xattrs p=%p\n", p); 507 508 while (p) { 509 xattr = rb_entry(p, struct ceph_inode_xattr, node); 510 tmp = p; 511 p = rb_next(tmp); 512 dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p, 513 xattr->name_len, xattr->name); 514 rb_erase(tmp, &ci->i_xattrs.index); 515 516 __free_xattr(xattr); 517 } 518 519 ci->i_xattrs.names_size = 0; 520 ci->i_xattrs.vals_size = 0; 521 ci->i_xattrs.index_version = 0; 522 ci->i_xattrs.count = 0; 523 ci->i_xattrs.index = RB_ROOT; 524 } 525 526 static int __build_xattrs(struct inode *inode) 527 __releases(ci->i_ceph_lock) 528 __acquires(ci->i_ceph_lock) 529 { 530 u32 namelen; 531 u32 numattr = 0; 532 void *p, *end; 533 u32 len; 534 const char *name, *val; 535 struct ceph_inode_info *ci = ceph_inode(inode); 536 int xattr_version; 537 struct ceph_inode_xattr **xattrs = NULL; 538 int err = 0; 539 int i; 540 541 dout("__build_xattrs() len=%d\n", 542 ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0); 543 544 if (ci->i_xattrs.index_version >= ci->i_xattrs.version) 545 return 0; /* already built */ 546 547 __ceph_destroy_xattrs(ci); 548 549 start: 550 /* updated internal xattr rb tree */ 551 if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) { 552 p = ci->i_xattrs.blob->vec.iov_base; 553 end = p + ci->i_xattrs.blob->vec.iov_len; 554 ceph_decode_32_safe(&p, end, numattr, bad); 555 xattr_version = ci->i_xattrs.version; 556 spin_unlock(&ci->i_ceph_lock); 557 558 xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *), 559 GFP_NOFS); 560 err = -ENOMEM; 561 if (!xattrs) 562 goto bad_lock; 563 memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *)); 564 for (i = 0; i < numattr; i++) { 565 xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr), 566 GFP_NOFS); 567 if (!xattrs[i]) 568 goto bad_lock; 569 } 570 571 spin_lock(&ci->i_ceph_lock); 572 if (ci->i_xattrs.version != xattr_version) { 573 /* lost a race, retry */ 574 for (i = 0; i < numattr; i++) 575 kfree(xattrs[i]); 576 kfree(xattrs); 577 xattrs = NULL; 578 goto start; 579 } 580 err = -EIO; 581 while (numattr--) { 582 ceph_decode_32_safe(&p, end, len, bad); 583 namelen = len; 584 name = p; 585 p += len; 586 ceph_decode_32_safe(&p, end, len, bad); 587 val = p; 588 p += len; 589 590 err = __set_xattr(ci, name, namelen, val, len, 591 0, 0, 0, &xattrs[numattr]); 592 593 if (err < 0) 594 goto bad; 595 } 596 kfree(xattrs); 597 } 598 ci->i_xattrs.index_version = ci->i_xattrs.version; 599 ci->i_xattrs.dirty = false; 600 601 return err; 602 bad_lock: 603 spin_lock(&ci->i_ceph_lock); 604 bad: 605 if (xattrs) { 606 for (i = 0; i < numattr; i++) 607 kfree(xattrs[i]); 608 kfree(xattrs); 609 } 610 ci->i_xattrs.names_size = 0; 611 return err; 612 } 613 614 static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size, 615 int val_size) 616 { 617 /* 618 * 4 bytes for the length, and additional 4 bytes per each xattr name, 619 * 4 bytes per each value 620 */ 621 int size = 4 + ci->i_xattrs.count*(4 + 4) + 622 ci->i_xattrs.names_size + 623 ci->i_xattrs.vals_size; 624 dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n", 625 ci->i_xattrs.count, ci->i_xattrs.names_size, 626 ci->i_xattrs.vals_size); 627 628 if (name_size) 629 size += 4 + 4 + name_size + val_size; 630 631 return size; 632 } 633 634 /* 635 * If there are dirty xattrs, reencode xattrs into the prealloc_blob 636 * and swap into place. 637 */ 638 void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) 639 { 640 struct rb_node *p; 641 struct ceph_inode_xattr *xattr = NULL; 642 void *dest; 643 644 dout("__build_xattrs_blob %p\n", &ci->vfs_inode); 645 if (ci->i_xattrs.dirty) { 646 int need = __get_required_blob_size(ci, 0, 0); 647 648 BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len); 649 650 p = rb_first(&ci->i_xattrs.index); 651 dest = ci->i_xattrs.prealloc_blob->vec.iov_base; 652 653 ceph_encode_32(&dest, ci->i_xattrs.count); 654 while (p) { 655 xattr = rb_entry(p, struct ceph_inode_xattr, node); 656 657 ceph_encode_32(&dest, xattr->name_len); 658 memcpy(dest, xattr->name, xattr->name_len); 659 dest += xattr->name_len; 660 ceph_encode_32(&dest, xattr->val_len); 661 memcpy(dest, xattr->val, xattr->val_len); 662 dest += xattr->val_len; 663 664 p = rb_next(p); 665 } 666 667 /* adjust buffer len; it may be larger than we need */ 668 ci->i_xattrs.prealloc_blob->vec.iov_len = 669 dest - ci->i_xattrs.prealloc_blob->vec.iov_base; 670 671 if (ci->i_xattrs.blob) 672 ceph_buffer_put(ci->i_xattrs.blob); 673 ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; 674 ci->i_xattrs.prealloc_blob = NULL; 675 ci->i_xattrs.dirty = false; 676 ci->i_xattrs.version++; 677 } 678 } 679 680 ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value, 681 size_t size) 682 { 683 struct ceph_inode_info *ci = ceph_inode(inode); 684 int err; 685 struct ceph_inode_xattr *xattr; 686 struct ceph_vxattr *vxattr = NULL; 687 688 if (!ceph_is_valid_xattr(name)) 689 return -ENODATA; 690 691 /* let's see if a virtual xattr was requested */ 692 vxattr = ceph_match_vxattr(inode, name); 693 if (vxattr && !(vxattr->exists_cb && !vxattr->exists_cb(ci))) { 694 err = vxattr->getxattr_cb(ci, value, size); 695 return err; 696 } 697 698 spin_lock(&ci->i_ceph_lock); 699 dout("getxattr %p ver=%lld index_ver=%lld\n", inode, 700 ci->i_xattrs.version, ci->i_xattrs.index_version); 701 702 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 703 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 704 goto get_xattr; 705 } else { 706 spin_unlock(&ci->i_ceph_lock); 707 /* get xattrs from mds (if we don't already have them) */ 708 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 709 if (err) 710 return err; 711 } 712 713 spin_lock(&ci->i_ceph_lock); 714 715 err = __build_xattrs(inode); 716 if (err < 0) 717 goto out; 718 719 get_xattr: 720 err = -ENODATA; /* == ENOATTR */ 721 xattr = __get_xattr(ci, name); 722 if (!xattr) 723 goto out; 724 725 err = -ERANGE; 726 if (size && size < xattr->val_len) 727 goto out; 728 729 err = xattr->val_len; 730 if (size == 0) 731 goto out; 732 733 memcpy(value, xattr->val, xattr->val_len); 734 735 out: 736 spin_unlock(&ci->i_ceph_lock); 737 return err; 738 } 739 740 ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, 741 size_t size) 742 { 743 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 744 return generic_getxattr(dentry, name, value, size); 745 746 return __ceph_getxattr(dentry->d_inode, name, value, size); 747 } 748 749 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) 750 { 751 struct inode *inode = dentry->d_inode; 752 struct ceph_inode_info *ci = ceph_inode(inode); 753 struct ceph_vxattr *vxattrs = ceph_inode_vxattrs(inode); 754 u32 vir_namelen = 0; 755 u32 namelen; 756 int err; 757 u32 len; 758 int i; 759 760 spin_lock(&ci->i_ceph_lock); 761 dout("listxattr %p ver=%lld index_ver=%lld\n", inode, 762 ci->i_xattrs.version, ci->i_xattrs.index_version); 763 764 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 765 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 766 goto list_xattr; 767 } else { 768 spin_unlock(&ci->i_ceph_lock); 769 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 770 if (err) 771 return err; 772 } 773 774 spin_lock(&ci->i_ceph_lock); 775 776 err = __build_xattrs(inode); 777 if (err < 0) 778 goto out; 779 780 list_xattr: 781 /* 782 * Start with virtual dir xattr names (if any) (including 783 * terminating '\0' characters for each). 784 */ 785 vir_namelen = ceph_vxattrs_name_size(vxattrs); 786 787 /* adding 1 byte per each variable due to the null termination */ 788 namelen = ci->i_xattrs.names_size + ci->i_xattrs.count; 789 err = -ERANGE; 790 if (size && vir_namelen + namelen > size) 791 goto out; 792 793 err = namelen + vir_namelen; 794 if (size == 0) 795 goto out; 796 797 names = __copy_xattr_names(ci, names); 798 799 /* virtual xattr names, too */ 800 err = namelen; 801 if (vxattrs) { 802 for (i = 0; vxattrs[i].name; i++) { 803 if (!vxattrs[i].hidden && 804 !(vxattrs[i].exists_cb && 805 !vxattrs[i].exists_cb(ci))) { 806 len = sprintf(names, "%s", vxattrs[i].name); 807 names += len + 1; 808 err += len + 1; 809 } 810 } 811 } 812 813 out: 814 spin_unlock(&ci->i_ceph_lock); 815 return err; 816 } 817 818 static int ceph_sync_setxattr(struct dentry *dentry, const char *name, 819 const char *value, size_t size, int flags) 820 { 821 struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); 822 struct inode *inode = dentry->d_inode; 823 struct ceph_inode_info *ci = ceph_inode(inode); 824 struct inode *parent_inode; 825 struct ceph_mds_request *req; 826 struct ceph_mds_client *mdsc = fsc->mdsc; 827 int err; 828 int i, nr_pages; 829 struct page **pages = NULL; 830 void *kaddr; 831 832 /* copy value into some pages */ 833 nr_pages = calc_pages_for(0, size); 834 if (nr_pages) { 835 pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS); 836 if (!pages) 837 return -ENOMEM; 838 err = -ENOMEM; 839 for (i = 0; i < nr_pages; i++) { 840 pages[i] = __page_cache_alloc(GFP_NOFS); 841 if (!pages[i]) { 842 nr_pages = i; 843 goto out; 844 } 845 kaddr = kmap(pages[i]); 846 memcpy(kaddr, value + i*PAGE_CACHE_SIZE, 847 min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE)); 848 } 849 } 850 851 dout("setxattr value=%.*s\n", (int)size, value); 852 853 /* do request */ 854 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, 855 USE_AUTH_MDS); 856 if (IS_ERR(req)) { 857 err = PTR_ERR(req); 858 goto out; 859 } 860 req->r_inode = inode; 861 ihold(inode); 862 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 863 req->r_num_caps = 1; 864 req->r_args.setxattr.flags = cpu_to_le32(flags); 865 req->r_path2 = kstrdup(name, GFP_NOFS); 866 867 req->r_pages = pages; 868 req->r_num_pages = nr_pages; 869 req->r_data_len = size; 870 871 dout("xattr.ver (before): %lld\n", ci->i_xattrs.version); 872 parent_inode = ceph_get_dentry_parent_inode(dentry); 873 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 874 iput(parent_inode); 875 ceph_mdsc_put_request(req); 876 dout("xattr.ver (after): %lld\n", ci->i_xattrs.version); 877 878 out: 879 if (pages) { 880 for (i = 0; i < nr_pages; i++) 881 __free_page(pages[i]); 882 kfree(pages); 883 } 884 return err; 885 } 886 887 int __ceph_setxattr(struct dentry *dentry, const char *name, 888 const void *value, size_t size, int flags) 889 { 890 struct inode *inode = dentry->d_inode; 891 struct ceph_vxattr *vxattr; 892 struct ceph_inode_info *ci = ceph_inode(inode); 893 int issued; 894 int err; 895 int dirty; 896 int name_len = strlen(name); 897 int val_len = size; 898 char *newname = NULL; 899 char *newval = NULL; 900 struct ceph_inode_xattr *xattr = NULL; 901 int required_blob_size; 902 903 if (!ceph_is_valid_xattr(name)) 904 return -EOPNOTSUPP; 905 906 vxattr = ceph_match_vxattr(inode, name); 907 if (vxattr && vxattr->readonly) 908 return -EOPNOTSUPP; 909 910 /* pass any unhandled ceph.* xattrs through to the MDS */ 911 if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) 912 goto do_sync_unlocked; 913 914 /* preallocate memory for xattr name, value, index node */ 915 err = -ENOMEM; 916 newname = kmemdup(name, name_len + 1, GFP_NOFS); 917 if (!newname) 918 goto out; 919 920 if (val_len) { 921 newval = kmemdup(value, val_len, GFP_NOFS); 922 if (!newval) 923 goto out; 924 } 925 926 xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS); 927 if (!xattr) 928 goto out; 929 930 spin_lock(&ci->i_ceph_lock); 931 retry: 932 issued = __ceph_caps_issued(ci, NULL); 933 dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued)); 934 if (!(issued & CEPH_CAP_XATTR_EXCL)) 935 goto do_sync; 936 __build_xattrs(inode); 937 938 required_blob_size = __get_required_blob_size(ci, name_len, val_len); 939 940 if (!ci->i_xattrs.prealloc_blob || 941 required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { 942 struct ceph_buffer *blob; 943 944 spin_unlock(&ci->i_ceph_lock); 945 dout(" preaallocating new blob size=%d\n", required_blob_size); 946 blob = ceph_buffer_new(required_blob_size, GFP_NOFS); 947 if (!blob) 948 goto out; 949 spin_lock(&ci->i_ceph_lock); 950 if (ci->i_xattrs.prealloc_blob) 951 ceph_buffer_put(ci->i_xattrs.prealloc_blob); 952 ci->i_xattrs.prealloc_blob = blob; 953 goto retry; 954 } 955 956 err = __set_xattr(ci, newname, name_len, newval, 957 val_len, 1, 1, 1, &xattr); 958 959 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 960 ci->i_xattrs.dirty = true; 961 inode->i_ctime = CURRENT_TIME; 962 963 spin_unlock(&ci->i_ceph_lock); 964 if (dirty) 965 __mark_inode_dirty(inode, dirty); 966 return err; 967 968 do_sync: 969 spin_unlock(&ci->i_ceph_lock); 970 do_sync_unlocked: 971 err = ceph_sync_setxattr(dentry, name, value, size, flags); 972 out: 973 kfree(newname); 974 kfree(newval); 975 kfree(xattr); 976 return err; 977 } 978 979 int ceph_setxattr(struct dentry *dentry, const char *name, 980 const void *value, size_t size, int flags) 981 { 982 if (ceph_snap(dentry->d_inode) != CEPH_NOSNAP) 983 return -EROFS; 984 985 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 986 return generic_setxattr(dentry, name, value, size, flags); 987 988 return __ceph_setxattr(dentry, name, value, size, flags); 989 } 990 991 static int ceph_send_removexattr(struct dentry *dentry, const char *name) 992 { 993 struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); 994 struct ceph_mds_client *mdsc = fsc->mdsc; 995 struct inode *inode = dentry->d_inode; 996 struct inode *parent_inode; 997 struct ceph_mds_request *req; 998 int err; 999 1000 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, 1001 USE_AUTH_MDS); 1002 if (IS_ERR(req)) 1003 return PTR_ERR(req); 1004 req->r_inode = inode; 1005 ihold(inode); 1006 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 1007 req->r_num_caps = 1; 1008 req->r_path2 = kstrdup(name, GFP_NOFS); 1009 1010 parent_inode = ceph_get_dentry_parent_inode(dentry); 1011 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 1012 iput(parent_inode); 1013 ceph_mdsc_put_request(req); 1014 return err; 1015 } 1016 1017 int __ceph_removexattr(struct dentry *dentry, const char *name) 1018 { 1019 struct inode *inode = dentry->d_inode; 1020 struct ceph_vxattr *vxattr; 1021 struct ceph_inode_info *ci = ceph_inode(inode); 1022 int issued; 1023 int err; 1024 int required_blob_size; 1025 int dirty; 1026 1027 if (!ceph_is_valid_xattr(name)) 1028 return -EOPNOTSUPP; 1029 1030 vxattr = ceph_match_vxattr(inode, name); 1031 if (vxattr && vxattr->readonly) 1032 return -EOPNOTSUPP; 1033 1034 /* pass any unhandled ceph.* xattrs through to the MDS */ 1035 if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) 1036 goto do_sync_unlocked; 1037 1038 err = -ENOMEM; 1039 spin_lock(&ci->i_ceph_lock); 1040 retry: 1041 issued = __ceph_caps_issued(ci, NULL); 1042 dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); 1043 1044 if (!(issued & CEPH_CAP_XATTR_EXCL)) 1045 goto do_sync; 1046 __build_xattrs(inode); 1047 1048 required_blob_size = __get_required_blob_size(ci, 0, 0); 1049 1050 if (!ci->i_xattrs.prealloc_blob || 1051 required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { 1052 struct ceph_buffer *blob; 1053 1054 spin_unlock(&ci->i_ceph_lock); 1055 dout(" preaallocating new blob size=%d\n", required_blob_size); 1056 blob = ceph_buffer_new(required_blob_size, GFP_NOFS); 1057 if (!blob) 1058 goto out; 1059 spin_lock(&ci->i_ceph_lock); 1060 if (ci->i_xattrs.prealloc_blob) 1061 ceph_buffer_put(ci->i_xattrs.prealloc_blob); 1062 ci->i_xattrs.prealloc_blob = blob; 1063 goto retry; 1064 } 1065 1066 err = __remove_xattr_by_name(ceph_inode(inode), name); 1067 1068 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 1069 ci->i_xattrs.dirty = true; 1070 inode->i_ctime = CURRENT_TIME; 1071 spin_unlock(&ci->i_ceph_lock); 1072 if (dirty) 1073 __mark_inode_dirty(inode, dirty); 1074 return err; 1075 do_sync: 1076 spin_unlock(&ci->i_ceph_lock); 1077 do_sync_unlocked: 1078 err = ceph_send_removexattr(dentry, name); 1079 out: 1080 return err; 1081 } 1082 1083 int ceph_removexattr(struct dentry *dentry, const char *name) 1084 { 1085 if (ceph_snap(dentry->d_inode) != CEPH_NOSNAP) 1086 return -EROFS; 1087 1088 if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) 1089 return generic_removexattr(dentry, name); 1090 1091 return __ceph_removexattr(dentry, name); 1092 } 1093