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