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