1 /* 2 * Copyright (C) 2007 Oracle. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public 14 * License along with this program; if not, write to the 15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 * Boston, MA 021110-1307, USA. 17 */ 18 19 #include <linux/sched.h> 20 #include <linux/slab.h> 21 #include <linux/spinlock.h> 22 #include <linux/completion.h> 23 #include <linux/buffer_head.h> 24 #include <linux/kobject.h> 25 #include <linux/bug.h> 26 #include <linux/genhd.h> 27 #include <linux/debugfs.h> 28 29 #include "ctree.h" 30 #include "disk-io.h" 31 #include "transaction.h" 32 #include "sysfs.h" 33 #include "volumes.h" 34 35 static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj); 36 37 static u64 get_features(struct btrfs_fs_info *fs_info, 38 enum btrfs_feature_set set) 39 { 40 struct btrfs_super_block *disk_super = fs_info->super_copy; 41 if (set == FEAT_COMPAT) 42 return btrfs_super_compat_flags(disk_super); 43 else if (set == FEAT_COMPAT_RO) 44 return btrfs_super_compat_ro_flags(disk_super); 45 else 46 return btrfs_super_incompat_flags(disk_super); 47 } 48 49 static void set_features(struct btrfs_fs_info *fs_info, 50 enum btrfs_feature_set set, u64 features) 51 { 52 struct btrfs_super_block *disk_super = fs_info->super_copy; 53 if (set == FEAT_COMPAT) 54 btrfs_set_super_compat_flags(disk_super, features); 55 else if (set == FEAT_COMPAT_RO) 56 btrfs_set_super_compat_ro_flags(disk_super, features); 57 else 58 btrfs_set_super_incompat_flags(disk_super, features); 59 } 60 61 static int can_modify_feature(struct btrfs_feature_attr *fa) 62 { 63 int val = 0; 64 u64 set, clear; 65 switch (fa->feature_set) { 66 case FEAT_COMPAT: 67 set = BTRFS_FEATURE_COMPAT_SAFE_SET; 68 clear = BTRFS_FEATURE_COMPAT_SAFE_CLEAR; 69 break; 70 case FEAT_COMPAT_RO: 71 set = BTRFS_FEATURE_COMPAT_RO_SAFE_SET; 72 clear = BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR; 73 break; 74 case FEAT_INCOMPAT: 75 set = BTRFS_FEATURE_INCOMPAT_SAFE_SET; 76 clear = BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR; 77 break; 78 default: 79 printk(KERN_WARNING "btrfs: sysfs: unknown feature set %d\n", 80 fa->feature_set); 81 return 0; 82 } 83 84 if (set & fa->feature_bit) 85 val |= 1; 86 if (clear & fa->feature_bit) 87 val |= 2; 88 89 return val; 90 } 91 92 static ssize_t btrfs_feature_attr_show(struct kobject *kobj, 93 struct kobj_attribute *a, char *buf) 94 { 95 int val = 0; 96 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 97 struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a); 98 if (fs_info) { 99 u64 features = get_features(fs_info, fa->feature_set); 100 if (features & fa->feature_bit) 101 val = 1; 102 } else 103 val = can_modify_feature(fa); 104 105 return snprintf(buf, PAGE_SIZE, "%d\n", val); 106 } 107 108 static ssize_t btrfs_feature_attr_store(struct kobject *kobj, 109 struct kobj_attribute *a, 110 const char *buf, size_t count) 111 { 112 struct btrfs_fs_info *fs_info; 113 struct btrfs_feature_attr *fa = to_btrfs_feature_attr(a); 114 struct btrfs_trans_handle *trans; 115 u64 features, set, clear; 116 unsigned long val; 117 int ret; 118 119 fs_info = to_fs_info(kobj); 120 if (!fs_info) 121 return -EPERM; 122 123 ret = kstrtoul(skip_spaces(buf), 0, &val); 124 if (ret) 125 return ret; 126 127 if (fa->feature_set == FEAT_COMPAT) { 128 set = BTRFS_FEATURE_COMPAT_SAFE_SET; 129 clear = BTRFS_FEATURE_COMPAT_SAFE_CLEAR; 130 } else if (fa->feature_set == FEAT_COMPAT_RO) { 131 set = BTRFS_FEATURE_COMPAT_RO_SAFE_SET; 132 clear = BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR; 133 } else { 134 set = BTRFS_FEATURE_INCOMPAT_SAFE_SET; 135 clear = BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR; 136 } 137 138 features = get_features(fs_info, fa->feature_set); 139 140 /* Nothing to do */ 141 if ((val && (features & fa->feature_bit)) || 142 (!val && !(features & fa->feature_bit))) 143 return count; 144 145 if ((val && !(set & fa->feature_bit)) || 146 (!val && !(clear & fa->feature_bit))) { 147 btrfs_info(fs_info, 148 "%sabling feature %s on mounted fs is not supported.", 149 val ? "En" : "Dis", fa->kobj_attr.attr.name); 150 return -EPERM; 151 } 152 153 btrfs_info(fs_info, "%s %s feature flag", 154 val ? "Setting" : "Clearing", fa->kobj_attr.attr.name); 155 156 trans = btrfs_start_transaction(fs_info->fs_root, 0); 157 if (IS_ERR(trans)) 158 return PTR_ERR(trans); 159 160 spin_lock(&fs_info->super_lock); 161 features = get_features(fs_info, fa->feature_set); 162 if (val) 163 features |= fa->feature_bit; 164 else 165 features &= ~fa->feature_bit; 166 set_features(fs_info, fa->feature_set, features); 167 spin_unlock(&fs_info->super_lock); 168 169 ret = btrfs_commit_transaction(trans, fs_info->fs_root); 170 if (ret) 171 return ret; 172 173 return count; 174 } 175 176 static umode_t btrfs_feature_visible(struct kobject *kobj, 177 struct attribute *attr, int unused) 178 { 179 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 180 umode_t mode = attr->mode; 181 182 if (fs_info) { 183 struct btrfs_feature_attr *fa; 184 u64 features; 185 186 fa = attr_to_btrfs_feature_attr(attr); 187 features = get_features(fs_info, fa->feature_set); 188 189 if (can_modify_feature(fa)) 190 mode |= S_IWUSR; 191 else if (!(features & fa->feature_bit)) 192 mode = 0; 193 } 194 195 return mode; 196 } 197 198 BTRFS_FEAT_ATTR_INCOMPAT(mixed_backref, MIXED_BACKREF); 199 BTRFS_FEAT_ATTR_INCOMPAT(default_subvol, DEFAULT_SUBVOL); 200 BTRFS_FEAT_ATTR_INCOMPAT(mixed_groups, MIXED_GROUPS); 201 BTRFS_FEAT_ATTR_INCOMPAT(compress_lzo, COMPRESS_LZO); 202 BTRFS_FEAT_ATTR_INCOMPAT(big_metadata, BIG_METADATA); 203 BTRFS_FEAT_ATTR_INCOMPAT(extended_iref, EXTENDED_IREF); 204 BTRFS_FEAT_ATTR_INCOMPAT(raid56, RAID56); 205 BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA); 206 BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES); 207 208 static struct attribute *btrfs_supported_feature_attrs[] = { 209 BTRFS_FEAT_ATTR_PTR(mixed_backref), 210 BTRFS_FEAT_ATTR_PTR(default_subvol), 211 BTRFS_FEAT_ATTR_PTR(mixed_groups), 212 BTRFS_FEAT_ATTR_PTR(compress_lzo), 213 BTRFS_FEAT_ATTR_PTR(big_metadata), 214 BTRFS_FEAT_ATTR_PTR(extended_iref), 215 BTRFS_FEAT_ATTR_PTR(raid56), 216 BTRFS_FEAT_ATTR_PTR(skinny_metadata), 217 BTRFS_FEAT_ATTR_PTR(no_holes), 218 NULL 219 }; 220 221 static const struct attribute_group btrfs_feature_attr_group = { 222 .name = "features", 223 .is_visible = btrfs_feature_visible, 224 .attrs = btrfs_supported_feature_attrs, 225 }; 226 227 static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf) 228 { 229 u64 val; 230 if (lock) 231 spin_lock(lock); 232 val = *value_ptr; 233 if (lock) 234 spin_unlock(lock); 235 return snprintf(buf, PAGE_SIZE, "%llu\n", val); 236 } 237 238 static ssize_t global_rsv_size_show(struct kobject *kobj, 239 struct kobj_attribute *ka, char *buf) 240 { 241 struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent); 242 struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; 243 return btrfs_show_u64(&block_rsv->size, &block_rsv->lock, buf); 244 } 245 BTRFS_ATTR(global_rsv_size, global_rsv_size_show); 246 247 static ssize_t global_rsv_reserved_show(struct kobject *kobj, 248 struct kobj_attribute *a, char *buf) 249 { 250 struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent); 251 struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; 252 return btrfs_show_u64(&block_rsv->reserved, &block_rsv->lock, buf); 253 } 254 BTRFS_ATTR(global_rsv_reserved, global_rsv_reserved_show); 255 256 #define to_space_info(_kobj) container_of(_kobj, struct btrfs_space_info, kobj) 257 #define to_raid_kobj(_kobj) container_of(_kobj, struct raid_kobject, kobj) 258 259 static ssize_t raid_bytes_show(struct kobject *kobj, 260 struct kobj_attribute *attr, char *buf); 261 BTRFS_RAID_ATTR(total_bytes, raid_bytes_show); 262 BTRFS_RAID_ATTR(used_bytes, raid_bytes_show); 263 264 static ssize_t raid_bytes_show(struct kobject *kobj, 265 struct kobj_attribute *attr, char *buf) 266 267 { 268 struct btrfs_space_info *sinfo = to_space_info(kobj->parent); 269 struct btrfs_block_group_cache *block_group; 270 int index = to_raid_kobj(kobj)->raid_type; 271 u64 val = 0; 272 273 down_read(&sinfo->groups_sem); 274 list_for_each_entry(block_group, &sinfo->block_groups[index], list) { 275 if (&attr->attr == BTRFS_RAID_ATTR_PTR(total_bytes)) 276 val += block_group->key.offset; 277 else 278 val += btrfs_block_group_used(&block_group->item); 279 } 280 up_read(&sinfo->groups_sem); 281 return snprintf(buf, PAGE_SIZE, "%llu\n", val); 282 } 283 284 static struct attribute *raid_attributes[] = { 285 BTRFS_RAID_ATTR_PTR(total_bytes), 286 BTRFS_RAID_ATTR_PTR(used_bytes), 287 NULL 288 }; 289 290 static void release_raid_kobj(struct kobject *kobj) 291 { 292 kfree(to_raid_kobj(kobj)); 293 } 294 295 struct kobj_type btrfs_raid_ktype = { 296 .sysfs_ops = &kobj_sysfs_ops, 297 .release = release_raid_kobj, 298 .default_attrs = raid_attributes, 299 }; 300 301 #define SPACE_INFO_ATTR(field) \ 302 static ssize_t btrfs_space_info_show_##field(struct kobject *kobj, \ 303 struct kobj_attribute *a, \ 304 char *buf) \ 305 { \ 306 struct btrfs_space_info *sinfo = to_space_info(kobj); \ 307 return btrfs_show_u64(&sinfo->field, &sinfo->lock, buf); \ 308 } \ 309 BTRFS_ATTR(field, btrfs_space_info_show_##field) 310 311 static ssize_t btrfs_space_info_show_total_bytes_pinned(struct kobject *kobj, 312 struct kobj_attribute *a, 313 char *buf) 314 { 315 struct btrfs_space_info *sinfo = to_space_info(kobj); 316 s64 val = percpu_counter_sum(&sinfo->total_bytes_pinned); 317 return snprintf(buf, PAGE_SIZE, "%lld\n", val); 318 } 319 320 SPACE_INFO_ATTR(flags); 321 SPACE_INFO_ATTR(total_bytes); 322 SPACE_INFO_ATTR(bytes_used); 323 SPACE_INFO_ATTR(bytes_pinned); 324 SPACE_INFO_ATTR(bytes_reserved); 325 SPACE_INFO_ATTR(bytes_may_use); 326 SPACE_INFO_ATTR(disk_used); 327 SPACE_INFO_ATTR(disk_total); 328 BTRFS_ATTR(total_bytes_pinned, btrfs_space_info_show_total_bytes_pinned); 329 330 static struct attribute *space_info_attrs[] = { 331 BTRFS_ATTR_PTR(flags), 332 BTRFS_ATTR_PTR(total_bytes), 333 BTRFS_ATTR_PTR(bytes_used), 334 BTRFS_ATTR_PTR(bytes_pinned), 335 BTRFS_ATTR_PTR(bytes_reserved), 336 BTRFS_ATTR_PTR(bytes_may_use), 337 BTRFS_ATTR_PTR(disk_used), 338 BTRFS_ATTR_PTR(disk_total), 339 BTRFS_ATTR_PTR(total_bytes_pinned), 340 NULL, 341 }; 342 343 static void space_info_release(struct kobject *kobj) 344 { 345 struct btrfs_space_info *sinfo = to_space_info(kobj); 346 percpu_counter_destroy(&sinfo->total_bytes_pinned); 347 kfree(sinfo); 348 } 349 350 struct kobj_type space_info_ktype = { 351 .sysfs_ops = &kobj_sysfs_ops, 352 .release = space_info_release, 353 .default_attrs = space_info_attrs, 354 }; 355 356 static const struct attribute *allocation_attrs[] = { 357 BTRFS_ATTR_PTR(global_rsv_reserved), 358 BTRFS_ATTR_PTR(global_rsv_size), 359 NULL, 360 }; 361 362 static ssize_t btrfs_label_show(struct kobject *kobj, 363 struct kobj_attribute *a, char *buf) 364 { 365 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 366 char *label = fs_info->super_copy->label; 367 return snprintf(buf, PAGE_SIZE, label[0] ? "%s\n" : "%s", label); 368 } 369 370 static ssize_t btrfs_label_store(struct kobject *kobj, 371 struct kobj_attribute *a, 372 const char *buf, size_t len) 373 { 374 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 375 struct btrfs_trans_handle *trans; 376 struct btrfs_root *root = fs_info->fs_root; 377 int ret; 378 size_t p_len; 379 380 if (fs_info->sb->s_flags & MS_RDONLY) 381 return -EROFS; 382 383 /* 384 * p_len is the len until the first occurrence of either 385 * '\n' or '\0' 386 */ 387 p_len = strcspn(buf, "\n"); 388 389 if (p_len >= BTRFS_LABEL_SIZE) 390 return -EINVAL; 391 392 trans = btrfs_start_transaction(root, 0); 393 if (IS_ERR(trans)) 394 return PTR_ERR(trans); 395 396 spin_lock(&root->fs_info->super_lock); 397 memset(fs_info->super_copy->label, 0, BTRFS_LABEL_SIZE); 398 memcpy(fs_info->super_copy->label, buf, p_len); 399 spin_unlock(&root->fs_info->super_lock); 400 ret = btrfs_commit_transaction(trans, root); 401 402 if (!ret) 403 return len; 404 405 return ret; 406 } 407 BTRFS_ATTR_RW(label, btrfs_label_show, btrfs_label_store); 408 409 static ssize_t btrfs_nodesize_show(struct kobject *kobj, 410 struct kobj_attribute *a, char *buf) 411 { 412 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 413 414 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->nodesize); 415 } 416 417 BTRFS_ATTR(nodesize, btrfs_nodesize_show); 418 419 static ssize_t btrfs_sectorsize_show(struct kobject *kobj, 420 struct kobj_attribute *a, char *buf) 421 { 422 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 423 424 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->sectorsize); 425 } 426 427 BTRFS_ATTR(sectorsize, btrfs_sectorsize_show); 428 429 static ssize_t btrfs_clone_alignment_show(struct kobject *kobj, 430 struct kobj_attribute *a, char *buf) 431 { 432 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 433 434 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->sectorsize); 435 } 436 437 BTRFS_ATTR(clone_alignment, btrfs_clone_alignment_show); 438 439 static struct attribute *btrfs_attrs[] = { 440 BTRFS_ATTR_PTR(label), 441 BTRFS_ATTR_PTR(nodesize), 442 BTRFS_ATTR_PTR(sectorsize), 443 BTRFS_ATTR_PTR(clone_alignment), 444 NULL, 445 }; 446 447 static void btrfs_release_super_kobj(struct kobject *kobj) 448 { 449 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 450 complete(&fs_info->kobj_unregister); 451 } 452 453 static struct kobj_type btrfs_ktype = { 454 .sysfs_ops = &kobj_sysfs_ops, 455 .release = btrfs_release_super_kobj, 456 .default_attrs = btrfs_attrs, 457 }; 458 459 static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj) 460 { 461 if (kobj->ktype != &btrfs_ktype) 462 return NULL; 463 return container_of(kobj, struct btrfs_fs_info, super_kobj); 464 } 465 466 #define NUM_FEATURE_BITS 64 467 static char btrfs_unknown_feature_names[3][NUM_FEATURE_BITS][13]; 468 static struct btrfs_feature_attr btrfs_feature_attrs[3][NUM_FEATURE_BITS]; 469 470 static u64 supported_feature_masks[3] = { 471 [FEAT_COMPAT] = BTRFS_FEATURE_COMPAT_SUPP, 472 [FEAT_COMPAT_RO] = BTRFS_FEATURE_COMPAT_RO_SUPP, 473 [FEAT_INCOMPAT] = BTRFS_FEATURE_INCOMPAT_SUPP, 474 }; 475 476 static int addrm_unknown_feature_attrs(struct btrfs_fs_info *fs_info, bool add) 477 { 478 int set; 479 480 for (set = 0; set < FEAT_MAX; set++) { 481 int i; 482 struct attribute *attrs[2]; 483 struct attribute_group agroup = { 484 .name = "features", 485 .attrs = attrs, 486 }; 487 u64 features = get_features(fs_info, set); 488 features &= ~supported_feature_masks[set]; 489 490 if (!features) 491 continue; 492 493 attrs[1] = NULL; 494 for (i = 0; i < NUM_FEATURE_BITS; i++) { 495 struct btrfs_feature_attr *fa; 496 497 if (!(features & (1ULL << i))) 498 continue; 499 500 fa = &btrfs_feature_attrs[set][i]; 501 attrs[0] = &fa->kobj_attr.attr; 502 if (add) { 503 int ret; 504 ret = sysfs_merge_group(&fs_info->super_kobj, 505 &agroup); 506 if (ret) 507 return ret; 508 } else 509 sysfs_unmerge_group(&fs_info->super_kobj, 510 &agroup); 511 } 512 513 } 514 return 0; 515 } 516 517 static void __btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info) 518 { 519 kobject_del(&fs_info->super_kobj); 520 kobject_put(&fs_info->super_kobj); 521 wait_for_completion(&fs_info->kobj_unregister); 522 } 523 524 void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info) 525 { 526 if (fs_info->space_info_kobj) { 527 sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs); 528 kobject_del(fs_info->space_info_kobj); 529 kobject_put(fs_info->space_info_kobj); 530 } 531 kobject_del(fs_info->device_dir_kobj); 532 kobject_put(fs_info->device_dir_kobj); 533 addrm_unknown_feature_attrs(fs_info, false); 534 sysfs_remove_group(&fs_info->super_kobj, &btrfs_feature_attr_group); 535 __btrfs_sysfs_remove_one(fs_info); 536 } 537 538 const char * const btrfs_feature_set_names[3] = { 539 [FEAT_COMPAT] = "compat", 540 [FEAT_COMPAT_RO] = "compat_ro", 541 [FEAT_INCOMPAT] = "incompat", 542 }; 543 544 char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags) 545 { 546 size_t bufsize = 4096; /* safe max, 64 names * 64 bytes */ 547 int len = 0; 548 int i; 549 char *str; 550 551 str = kmalloc(bufsize, GFP_KERNEL); 552 if (!str) 553 return str; 554 555 for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) { 556 const char *name; 557 558 if (!(flags & (1ULL << i))) 559 continue; 560 561 name = btrfs_feature_attrs[set][i].kobj_attr.attr.name; 562 len += snprintf(str + len, bufsize - len, "%s%s", 563 len ? "," : "", name); 564 } 565 566 return str; 567 } 568 569 static void init_feature_attrs(void) 570 { 571 struct btrfs_feature_attr *fa; 572 int set, i; 573 574 BUILD_BUG_ON(ARRAY_SIZE(btrfs_unknown_feature_names) != 575 ARRAY_SIZE(btrfs_feature_attrs)); 576 BUILD_BUG_ON(ARRAY_SIZE(btrfs_unknown_feature_names[0]) != 577 ARRAY_SIZE(btrfs_feature_attrs[0])); 578 579 memset(btrfs_feature_attrs, 0, sizeof(btrfs_feature_attrs)); 580 memset(btrfs_unknown_feature_names, 0, 581 sizeof(btrfs_unknown_feature_names)); 582 583 for (i = 0; btrfs_supported_feature_attrs[i]; i++) { 584 struct btrfs_feature_attr *sfa; 585 struct attribute *a = btrfs_supported_feature_attrs[i]; 586 int bit; 587 sfa = attr_to_btrfs_feature_attr(a); 588 bit = ilog2(sfa->feature_bit); 589 fa = &btrfs_feature_attrs[sfa->feature_set][bit]; 590 591 fa->kobj_attr.attr.name = sfa->kobj_attr.attr.name; 592 } 593 594 for (set = 0; set < FEAT_MAX; set++) { 595 for (i = 0; i < ARRAY_SIZE(btrfs_feature_attrs[set]); i++) { 596 char *name = btrfs_unknown_feature_names[set][i]; 597 fa = &btrfs_feature_attrs[set][i]; 598 599 if (fa->kobj_attr.attr.name) 600 continue; 601 602 snprintf(name, 13, "%s:%u", 603 btrfs_feature_set_names[set], i); 604 605 fa->kobj_attr.attr.name = name; 606 fa->kobj_attr.attr.mode = S_IRUGO; 607 fa->feature_set = set; 608 fa->feature_bit = 1ULL << i; 609 } 610 } 611 } 612 613 int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info, 614 struct btrfs_device *one_device) 615 { 616 struct hd_struct *disk; 617 struct kobject *disk_kobj; 618 619 if (!fs_info->device_dir_kobj) 620 return -EINVAL; 621 622 if (one_device && one_device->bdev) { 623 disk = one_device->bdev->bd_part; 624 disk_kobj = &part_to_dev(disk)->kobj; 625 626 sysfs_remove_link(fs_info->device_dir_kobj, 627 disk_kobj->name); 628 } 629 630 return 0; 631 } 632 633 int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info, 634 struct btrfs_device *one_device) 635 { 636 int error = 0; 637 struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; 638 struct btrfs_device *dev; 639 640 if (!fs_info->device_dir_kobj) 641 fs_info->device_dir_kobj = kobject_create_and_add("devices", 642 &fs_info->super_kobj); 643 644 if (!fs_info->device_dir_kobj) 645 return -ENOMEM; 646 647 list_for_each_entry(dev, &fs_devices->devices, dev_list) { 648 struct hd_struct *disk; 649 struct kobject *disk_kobj; 650 651 if (!dev->bdev) 652 continue; 653 654 if (one_device && one_device != dev) 655 continue; 656 657 disk = dev->bdev->bd_part; 658 disk_kobj = &part_to_dev(disk)->kobj; 659 660 error = sysfs_create_link(fs_info->device_dir_kobj, 661 disk_kobj, disk_kobj->name); 662 if (error) 663 break; 664 } 665 666 return error; 667 } 668 669 /* /sys/fs/btrfs/ entry */ 670 static struct kset *btrfs_kset; 671 672 /* /sys/kernel/debug/btrfs */ 673 static struct dentry *btrfs_debugfs_root_dentry; 674 675 /* Debugging tunables and exported data */ 676 u64 btrfs_debugfs_test; 677 678 int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info) 679 { 680 int error; 681 682 init_completion(&fs_info->kobj_unregister); 683 fs_info->super_kobj.kset = btrfs_kset; 684 error = kobject_init_and_add(&fs_info->super_kobj, &btrfs_ktype, NULL, 685 "%pU", fs_info->fsid); 686 if (error) 687 return error; 688 689 error = sysfs_create_group(&fs_info->super_kobj, 690 &btrfs_feature_attr_group); 691 if (error) { 692 __btrfs_sysfs_remove_one(fs_info); 693 return error; 694 } 695 696 error = addrm_unknown_feature_attrs(fs_info, true); 697 if (error) 698 goto failure; 699 700 error = btrfs_kobj_add_device(fs_info, NULL); 701 if (error) 702 goto failure; 703 704 fs_info->space_info_kobj = kobject_create_and_add("allocation", 705 &fs_info->super_kobj); 706 if (!fs_info->space_info_kobj) { 707 error = -ENOMEM; 708 goto failure; 709 } 710 711 error = sysfs_create_files(fs_info->space_info_kobj, allocation_attrs); 712 if (error) 713 goto failure; 714 715 return 0; 716 failure: 717 btrfs_sysfs_remove_one(fs_info); 718 return error; 719 } 720 721 static int btrfs_init_debugfs(void) 722 { 723 #ifdef CONFIG_DEBUG_FS 724 btrfs_debugfs_root_dentry = debugfs_create_dir("btrfs", NULL); 725 if (!btrfs_debugfs_root_dentry) 726 return -ENOMEM; 727 728 debugfs_create_u64("test", S_IRUGO | S_IWUGO, btrfs_debugfs_root_dentry, 729 &btrfs_debugfs_test); 730 #endif 731 return 0; 732 } 733 734 int btrfs_init_sysfs(void) 735 { 736 int ret; 737 738 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj); 739 if (!btrfs_kset) 740 return -ENOMEM; 741 742 ret = btrfs_init_debugfs(); 743 if (ret) 744 return ret; 745 746 init_feature_attrs(); 747 ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_feature_attr_group); 748 749 return ret; 750 } 751 752 void btrfs_exit_sysfs(void) 753 { 754 sysfs_remove_group(&btrfs_kset->kobj, &btrfs_feature_attr_group); 755 kset_unregister(btrfs_kset); 756 debugfs_remove_recursive(btrfs_debugfs_root_dentry); 757 } 758 759