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