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/slab.h> 10 11 static bool ceph_is_valid_xattr(const char *name) 12 { 13 return !strncmp(name, "ceph.", 5) || 14 !strncmp(name, XATTR_SECURITY_PREFIX, 15 XATTR_SECURITY_PREFIX_LEN) || 16 !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || 17 !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); 18 } 19 20 /* 21 * These define virtual xattrs exposing the recursive directory 22 * statistics and layout metadata. 23 */ 24 struct ceph_vxattr_cb { 25 bool readonly; 26 char *name; 27 size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val, 28 size_t size); 29 }; 30 31 /* directories */ 32 33 static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val, 34 size_t size) 35 { 36 return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs); 37 } 38 39 static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val, 40 size_t size) 41 { 42 return snprintf(val, size, "%lld", ci->i_files); 43 } 44 45 static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val, 46 size_t size) 47 { 48 return snprintf(val, size, "%lld", ci->i_subdirs); 49 } 50 51 static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val, 52 size_t size) 53 { 54 return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs); 55 } 56 57 static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val, 58 size_t size) 59 { 60 return snprintf(val, size, "%lld", ci->i_rfiles); 61 } 62 63 static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val, 64 size_t size) 65 { 66 return snprintf(val, size, "%lld", ci->i_rsubdirs); 67 } 68 69 static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val, 70 size_t size) 71 { 72 return snprintf(val, size, "%lld", ci->i_rbytes); 73 } 74 75 static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val, 76 size_t size) 77 { 78 return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec, 79 (long)ci->i_rctime.tv_nsec); 80 } 81 82 static struct ceph_vxattr_cb ceph_dir_vxattrs[] = { 83 { true, "ceph.dir.entries", ceph_vxattrcb_entries}, 84 { true, "ceph.dir.files", ceph_vxattrcb_files}, 85 { true, "ceph.dir.subdirs", ceph_vxattrcb_subdirs}, 86 { true, "ceph.dir.rentries", ceph_vxattrcb_rentries}, 87 { true, "ceph.dir.rfiles", ceph_vxattrcb_rfiles}, 88 { true, "ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs}, 89 { true, "ceph.dir.rbytes", ceph_vxattrcb_rbytes}, 90 { true, "ceph.dir.rctime", ceph_vxattrcb_rctime}, 91 { true, NULL, NULL } 92 }; 93 94 /* files */ 95 96 static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, 97 size_t size) 98 { 99 int ret; 100 101 ret = snprintf(val, size, 102 "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n", 103 (unsigned long long)ceph_file_layout_su(ci->i_layout), 104 (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), 105 (unsigned long long)ceph_file_layout_object_size(ci->i_layout)); 106 if (ceph_file_layout_pg_preferred(ci->i_layout)) 107 ret += snprintf(val + ret, size, "preferred_osd=%lld\n", 108 (unsigned long long)ceph_file_layout_pg_preferred( 109 ci->i_layout)); 110 return ret; 111 } 112 113 static struct ceph_vxattr_cb ceph_file_vxattrs[] = { 114 { true, "ceph.layout", ceph_vxattrcb_layout}, 115 { NULL, NULL } 116 }; 117 118 static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode) 119 { 120 if (S_ISDIR(inode->i_mode)) 121 return ceph_dir_vxattrs; 122 else if (S_ISREG(inode->i_mode)) 123 return ceph_file_vxattrs; 124 return NULL; 125 } 126 127 static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr, 128 const char *name) 129 { 130 do { 131 if (strcmp(vxattr->name, name) == 0) 132 return vxattr; 133 vxattr++; 134 } while (vxattr->name); 135 return NULL; 136 } 137 138 static int __set_xattr(struct ceph_inode_info *ci, 139 const char *name, int name_len, 140 const char *val, int val_len, 141 int dirty, 142 int should_free_name, int should_free_val, 143 struct ceph_inode_xattr **newxattr) 144 { 145 struct rb_node **p; 146 struct rb_node *parent = NULL; 147 struct ceph_inode_xattr *xattr = NULL; 148 int c; 149 int new = 0; 150 151 p = &ci->i_xattrs.index.rb_node; 152 while (*p) { 153 parent = *p; 154 xattr = rb_entry(parent, struct ceph_inode_xattr, node); 155 c = strncmp(name, xattr->name, min(name_len, xattr->name_len)); 156 if (c < 0) 157 p = &(*p)->rb_left; 158 else if (c > 0) 159 p = &(*p)->rb_right; 160 else { 161 if (name_len == xattr->name_len) 162 break; 163 else if (name_len < xattr->name_len) 164 p = &(*p)->rb_left; 165 else 166 p = &(*p)->rb_right; 167 } 168 xattr = NULL; 169 } 170 171 if (!xattr) { 172 new = 1; 173 xattr = *newxattr; 174 xattr->name = name; 175 xattr->name_len = name_len; 176 xattr->should_free_name = should_free_name; 177 178 ci->i_xattrs.count++; 179 dout("__set_xattr count=%d\n", ci->i_xattrs.count); 180 } else { 181 kfree(*newxattr); 182 *newxattr = NULL; 183 if (xattr->should_free_val) 184 kfree((void *)xattr->val); 185 186 if (should_free_name) { 187 kfree((void *)name); 188 name = xattr->name; 189 } 190 ci->i_xattrs.names_size -= xattr->name_len; 191 ci->i_xattrs.vals_size -= xattr->val_len; 192 } 193 ci->i_xattrs.names_size += name_len; 194 ci->i_xattrs.vals_size += val_len; 195 if (val) 196 xattr->val = val; 197 else 198 xattr->val = ""; 199 200 xattr->val_len = val_len; 201 xattr->dirty = dirty; 202 xattr->should_free_val = (val && should_free_val); 203 204 if (new) { 205 rb_link_node(&xattr->node, parent, p); 206 rb_insert_color(&xattr->node, &ci->i_xattrs.index); 207 dout("__set_xattr_val p=%p\n", p); 208 } 209 210 dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n", 211 ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val); 212 213 return 0; 214 } 215 216 static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci, 217 const char *name) 218 { 219 struct rb_node **p; 220 struct rb_node *parent = NULL; 221 struct ceph_inode_xattr *xattr = NULL; 222 int c; 223 224 p = &ci->i_xattrs.index.rb_node; 225 while (*p) { 226 parent = *p; 227 xattr = rb_entry(parent, struct ceph_inode_xattr, node); 228 c = strncmp(name, xattr->name, xattr->name_len); 229 if (c < 0) 230 p = &(*p)->rb_left; 231 else if (c > 0) 232 p = &(*p)->rb_right; 233 else { 234 dout("__get_xattr %s: found %.*s\n", name, 235 xattr->val_len, xattr->val); 236 return xattr; 237 } 238 } 239 240 dout("__get_xattr %s: not found\n", name); 241 242 return NULL; 243 } 244 245 static void __free_xattr(struct ceph_inode_xattr *xattr) 246 { 247 BUG_ON(!xattr); 248 249 if (xattr->should_free_name) 250 kfree((void *)xattr->name); 251 if (xattr->should_free_val) 252 kfree((void *)xattr->val); 253 254 kfree(xattr); 255 } 256 257 static int __remove_xattr(struct ceph_inode_info *ci, 258 struct ceph_inode_xattr *xattr) 259 { 260 if (!xattr) 261 return -EOPNOTSUPP; 262 263 rb_erase(&xattr->node, &ci->i_xattrs.index); 264 265 if (xattr->should_free_name) 266 kfree((void *)xattr->name); 267 if (xattr->should_free_val) 268 kfree((void *)xattr->val); 269 270 ci->i_xattrs.names_size -= xattr->name_len; 271 ci->i_xattrs.vals_size -= xattr->val_len; 272 ci->i_xattrs.count--; 273 kfree(xattr); 274 275 return 0; 276 } 277 278 static int __remove_xattr_by_name(struct ceph_inode_info *ci, 279 const char *name) 280 { 281 struct rb_node **p; 282 struct ceph_inode_xattr *xattr; 283 int err; 284 285 p = &ci->i_xattrs.index.rb_node; 286 xattr = __get_xattr(ci, name); 287 err = __remove_xattr(ci, xattr); 288 return err; 289 } 290 291 static char *__copy_xattr_names(struct ceph_inode_info *ci, 292 char *dest) 293 { 294 struct rb_node *p; 295 struct ceph_inode_xattr *xattr = NULL; 296 297 p = rb_first(&ci->i_xattrs.index); 298 dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count); 299 300 while (p) { 301 xattr = rb_entry(p, struct ceph_inode_xattr, node); 302 memcpy(dest, xattr->name, xattr->name_len); 303 dest[xattr->name_len] = '\0'; 304 305 dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name, 306 xattr->name_len, ci->i_xattrs.names_size); 307 308 dest += xattr->name_len + 1; 309 p = rb_next(p); 310 } 311 312 return dest; 313 } 314 315 void __ceph_destroy_xattrs(struct ceph_inode_info *ci) 316 { 317 struct rb_node *p, *tmp; 318 struct ceph_inode_xattr *xattr = NULL; 319 320 p = rb_first(&ci->i_xattrs.index); 321 322 dout("__ceph_destroy_xattrs p=%p\n", p); 323 324 while (p) { 325 xattr = rb_entry(p, struct ceph_inode_xattr, node); 326 tmp = p; 327 p = rb_next(tmp); 328 dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p, 329 xattr->name_len, xattr->name); 330 rb_erase(tmp, &ci->i_xattrs.index); 331 332 __free_xattr(xattr); 333 } 334 335 ci->i_xattrs.names_size = 0; 336 ci->i_xattrs.vals_size = 0; 337 ci->i_xattrs.index_version = 0; 338 ci->i_xattrs.count = 0; 339 ci->i_xattrs.index = RB_ROOT; 340 } 341 342 static int __build_xattrs(struct inode *inode) 343 __releases(inode->i_lock) 344 __acquires(inode->i_lock) 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 ci->i_xattrs.version++; 492 } 493 } 494 495 ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, 496 size_t size) 497 { 498 struct inode *inode = dentry->d_inode; 499 struct ceph_inode_info *ci = ceph_inode(inode); 500 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 501 int err; 502 struct ceph_inode_xattr *xattr; 503 struct ceph_vxattr_cb *vxattr = NULL; 504 505 if (!ceph_is_valid_xattr(name)) 506 return -ENODATA; 507 508 /* let's see if a virtual xattr was requested */ 509 if (vxattrs) 510 vxattr = ceph_match_vxattr(vxattrs, name); 511 512 spin_lock(&inode->i_lock); 513 dout("getxattr %p ver=%lld index_ver=%lld\n", inode, 514 ci->i_xattrs.version, ci->i_xattrs.index_version); 515 516 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 517 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 518 goto get_xattr; 519 } else { 520 spin_unlock(&inode->i_lock); 521 /* get xattrs from mds (if we don't already have them) */ 522 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 523 if (err) 524 return err; 525 } 526 527 spin_lock(&inode->i_lock); 528 529 if (vxattr && vxattr->readonly) { 530 err = vxattr->getxattr_cb(ci, value, size); 531 goto out; 532 } 533 534 err = __build_xattrs(inode); 535 if (err < 0) 536 goto out; 537 538 get_xattr: 539 err = -ENODATA; /* == ENOATTR */ 540 xattr = __get_xattr(ci, name); 541 if (!xattr) { 542 if (vxattr) 543 err = vxattr->getxattr_cb(ci, value, size); 544 goto out; 545 } 546 547 err = -ERANGE; 548 if (size && size < xattr->val_len) 549 goto out; 550 551 err = xattr->val_len; 552 if (size == 0) 553 goto out; 554 555 memcpy(value, xattr->val, xattr->val_len); 556 557 out: 558 spin_unlock(&inode->i_lock); 559 return err; 560 } 561 562 ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) 563 { 564 struct inode *inode = dentry->d_inode; 565 struct ceph_inode_info *ci = ceph_inode(inode); 566 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 567 u32 vir_namelen = 0; 568 u32 namelen; 569 int err; 570 u32 len; 571 int i; 572 573 spin_lock(&inode->i_lock); 574 dout("listxattr %p ver=%lld index_ver=%lld\n", inode, 575 ci->i_xattrs.version, ci->i_xattrs.index_version); 576 577 if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && 578 (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { 579 goto list_xattr; 580 } else { 581 spin_unlock(&inode->i_lock); 582 err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); 583 if (err) 584 return err; 585 } 586 587 spin_lock(&inode->i_lock); 588 589 err = __build_xattrs(inode); 590 if (err < 0) 591 goto out; 592 593 list_xattr: 594 vir_namelen = 0; 595 /* include virtual dir xattrs */ 596 if (vxattrs) 597 for (i = 0; vxattrs[i].name; i++) 598 vir_namelen += strlen(vxattrs[i].name) + 1; 599 /* adding 1 byte per each variable due to the null termination */ 600 namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; 601 err = -ERANGE; 602 if (size && namelen > size) 603 goto out; 604 605 err = namelen; 606 if (size == 0) 607 goto out; 608 609 names = __copy_xattr_names(ci, names); 610 611 /* virtual xattr names, too */ 612 if (vxattrs) 613 for (i = 0; vxattrs[i].name; i++) { 614 len = sprintf(names, "%s", vxattrs[i].name); 615 names += len + 1; 616 } 617 618 out: 619 spin_unlock(&inode->i_lock); 620 return err; 621 } 622 623 static int ceph_sync_setxattr(struct dentry *dentry, const char *name, 624 const char *value, size_t size, int flags) 625 { 626 struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); 627 struct inode *inode = dentry->d_inode; 628 struct ceph_inode_info *ci = ceph_inode(inode); 629 struct inode *parent_inode = dentry->d_parent->d_inode; 630 struct ceph_mds_request *req; 631 struct ceph_mds_client *mdsc = fsc->mdsc; 632 int err; 633 int i, nr_pages; 634 struct page **pages = NULL; 635 void *kaddr; 636 637 /* copy value into some pages */ 638 nr_pages = calc_pages_for(0, size); 639 if (nr_pages) { 640 pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS); 641 if (!pages) 642 return -ENOMEM; 643 err = -ENOMEM; 644 for (i = 0; i < nr_pages; i++) { 645 pages[i] = __page_cache_alloc(GFP_NOFS); 646 if (!pages[i]) { 647 nr_pages = i; 648 goto out; 649 } 650 kaddr = kmap(pages[i]); 651 memcpy(kaddr, value + i*PAGE_CACHE_SIZE, 652 min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE)); 653 } 654 } 655 656 dout("setxattr value=%.*s\n", (int)size, value); 657 658 /* do request */ 659 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, 660 USE_AUTH_MDS); 661 if (IS_ERR(req)) { 662 err = PTR_ERR(req); 663 goto out; 664 } 665 req->r_inode = igrab(inode); 666 req->r_inode_drop = CEPH_CAP_XATTR_SHARED; 667 req->r_num_caps = 1; 668 req->r_args.setxattr.flags = cpu_to_le32(flags); 669 req->r_path2 = kstrdup(name, GFP_NOFS); 670 671 req->r_pages = pages; 672 req->r_num_pages = nr_pages; 673 req->r_data_len = size; 674 675 dout("xattr.ver (before): %lld\n", ci->i_xattrs.version); 676 err = ceph_mdsc_do_request(mdsc, parent_inode, req); 677 ceph_mdsc_put_request(req); 678 dout("xattr.ver (after): %lld\n", ci->i_xattrs.version); 679 680 out: 681 if (pages) { 682 for (i = 0; i < nr_pages; i++) 683 __free_page(pages[i]); 684 kfree(pages); 685 } 686 return err; 687 } 688 689 int ceph_setxattr(struct dentry *dentry, const char *name, 690 const void *value, size_t size, int flags) 691 { 692 struct inode *inode = dentry->d_inode; 693 struct ceph_inode_info *ci = ceph_inode(inode); 694 struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); 695 int err; 696 int name_len = strlen(name); 697 int val_len = size; 698 char *newname = NULL; 699 char *newval = NULL; 700 struct ceph_inode_xattr *xattr = NULL; 701 int issued; 702 int required_blob_size; 703 704 if (ceph_snap(inode) != CEPH_NOSNAP) 705 return -EROFS; 706 707 if (!ceph_is_valid_xattr(name)) 708 return -EOPNOTSUPP; 709 710 if (vxattrs) { 711 struct ceph_vxattr_cb *vxattr = 712 ceph_match_vxattr(vxattrs, name); 713 if (vxattr && vxattr->readonly) 714 return -EOPNOTSUPP; 715 } 716 717 /* preallocate memory for xattr name, value, index node */ 718 err = -ENOMEM; 719 newname = kmemdup(name, name_len + 1, GFP_NOFS); 720 if (!newname) 721 goto out; 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_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); 783 struct ceph_mds_client *mdsc = fsc->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