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 { 341 u32 namelen; 342 u32 numattr = 0; 343 void *p, *end; 344 u32 len; 345 const char *name, *val; 346 struct ceph_inode_info *ci = ceph_inode(inode); 347 int xattr_version; 348 struct ceph_inode_xattr **xattrs = NULL; 349 int err = 0; 350 int i; 351 352 dout("__build_xattrs() len=%d\n", 353 ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0); 354 355 if (ci->i_xattrs.index_version >= ci->i_xattrs.version) 356 return 0; /* already built */ 357 358 __ceph_destroy_xattrs(ci); 359 360 start: 361 /* updated internal xattr rb tree */ 362 if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) { 363 p = ci->i_xattrs.blob->vec.iov_base; 364 end = p + ci->i_xattrs.blob->vec.iov_len; 365 ceph_decode_32_safe(&p, end, numattr, bad); 366 xattr_version = ci->i_xattrs.version; 367 spin_unlock(&inode->i_lock); 368 369 xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *), 370 GFP_NOFS); 371 err = -ENOMEM; 372 if (!xattrs) 373 goto bad_lock; 374 memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *)); 375 for (i = 0; i < numattr; i++) { 376 xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr), 377 GFP_NOFS); 378 if (!xattrs[i]) 379 goto bad_lock; 380 } 381 382 spin_lock(&inode->i_lock); 383 if (ci->i_xattrs.version != xattr_version) { 384 /* lost a race, retry */ 385 for (i = 0; i < numattr; i++) 386 kfree(xattrs[i]); 387 kfree(xattrs); 388 goto start; 389 } 390 err = -EIO; 391 while (numattr--) { 392 ceph_decode_32_safe(&p, end, len, bad); 393 namelen = len; 394 name = p; 395 p += len; 396 ceph_decode_32_safe(&p, end, len, bad); 397 val = p; 398 p += len; 399 400 err = __set_xattr(ci, name, namelen, val, len, 401 0, 0, 0, &xattrs[numattr]); 402 403 if (err < 0) 404 goto bad; 405 } 406 kfree(xattrs); 407 } 408 ci->i_xattrs.index_version = ci->i_xattrs.version; 409 ci->i_xattrs.dirty = false; 410 411 return err; 412 bad_lock: 413 spin_lock(&inode->i_lock); 414 bad: 415 if (xattrs) { 416 for (i = 0; i < numattr; i++) 417 kfree(xattrs[i]); 418 kfree(xattrs); 419 } 420 ci->i_xattrs.names_size = 0; 421 return err; 422 } 423 424 static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size, 425 int val_size) 426 { 427 /* 428 * 4 bytes for the length, and additional 4 bytes per each xattr name, 429 * 4 bytes per each value 430 */ 431 int size = 4 + ci->i_xattrs.count*(4 + 4) + 432 ci->i_xattrs.names_size + 433 ci->i_xattrs.vals_size; 434 dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n", 435 ci->i_xattrs.count, ci->i_xattrs.names_size, 436 ci->i_xattrs.vals_size); 437 438 if (name_size) 439 size += 4 + 4 + name_size + val_size; 440 441 return size; 442 } 443 444 /* 445 * If there are dirty xattrs, reencode xattrs into the prealloc_blob 446 * and swap into place. 447 */ 448 void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) 449 { 450 struct rb_node *p; 451 struct ceph_inode_xattr *xattr = NULL; 452 void *dest; 453 454 dout("__build_xattrs_blob %p\n", &ci->vfs_inode); 455 if (ci->i_xattrs.dirty) { 456 int need = __get_required_blob_size(ci, 0, 0); 457 458 BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len); 459 460 p = rb_first(&ci->i_xattrs.index); 461 dest = ci->i_xattrs.prealloc_blob->vec.iov_base; 462 463 ceph_encode_32(&dest, ci->i_xattrs.count); 464 while (p) { 465 xattr = rb_entry(p, struct ceph_inode_xattr, node); 466 467 ceph_encode_32(&dest, xattr->name_len); 468 memcpy(dest, xattr->name, xattr->name_len); 469 dest += xattr->name_len; 470 ceph_encode_32(&dest, xattr->val_len); 471 memcpy(dest, xattr->val, xattr->val_len); 472 dest += xattr->val_len; 473 474 p = rb_next(p); 475 } 476 477 /* adjust buffer len; it may be larger than we need */ 478 ci->i_xattrs.prealloc_blob->vec.iov_len = 479 dest - ci->i_xattrs.prealloc_blob->vec.iov_base; 480 481 if (ci->i_xattrs.blob) 482 ceph_buffer_put(ci->i_xattrs.blob); 483 ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; 484 ci->i_xattrs.prealloc_blob = NULL; 485 ci->i_xattrs.dirty = false; 486 } 487 } 488 489 ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, 490 size_t size) 491 { 492 struct inode *inode = dentry->d_inode; 493 struct ceph_inode_info *ci = ceph_inode(inode); 494 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 495 int err; 496 struct ceph_inode_xattr *xattr; 497 struct ceph_vxattr_cb *vxattr = NULL; 498 499 if (!ceph_is_valid_xattr(name)) 500 return -ENODATA; 501 502 /* let's see if a virtual xattr was requested */ 503 if (vxattrs) 504 vxattr = ceph_match_vxattr(vxattrs, name); 505 506 spin_lock(&inode->i_lock); 507 dout("getxattr %p ver=%lld index_ver=%lld\n", inode, 508 ci->i_xattrs.version, ci->i_xattrs.index_version); 509 510 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 511 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 512 goto get_xattr; 513 } else { 514 spin_unlock(&inode->i_lock); 515 /* get xattrs from mds (if we don't already have them) */ 516 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 517 if (err) 518 return err; 519 } 520 521 spin_lock(&inode->i_lock); 522 523 if (vxattr && vxattr->readonly) { 524 err = vxattr->getxattr_cb(ci, value, size); 525 goto out; 526 } 527 528 err = __build_xattrs(inode); 529 if (err < 0) 530 goto out; 531 532 get_xattr: 533 err = -ENODATA; /* == ENOATTR */ 534 xattr = __get_xattr(ci, name); 535 if (!xattr) { 536 if (vxattr) 537 err = vxattr->getxattr_cb(ci, value, size); 538 goto out; 539 } 540 541 err = -ERANGE; 542 if (size && size < xattr->val_len) 543 goto out; 544 545 err = xattr->val_len; 546 if (size == 0) 547 goto out; 548 549 memcpy(value, xattr->val, xattr->val_len); 550 551 out: 552 spin_unlock(&inode->i_lock); 553 return err; 554 } 555 556 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) 557 { 558 struct inode *inode = dentry->d_inode; 559 struct ceph_inode_info *ci = ceph_inode(inode); 560 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 561 u32 vir_namelen = 0; 562 u32 namelen; 563 int err; 564 u32 len; 565 int i; 566 567 spin_lock(&inode->i_lock); 568 dout("listxattr %p ver=%lld index_ver=%lld\n", inode, 569 ci->i_xattrs.version, ci->i_xattrs.index_version); 570 571 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 572 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 573 goto list_xattr; 574 } else { 575 spin_unlock(&inode->i_lock); 576 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 577 if (err) 578 return err; 579 } 580 581 spin_lock(&inode->i_lock); 582 583 err = __build_xattrs(inode); 584 if (err < 0) 585 goto out; 586 587 list_xattr: 588 vir_namelen = 0; 589 /* include virtual dir xattrs */ 590 if (vxattrs) 591 for (i = 0; vxattrs[i].name; i++) 592 vir_namelen += strlen(vxattrs[i].name) + 1; 593 /* adding 1 byte per each variable due to the null termination */ 594 namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; 595 err = -ERANGE; 596 if (size && namelen > size) 597 goto out; 598 599 err = namelen; 600 if (size == 0) 601 goto out; 602 603 names = __copy_xattr_names(ci, names); 604 605 /* virtual xattr names, too */ 606 if (vxattrs) 607 for (i = 0; vxattrs[i].name; i++) { 608 len = sprintf(names, "%s", vxattrs[i].name); 609 names += len + 1; 610 } 611 612 out: 613 spin_unlock(&inode->i_lock); 614 return err; 615 } 616 617 static int ceph_sync_setxattr(struct dentry *dentry, const char *name, 618 const char *value, size_t size, int flags) 619 { 620 struct ceph_client *client = ceph_sb_to_client(dentry->d_sb); 621 struct inode *inode = dentry->d_inode; 622 struct ceph_inode_info *ci = ceph_inode(inode); 623 struct inode *parent_inode = dentry->d_parent->d_inode; 624 struct ceph_mds_request *req; 625 struct ceph_mds_client *mdsc = &client->mdsc; 626 int err; 627 int i, nr_pages; 628 struct page **pages = NULL; 629 void *kaddr; 630 631 /* copy value into some pages */ 632 nr_pages = calc_pages_for(0, size); 633 if (nr_pages) { 634 pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS); 635 if (!pages) 636 return -ENOMEM; 637 err = -ENOMEM; 638 for (i = 0; i < nr_pages; i++) { 639 pages[i] = __page_cache_alloc(GFP_NOFS); 640 if (!pages[i]) { 641 nr_pages = i; 642 goto out; 643 } 644 kaddr = kmap(pages[i]); 645 memcpy(kaddr, value + i*PAGE_CACHE_SIZE, 646 min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE)); 647 } 648 } 649 650 dout("setxattr value=%.*s\n", (int)size, value); 651 652 /* do request */ 653 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, 654 USE_AUTH_MDS); 655 if (IS_ERR(req)) { 656 err = PTR_ERR(req); 657 goto out; 658 } 659 req->r_inode = igrab(inode); 660 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 661 req->r_num_caps = 1; 662 req->r_args.setxattr.flags = cpu_to_le32(flags); 663 req->r_path2 = kstrdup(name, GFP_NOFS); 664 665 req->r_pages = pages; 666 req->r_num_pages = nr_pages; 667 req->r_data_len = size; 668 669 dout("xattr.ver (before): %lld\n", ci->i_xattrs.version); 670 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 671 ceph_mdsc_put_request(req); 672 dout("xattr.ver (after): %lld\n", ci->i_xattrs.version); 673 674 out: 675 if (pages) { 676 for (i = 0; i < nr_pages; i++) 677 __free_page(pages[i]); 678 kfree(pages); 679 } 680 return err; 681 } 682 683 int ceph_setxattr(struct dentry *dentry, const char *name, 684 const void *value, size_t size, int flags) 685 { 686 struct inode *inode = dentry->d_inode; 687 struct ceph_inode_info *ci = ceph_inode(inode); 688 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 689 int err; 690 int name_len = strlen(name); 691 int val_len = size; 692 char *newname = NULL; 693 char *newval = NULL; 694 struct ceph_inode_xattr *xattr = NULL; 695 int issued; 696 int required_blob_size; 697 698 if (ceph_snap(inode) != CEPH_NOSNAP) 699 return -EROFS; 700 701 if (!ceph_is_valid_xattr(name)) 702 return -EOPNOTSUPP; 703 704 if (vxattrs) { 705 struct ceph_vxattr_cb *vxattr = 706 ceph_match_vxattr(vxattrs, name); 707 if (vxattr && vxattr->readonly) 708 return -EOPNOTSUPP; 709 } 710 711 /* preallocate memory for xattr name, value, index node */ 712 err = -ENOMEM; 713 newname = kmalloc(name_len + 1, GFP_NOFS); 714 if (!newname) 715 goto out; 716 memcpy(newname, name, name_len + 1); 717 718 if (val_len) { 719 newval = kmalloc(val_len + 1, GFP_NOFS); 720 if (!newval) 721 goto out; 722 memcpy(newval, value, val_len); 723 newval[val_len] = '\0'; 724 } 725 726 xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS); 727 if (!xattr) 728 goto out; 729 730 spin_lock(&inode->i_lock); 731 retry: 732 issued = __ceph_caps_issued(ci, NULL); 733 if (!(issued & CEPH_CAP_XATTR_EXCL)) 734 goto do_sync; 735 __build_xattrs(inode); 736 737 required_blob_size = __get_required_blob_size(ci, name_len, val_len); 738 739 if (!ci->i_xattrs.prealloc_blob || 740 required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { 741 struct ceph_buffer *blob = NULL; 742 743 spin_unlock(&inode->i_lock); 744 dout(" preaallocating new blob size=%d\n", required_blob_size); 745 blob = ceph_buffer_new(required_blob_size, GFP_NOFS); 746 if (!blob) 747 goto out; 748 spin_lock(&inode->i_lock); 749 if (ci->i_xattrs.prealloc_blob) 750 ceph_buffer_put(ci->i_xattrs.prealloc_blob); 751 ci->i_xattrs.prealloc_blob = blob; 752 goto retry; 753 } 754 755 dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued)); 756 err = __set_xattr(ci, newname, name_len, newval, 757 val_len, 1, 1, 1, &xattr); 758 __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 759 ci->i_xattrs.dirty = true; 760 inode->i_ctime = CURRENT_TIME; 761 spin_unlock(&inode->i_lock); 762 763 return err; 764 765 do_sync: 766 spin_unlock(&inode->i_lock); 767 err = ceph_sync_setxattr(dentry, name, value, size, flags); 768 out: 769 kfree(newname); 770 kfree(newval); 771 kfree(xattr); 772 return err; 773 } 774 775 static int ceph_send_removexattr(struct dentry *dentry, const char *name) 776 { 777 struct ceph_client *client = ceph_sb_to_client(dentry->d_sb); 778 struct ceph_mds_client *mdsc = &client->mdsc; 779 struct inode *inode = dentry->d_inode; 780 struct inode *parent_inode = dentry->d_parent->d_inode; 781 struct ceph_mds_request *req; 782 int err; 783 784 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, 785 USE_AUTH_MDS); 786 if (IS_ERR(req)) 787 return PTR_ERR(req); 788 req->r_inode = igrab(inode); 789 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 790 req->r_num_caps = 1; 791 req->r_path2 = kstrdup(name, GFP_NOFS); 792 793 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 794 ceph_mdsc_put_request(req); 795 return err; 796 } 797 798 int ceph_removexattr(struct dentry *dentry, const char *name) 799 { 800 struct inode *inode = dentry->d_inode; 801 struct ceph_inode_info *ci = ceph_inode(inode); 802 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 803 int issued; 804 int err; 805 806 if (ceph_snap(inode) != CEPH_NOSNAP) 807 return -EROFS; 808 809 if (!ceph_is_valid_xattr(name)) 810 return -EOPNOTSUPP; 811 812 if (vxattrs) { 813 struct ceph_vxattr_cb *vxattr = 814 ceph_match_vxattr(vxattrs, name); 815 if (vxattr && vxattr->readonly) 816 return -EOPNOTSUPP; 817 } 818 819 spin_lock(&inode->i_lock); 820 __build_xattrs(inode); 821 issued = __ceph_caps_issued(ci, NULL); 822 dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); 823 824 if (!(issued & CEPH_CAP_XATTR_EXCL)) 825 goto do_sync; 826 827 err = __remove_xattr_by_name(ceph_inode(inode), name); 828 __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 829 ci->i_xattrs.dirty = true; 830 inode->i_ctime = CURRENT_TIME; 831 832 spin_unlock(&inode->i_lock); 833 834 return err; 835 do_sync: 836 spin_unlock(&inode->i_lock); 837 err = ceph_send_removexattr(dentry, name); 838 return err; 839 } 840 841