1 #include "ceph_debug.h" 2 #include "super.h" 3 #include "decode.h" 4 5 #include <linux/xattr.h> 6 #include <linux/slab.h> 7 8 static bool ceph_is_valid_xattr(const char *name) 9 { 10 return !strncmp(name, "ceph.", 5) || 11 !strncmp(name, XATTR_SECURITY_PREFIX, 12 XATTR_SECURITY_PREFIX_LEN) || 13 !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || 14 !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 15 } 16 17 /* 18 * These define virtual xattrs exposing the recursive directory 19 * statistics and layout metadata. 20 */ 21 struct ceph_vxattr_cb { 22 bool readonly; 23 char *name; 24 size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val, 25 size_t size); 26 }; 27 28 /* directories */ 29 30 static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val, 31 size_t size) 32 { 33 return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs); 34 } 35 36 static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val, 37 size_t size) 38 { 39 return snprintf(val, size, "%lld", ci->i_files); 40 } 41 42 static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val, 43 size_t size) 44 { 45 return snprintf(val, size, "%lld", ci->i_subdirs); 46 } 47 48 static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val, 49 size_t size) 50 { 51 return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs); 52 } 53 54 static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val, 55 size_t size) 56 { 57 return snprintf(val, size, "%lld", ci->i_rfiles); 58 } 59 60 static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val, 61 size_t size) 62 { 63 return snprintf(val, size, "%lld", ci->i_rsubdirs); 64 } 65 66 static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val, 67 size_t size) 68 { 69 return snprintf(val, size, "%lld", ci->i_rbytes); 70 } 71 72 static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val, 73 size_t size) 74 { 75 return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec, 76 (long)ci->i_rctime.tv_nsec); 77 } 78 79 static struct ceph_vxattr_cb ceph_dir_vxattrs[] = { 80 { true, "ceph.dir.entries", ceph_vxattrcb_entries}, 81 { true, "ceph.dir.files", ceph_vxattrcb_files}, 82 { true, "ceph.dir.subdirs", ceph_vxattrcb_subdirs}, 83 { true, "ceph.dir.rentries", ceph_vxattrcb_rentries}, 84 { true, "ceph.dir.rfiles", ceph_vxattrcb_rfiles}, 85 { true, "ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs}, 86 { true, "ceph.dir.rbytes", ceph_vxattrcb_rbytes}, 87 { true, "ceph.dir.rctime", ceph_vxattrcb_rctime}, 88 { true, NULL, NULL } 89 }; 90 91 /* files */ 92 93 static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, 94 size_t size) 95 { 96 int ret; 97 98 ret = snprintf(val, size, 99 "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n", 100 (unsigned long long)ceph_file_layout_su(ci->i_layout), 101 (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), 102 (unsigned long long)ceph_file_layout_object_size(ci->i_layout)); 103 if (ceph_file_layout_pg_preferred(ci->i_layout)) 104 ret += snprintf(val + ret, size, "preferred_osd=%lld\n", 105 (unsigned long long)ceph_file_layout_pg_preferred( 106 ci->i_layout)); 107 return ret; 108 } 109 110 static struct ceph_vxattr_cb ceph_file_vxattrs[] = { 111 { true, "ceph.layout", ceph_vxattrcb_layout}, 112 { NULL, NULL } 113 }; 114 115 static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode) 116 { 117 if (S_ISDIR(inode->i_mode)) 118 return ceph_dir_vxattrs; 119 else if (S_ISREG(inode->i_mode)) 120 return ceph_file_vxattrs; 121 return NULL; 122 } 123 124 static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr, 125 const char *name) 126 { 127 do { 128 if (strcmp(vxattr->name, name) == 0) 129 return vxattr; 130 vxattr++; 131 } while (vxattr->name); 132 return NULL; 133 } 134 135 static int __set_xattr(struct ceph_inode_info *ci, 136 const char *name, int name_len, 137 const char *val, int val_len, 138 int dirty, 139 int should_free_name, int should_free_val, 140 struct ceph_inode_xattr **newxattr) 141 { 142 struct rb_node **p; 143 struct rb_node *parent = NULL; 144 struct ceph_inode_xattr *xattr = NULL; 145 int c; 146 int new = 0; 147 148 p = &ci->i_xattrs.index.rb_node; 149 while (*p) { 150 parent = *p; 151 xattr = rb_entry(parent, struct ceph_inode_xattr, node); 152 c = strncmp(name, xattr->name, min(name_len, xattr->name_len)); 153 if (c < 0) 154 p = &(*p)->rb_left; 155 else if (c > 0) 156 p = &(*p)->rb_right; 157 else { 158 if (name_len == xattr->name_len) 159 break; 160 else if (name_len < xattr->name_len) 161 p = &(*p)->rb_left; 162 else 163 p = &(*p)->rb_right; 164 } 165 xattr = NULL; 166 } 167 168 if (!xattr) { 169 new = 1; 170 xattr = *newxattr; 171 xattr->name = name; 172 xattr->name_len = name_len; 173 xattr->should_free_name = should_free_name; 174 175 ci->i_xattrs.count++; 176 dout("__set_xattr count=%d\n", ci->i_xattrs.count); 177 } else { 178 kfree(*newxattr); 179 *newxattr = NULL; 180 if (xattr->should_free_val) 181 kfree((void *)xattr->val); 182 183 if (should_free_name) { 184 kfree((void *)name); 185 name = xattr->name; 186 } 187 ci->i_xattrs.names_size -= xattr->name_len; 188 ci->i_xattrs.vals_size -= xattr->val_len; 189 } 190 ci->i_xattrs.names_size += name_len; 191 ci->i_xattrs.vals_size += val_len; 192 if (val) 193 xattr->val = val; 194 else 195 xattr->val = ""; 196 197 xattr->val_len = val_len; 198 xattr->dirty = dirty; 199 xattr->should_free_val = (val && should_free_val); 200 201 if (new) { 202 rb_link_node(&xattr->node, parent, p); 203 rb_insert_color(&xattr->node, &ci->i_xattrs.index); 204 dout("__set_xattr_val p=%p\n", p); 205 } 206 207 dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n", 208 ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val); 209 210 return 0; 211 } 212 213 static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci, 214 const char *name) 215 { 216 struct rb_node **p; 217 struct rb_node *parent = NULL; 218 struct ceph_inode_xattr *xattr = NULL; 219 int c; 220 221 p = &ci->i_xattrs.index.rb_node; 222 while (*p) { 223 parent = *p; 224 xattr = rb_entry(parent, struct ceph_inode_xattr, node); 225 c = strncmp(name, xattr->name, xattr->name_len); 226 if (c < 0) 227 p = &(*p)->rb_left; 228 else if (c > 0) 229 p = &(*p)->rb_right; 230 else { 231 dout("__get_xattr %s: found %.*s\n", name, 232 xattr->val_len, xattr->val); 233 return xattr; 234 } 235 } 236 237 dout("__get_xattr %s: not found\n", name); 238 239 return NULL; 240 } 241 242 static void __free_xattr(struct ceph_inode_xattr *xattr) 243 { 244 BUG_ON(!xattr); 245 246 if (xattr->should_free_name) 247 kfree((void *)xattr->name); 248 if (xattr->should_free_val) 249 kfree((void *)xattr->val); 250 251 kfree(xattr); 252 } 253 254 static int __remove_xattr(struct ceph_inode_info *ci, 255 struct ceph_inode_xattr *xattr) 256 { 257 if (!xattr) 258 return -EOPNOTSUPP; 259 260 rb_erase(&xattr->node, &ci->i_xattrs.index); 261 262 if (xattr->should_free_name) 263 kfree((void *)xattr->name); 264 if (xattr->should_free_val) 265 kfree((void *)xattr->val); 266 267 ci->i_xattrs.names_size -= xattr->name_len; 268 ci->i_xattrs.vals_size -= xattr->val_len; 269 ci->i_xattrs.count--; 270 kfree(xattr); 271 272 return 0; 273 } 274 275 static int __remove_xattr_by_name(struct ceph_inode_info *ci, 276 const char *name) 277 { 278 struct rb_node **p; 279 struct ceph_inode_xattr *xattr; 280 int err; 281 282 p = &ci->i_xattrs.index.rb_node; 283 xattr = __get_xattr(ci, name); 284 err = __remove_xattr(ci, xattr); 285 return err; 286 } 287 288 static char *__copy_xattr_names(struct ceph_inode_info *ci, 289 char *dest) 290 { 291 struct rb_node *p; 292 struct ceph_inode_xattr *xattr = NULL; 293 294 p = rb_first(&ci->i_xattrs.index); 295 dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count); 296 297 while (p) { 298 xattr = rb_entry(p, struct ceph_inode_xattr, node); 299 memcpy(dest, xattr->name, xattr->name_len); 300 dest[xattr->name_len] = '\0'; 301 302 dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name, 303 xattr->name_len, ci->i_xattrs.names_size); 304 305 dest += xattr->name_len + 1; 306 p = rb_next(p); 307 } 308 309 return dest; 310 } 311 312 void __ceph_destroy_xattrs(struct ceph_inode_info *ci) 313 { 314 struct rb_node *p, *tmp; 315 struct ceph_inode_xattr *xattr = NULL; 316 317 p = rb_first(&ci->i_xattrs.index); 318 319 dout("__ceph_destroy_xattrs p=%p\n", p); 320 321 while (p) { 322 xattr = rb_entry(p, struct ceph_inode_xattr, node); 323 tmp = p; 324 p = rb_next(tmp); 325 dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p, 326 xattr->name_len, xattr->name); 327 rb_erase(tmp, &ci->i_xattrs.index); 328 329 __free_xattr(xattr); 330 } 331 332 ci->i_xattrs.names_size = 0; 333 ci->i_xattrs.vals_size = 0; 334 ci->i_xattrs.index_version = 0; 335 ci->i_xattrs.count = 0; 336 ci->i_xattrs.index = RB_ROOT; 337 } 338 339 static int __build_xattrs(struct inode *inode) 340 __releases(inode->i_lock) 341 __acquires(inode->i_lock) 342 { 343 u32 namelen; 344 u32 numattr = 0; 345 void *p, *end; 346 u32 len; 347 const char *name, *val; 348 struct ceph_inode_info *ci = ceph_inode(inode); 349 int xattr_version; 350 struct ceph_inode_xattr **xattrs = NULL; 351 int err = 0; 352 int i; 353 354 dout("__build_xattrs() len=%d\n", 355 ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0); 356 357 if (ci->i_xattrs.index_version >= ci->i_xattrs.version) 358 return 0; /* already built */ 359 360 __ceph_destroy_xattrs(ci); 361 362 start: 363 /* updated internal xattr rb tree */ 364 if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) { 365 p = ci->i_xattrs.blob->vec.iov_base; 366 end = p + ci->i_xattrs.blob->vec.iov_len; 367 ceph_decode_32_safe(&p, end, numattr, bad); 368 xattr_version = ci->i_xattrs.version; 369 spin_unlock(&inode->i_lock); 370 371 xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *), 372 GFP_NOFS); 373 err = -ENOMEM; 374 if (!xattrs) 375 goto bad_lock; 376 memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *)); 377 for (i = 0; i < numattr; i++) { 378 xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr), 379 GFP_NOFS); 380 if (!xattrs[i]) 381 goto bad_lock; 382 } 383 384 spin_lock(&inode->i_lock); 385 if (ci->i_xattrs.version != xattr_version) { 386 /* lost a race, retry */ 387 for (i = 0; i < numattr; i++) 388 kfree(xattrs[i]); 389 kfree(xattrs); 390 goto start; 391 } 392 err = -EIO; 393 while (numattr--) { 394 ceph_decode_32_safe(&p, end, len, bad); 395 namelen = len; 396 name = p; 397 p += len; 398 ceph_decode_32_safe(&p, end, len, bad); 399 val = p; 400 p += len; 401 402 err = __set_xattr(ci, name, namelen, val, len, 403 0, 0, 0, &xattrs[numattr]); 404 405 if (err < 0) 406 goto bad; 407 } 408 kfree(xattrs); 409 } 410 ci->i_xattrs.index_version = ci->i_xattrs.version; 411 ci->i_xattrs.dirty = false; 412 413 return err; 414 bad_lock: 415 spin_lock(&inode->i_lock); 416 bad: 417 if (xattrs) { 418 for (i = 0; i < numattr; i++) 419 kfree(xattrs[i]); 420 kfree(xattrs); 421 } 422 ci->i_xattrs.names_size = 0; 423 return err; 424 } 425 426 static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size, 427 int val_size) 428 { 429 /* 430 * 4 bytes for the length, and additional 4 bytes per each xattr name, 431 * 4 bytes per each value 432 */ 433 int size = 4 + ci->i_xattrs.count*(4 + 4) + 434 ci->i_xattrs.names_size + 435 ci->i_xattrs.vals_size; 436 dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n", 437 ci->i_xattrs.count, ci->i_xattrs.names_size, 438 ci->i_xattrs.vals_size); 439 440 if (name_size) 441 size += 4 + 4 + name_size + val_size; 442 443 return size; 444 } 445 446 /* 447 * If there are dirty xattrs, reencode xattrs into the prealloc_blob 448 * and swap into place. 449 */ 450 void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) 451 { 452 struct rb_node *p; 453 struct ceph_inode_xattr *xattr = NULL; 454 void *dest; 455 456 dout("__build_xattrs_blob %p\n", &ci->vfs_inode); 457 if (ci->i_xattrs.dirty) { 458 int need = __get_required_blob_size(ci, 0, 0); 459 460 BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len); 461 462 p = rb_first(&ci->i_xattrs.index); 463 dest = ci->i_xattrs.prealloc_blob->vec.iov_base; 464 465 ceph_encode_32(&dest, ci->i_xattrs.count); 466 while (p) { 467 xattr = rb_entry(p, struct ceph_inode_xattr, node); 468 469 ceph_encode_32(&dest, xattr->name_len); 470 memcpy(dest, xattr->name, xattr->name_len); 471 dest += xattr->name_len; 472 ceph_encode_32(&dest, xattr->val_len); 473 memcpy(dest, xattr->val, xattr->val_len); 474 dest += xattr->val_len; 475 476 p = rb_next(p); 477 } 478 479 /* adjust buffer len; it may be larger than we need */ 480 ci->i_xattrs.prealloc_blob->vec.iov_len = 481 dest - ci->i_xattrs.prealloc_blob->vec.iov_base; 482 483 if (ci->i_xattrs.blob) 484 ceph_buffer_put(ci->i_xattrs.blob); 485 ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; 486 ci->i_xattrs.prealloc_blob = NULL; 487 ci->i_xattrs.dirty = false; 488 } 489 } 490 491 ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, 492 size_t size) 493 { 494 struct inode *inode = dentry->d_inode; 495 struct ceph_inode_info *ci = ceph_inode(inode); 496 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 497 int err; 498 struct ceph_inode_xattr *xattr; 499 struct ceph_vxattr_cb *vxattr = NULL; 500 501 if (!ceph_is_valid_xattr(name)) 502 return -ENODATA; 503 504 /* let's see if a virtual xattr was requested */ 505 if (vxattrs) 506 vxattr = ceph_match_vxattr(vxattrs, name); 507 508 spin_lock(&inode->i_lock); 509 dout("getxattr %p ver=%lld index_ver=%lld\n", inode, 510 ci->i_xattrs.version, ci->i_xattrs.index_version); 511 512 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 513 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 514 goto get_xattr; 515 } else { 516 spin_unlock(&inode->i_lock); 517 /* get xattrs from mds (if we don't already have them) */ 518 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 519 if (err) 520 return err; 521 } 522 523 spin_lock(&inode->i_lock); 524 525 if (vxattr && vxattr->readonly) { 526 err = vxattr->getxattr_cb(ci, value, size); 527 goto out; 528 } 529 530 err = __build_xattrs(inode); 531 if (err < 0) 532 goto out; 533 534 get_xattr: 535 err = -ENODATA; /* == ENOATTR */ 536 xattr = __get_xattr(ci, name); 537 if (!xattr) { 538 if (vxattr) 539 err = vxattr->getxattr_cb(ci, value, size); 540 goto out; 541 } 542 543 err = -ERANGE; 544 if (size && size < xattr->val_len) 545 goto out; 546 547 err = xattr->val_len; 548 if (size == 0) 549 goto out; 550 551 memcpy(value, xattr->val, xattr->val_len); 552 553 out: 554 spin_unlock(&inode->i_lock); 555 return err; 556 } 557 558 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) 559 { 560 struct inode *inode = dentry->d_inode; 561 struct ceph_inode_info *ci = ceph_inode(inode); 562 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 563 u32 vir_namelen = 0; 564 u32 namelen; 565 int err; 566 u32 len; 567 int i; 568 569 spin_lock(&inode->i_lock); 570 dout("listxattr %p ver=%lld index_ver=%lld\n", inode, 571 ci->i_xattrs.version, ci->i_xattrs.index_version); 572 573 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 574 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 575 goto list_xattr; 576 } else { 577 spin_unlock(&inode->i_lock); 578 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 579 if (err) 580 return err; 581 } 582 583 spin_lock(&inode->i_lock); 584 585 err = __build_xattrs(inode); 586 if (err < 0) 587 goto out; 588 589 list_xattr: 590 vir_namelen = 0; 591 /* include virtual dir xattrs */ 592 if (vxattrs) 593 for (i = 0; vxattrs[i].name; i++) 594 vir_namelen += strlen(vxattrs[i].name) + 1; 595 /* adding 1 byte per each variable due to the null termination */ 596 namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; 597 err = -ERANGE; 598 if (size && namelen > size) 599 goto out; 600 601 err = namelen; 602 if (size == 0) 603 goto out; 604 605 names = __copy_xattr_names(ci, names); 606 607 /* virtual xattr names, too */ 608 if (vxattrs) 609 for (i = 0; vxattrs[i].name; i++) { 610 len = sprintf(names, "%s", vxattrs[i].name); 611 names += len + 1; 612 } 613 614 out: 615 spin_unlock(&inode->i_lock); 616 return err; 617 } 618 619 static int ceph_sync_setxattr(struct dentry *dentry, const char *name, 620 const char *value, size_t size, int flags) 621 { 622 struct ceph_client *client = ceph_sb_to_client(dentry->d_sb); 623 struct inode *inode = dentry->d_inode; 624 struct ceph_inode_info *ci = ceph_inode(inode); 625 struct inode *parent_inode = dentry->d_parent->d_inode; 626 struct ceph_mds_request *req; 627 struct ceph_mds_client *mdsc = &client->mdsc; 628 int err; 629 int i, nr_pages; 630 struct page **pages = NULL; 631 void *kaddr; 632 633 /* copy value into some pages */ 634 nr_pages = calc_pages_for(0, size); 635 if (nr_pages) { 636 pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS); 637 if (!pages) 638 return -ENOMEM; 639 err = -ENOMEM; 640 for (i = 0; i < nr_pages; i++) { 641 pages[i] = __page_cache_alloc(GFP_NOFS); 642 if (!pages[i]) { 643 nr_pages = i; 644 goto out; 645 } 646 kaddr = kmap(pages[i]); 647 memcpy(kaddr, value + i*PAGE_CACHE_SIZE, 648 min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE)); 649 } 650 } 651 652 dout("setxattr value=%.*s\n", (int)size, value); 653 654 /* do request */ 655 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, 656 USE_AUTH_MDS); 657 if (IS_ERR(req)) { 658 err = PTR_ERR(req); 659 goto out; 660 } 661 req->r_inode = igrab(inode); 662 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 663 req->r_num_caps = 1; 664 req->r_args.setxattr.flags = cpu_to_le32(flags); 665 req->r_path2 = kstrdup(name, GFP_NOFS); 666 667 req->r_pages = pages; 668 req->r_num_pages = nr_pages; 669 req->r_data_len = size; 670 671 dout("xattr.ver (before): %lld\n", ci->i_xattrs.version); 672 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 673 ceph_mdsc_put_request(req); 674 dout("xattr.ver (after): %lld\n", ci->i_xattrs.version); 675 676 out: 677 if (pages) { 678 for (i = 0; i < nr_pages; i++) 679 __free_page(pages[i]); 680 kfree(pages); 681 } 682 return err; 683 } 684 685 int ceph_setxattr(struct dentry *dentry, const char *name, 686 const void *value, size_t size, int flags) 687 { 688 struct inode *inode = dentry->d_inode; 689 struct ceph_inode_info *ci = ceph_inode(inode); 690 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 691 int err; 692 int name_len = strlen(name); 693 int val_len = size; 694 char *newname = NULL; 695 char *newval = NULL; 696 struct ceph_inode_xattr *xattr = NULL; 697 int issued; 698 int required_blob_size; 699 700 if (ceph_snap(inode) != CEPH_NOSNAP) 701 return -EROFS; 702 703 if (!ceph_is_valid_xattr(name)) 704 return -EOPNOTSUPP; 705 706 if (vxattrs) { 707 struct ceph_vxattr_cb *vxattr = 708 ceph_match_vxattr(vxattrs, name); 709 if (vxattr && vxattr->readonly) 710 return -EOPNOTSUPP; 711 } 712 713 /* preallocate memory for xattr name, value, index node */ 714 err = -ENOMEM; 715 newname = kmalloc(name_len + 1, GFP_NOFS); 716 if (!newname) 717 goto out; 718 memcpy(newname, name, name_len + 1); 719 720 if (val_len) { 721 newval = kmalloc(val_len + 1, GFP_NOFS); 722 if (!newval) 723 goto out; 724 memcpy(newval, value, val_len); 725 newval[val_len] = '\0'; 726 } 727 728 xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS); 729 if (!xattr) 730 goto out; 731 732 spin_lock(&inode->i_lock); 733 retry: 734 issued = __ceph_caps_issued(ci, NULL); 735 if (!(issued & CEPH_CAP_XATTR_EXCL)) 736 goto do_sync; 737 __build_xattrs(inode); 738 739 required_blob_size = __get_required_blob_size(ci, name_len, val_len); 740 741 if (!ci->i_xattrs.prealloc_blob || 742 required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { 743 struct ceph_buffer *blob = NULL; 744 745 spin_unlock(&inode->i_lock); 746 dout(" preaallocating new blob size=%d\n", required_blob_size); 747 blob = ceph_buffer_new(required_blob_size, GFP_NOFS); 748 if (!blob) 749 goto out; 750 spin_lock(&inode->i_lock); 751 if (ci->i_xattrs.prealloc_blob) 752 ceph_buffer_put(ci->i_xattrs.prealloc_blob); 753 ci->i_xattrs.prealloc_blob = blob; 754 goto retry; 755 } 756 757 dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued)); 758 err = __set_xattr(ci, newname, name_len, newval, 759 val_len, 1, 1, 1, &xattr); 760 __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 761 ci->i_xattrs.dirty = true; 762 inode->i_ctime = CURRENT_TIME; 763 spin_unlock(&inode->i_lock); 764 765 return err; 766 767 do_sync: 768 spin_unlock(&inode->i_lock); 769 err = ceph_sync_setxattr(dentry, name, value, size, flags); 770 out: 771 kfree(newname); 772 kfree(newval); 773 kfree(xattr); 774 return err; 775 } 776 777 static int ceph_send_removexattr(struct dentry *dentry, const char *name) 778 { 779 struct ceph_client *client = ceph_sb_to_client(dentry->d_sb); 780 struct ceph_mds_client *mdsc = &client->mdsc; 781 struct inode *inode = dentry->d_inode; 782 struct inode *parent_inode = dentry->d_parent->d_inode; 783 struct ceph_mds_request *req; 784 int err; 785 786 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, 787 USE_AUTH_MDS); 788 if (IS_ERR(req)) 789 return PTR_ERR(req); 790 req->r_inode = igrab(inode); 791 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 792 req->r_num_caps = 1; 793 req->r_path2 = kstrdup(name, GFP_NOFS); 794 795 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 796 ceph_mdsc_put_request(req); 797 return err; 798 } 799 800 int ceph_removexattr(struct dentry *dentry, const char *name) 801 { 802 struct inode *inode = dentry->d_inode; 803 struct ceph_inode_info *ci = ceph_inode(inode); 804 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 805 int issued; 806 int err; 807 808 if (ceph_snap(inode) != CEPH_NOSNAP) 809 return -EROFS; 810 811 if (!ceph_is_valid_xattr(name)) 812 return -EOPNOTSUPP; 813 814 if (vxattrs) { 815 struct ceph_vxattr_cb *vxattr = 816 ceph_match_vxattr(vxattrs, name); 817 if (vxattr && vxattr->readonly) 818 return -EOPNOTSUPP; 819 } 820 821 spin_lock(&inode->i_lock); 822 __build_xattrs(inode); 823 issued = __ceph_caps_issued(ci, NULL); 824 dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); 825 826 if (!(issued & CEPH_CAP_XATTR_EXCL)) 827 goto do_sync; 828 829 err = __remove_xattr_by_name(ceph_inode(inode), name); 830 __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 831 ci->i_xattrs.dirty = true; 832 inode->i_ctime = CURRENT_TIME; 833 834 spin_unlock(&inode->i_lock); 835 836 return err; 837 do_sync: 838 spin_unlock(&inode->i_lock); 839 err = ceph_send_removexattr(dentry, name); 840 return err; 841 } 842 843