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