diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ebe46c62874..8299a25ffc8 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -61,6 +61,8 @@ static void btrfs_put_super(struct super_block *sb) | |||
61 | 61 | ||
62 | ret = close_ctree(root); | 62 | ret = close_ctree(root); |
63 | sb->s_fs_info = NULL; | 63 | sb->s_fs_info = NULL; |
64 | |||
65 | (void)ret; /* FIXME: need to fix VFS to return error? */ | ||
64 | } | 66 | } |
65 | 67 | ||
66 | enum { | 68 | enum { |
@@ -68,7 +70,8 @@ enum { | |||
68 | Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd, | 70 | Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd, |
69 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, | 71 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, |
70 | Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit, | 72 | Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit, |
71 | Opt_discard, Opt_err, | 73 | Opt_discard, Opt_space_cache, Opt_clear_cache, Opt_err, |
74 | Opt_user_subvol_rm_allowed, | ||
72 | }; | 75 | }; |
73 | 76 | ||
74 | static match_table_t tokens = { | 77 | static match_table_t tokens = { |
@@ -92,6 +95,9 @@ static match_table_t tokens = { | |||
92 | {Opt_flushoncommit, "flushoncommit"}, | 95 | {Opt_flushoncommit, "flushoncommit"}, |
93 | {Opt_ratio, "metadata_ratio=%d"}, | 96 | {Opt_ratio, "metadata_ratio=%d"}, |
94 | {Opt_discard, "discard"}, | 97 | {Opt_discard, "discard"}, |
98 | {Opt_space_cache, "space_cache"}, | ||
99 | {Opt_clear_cache, "clear_cache"}, | ||
100 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, | ||
95 | {Opt_err, NULL}, | 101 | {Opt_err, NULL}, |
96 | }; | 102 | }; |
97 | 103 | ||
@@ -235,6 +241,16 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
235 | case Opt_discard: | 241 | case Opt_discard: |
236 | btrfs_set_opt(info->mount_opt, DISCARD); | 242 | btrfs_set_opt(info->mount_opt, DISCARD); |
237 | break; | 243 | break; |
244 | case Opt_space_cache: | ||
245 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); | ||
246 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | ||
247 | case Opt_clear_cache: | ||
248 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); | ||
249 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); | ||
250 | break; | ||
251 | case Opt_user_subvol_rm_allowed: | ||
252 | btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); | ||
253 | break; | ||
238 | case Opt_err: | 254 | case Opt_err: |
239 | printk(KERN_INFO "btrfs: unrecognized mount option " | 255 | printk(KERN_INFO "btrfs: unrecognized mount option " |
240 | "'%s'\n", p); | 256 | "'%s'\n", p); |
@@ -380,7 +396,7 @@ static struct dentry *get_default_root(struct super_block *sb, | |||
380 | find_root: | 396 | find_root: |
381 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | 397 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); |
382 | if (IS_ERR(new_root)) | 398 | if (IS_ERR(new_root)) |
383 | return ERR_PTR(PTR_ERR(new_root)); | 399 | return ERR_CAST(new_root); |
384 | 400 | ||
385 | if (btrfs_root_refs(&new_root->root_item) == 0) | 401 | if (btrfs_root_refs(&new_root->root_item) == 0) |
386 | return ERR_PTR(-ENOENT); | 402 | return ERR_PTR(-ENOENT); |
@@ -436,7 +452,6 @@ static int btrfs_fill_super(struct super_block *sb, | |||
436 | { | 452 | { |
437 | struct inode *inode; | 453 | struct inode *inode; |
438 | struct dentry *root_dentry; | 454 | struct dentry *root_dentry; |
439 | struct btrfs_super_block *disk_super; | ||
440 | struct btrfs_root *tree_root; | 455 | struct btrfs_root *tree_root; |
441 | struct btrfs_key key; | 456 | struct btrfs_key key; |
442 | int err; | 457 | int err; |
@@ -458,7 +473,6 @@ static int btrfs_fill_super(struct super_block *sb, | |||
458 | return PTR_ERR(tree_root); | 473 | return PTR_ERR(tree_root); |
459 | } | 474 | } |
460 | sb->s_fs_info = tree_root; | 475 | sb->s_fs_info = tree_root; |
461 | disk_super = &tree_root->fs_info->super_copy; | ||
462 | 476 | ||
463 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; | 477 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
464 | key.type = BTRFS_INODE_ITEM_KEY; | 478 | key.type = BTRFS_INODE_ITEM_KEY; |
@@ -571,7 +585,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
571 | char *subvol_name = NULL; | 585 | char *subvol_name = NULL; |
572 | u64 subvol_objectid = 0; | 586 | u64 subvol_objectid = 0; |
573 | int error = 0; | 587 | int error = 0; |
574 | int found = 0; | ||
575 | 588 | ||
576 | if (!(flags & MS_RDONLY)) | 589 | if (!(flags & MS_RDONLY)) |
577 | mode |= FMODE_WRITE; | 590 | mode |= FMODE_WRITE; |
@@ -607,7 +620,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
607 | goto error_close_devices; | 620 | goto error_close_devices; |
608 | } | 621 | } |
609 | 622 | ||
610 | found = 1; | ||
611 | btrfs_close_devices(fs_devices); | 623 | btrfs_close_devices(fs_devices); |
612 | } else { | 624 | } else { |
613 | char b[BDEVNAME_SIZE]; | 625 | char b[BDEVNAME_SIZE]; |
@@ -629,7 +641,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
629 | if (IS_ERR(root)) { | 641 | if (IS_ERR(root)) { |
630 | error = PTR_ERR(root); | 642 | error = PTR_ERR(root); |
631 | deactivate_locked_super(s); | 643 | deactivate_locked_super(s); |
632 | goto error; | 644 | goto error_free_subvol_name; |
633 | } | 645 | } |
634 | /* if they gave us a subvolume name bind mount into that */ | 646 | /* if they gave us a subvolume name bind mount into that */ |
635 | if (strcmp(subvol_name, ".")) { | 647 | if (strcmp(subvol_name, ".")) { |
@@ -643,14 +655,14 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
643 | deactivate_locked_super(s); | 655 | deactivate_locked_super(s); |
644 | error = PTR_ERR(new_root); | 656 | error = PTR_ERR(new_root); |
645 | dput(root); | 657 | dput(root); |
646 | goto error_close_devices; | 658 | goto error_free_subvol_name; |
647 | } | 659 | } |
648 | if (!new_root->d_inode) { | 660 | if (!new_root->d_inode) { |
649 | dput(root); | 661 | dput(root); |
650 | dput(new_root); | 662 | dput(new_root); |
651 | deactivate_locked_super(s); | 663 | deactivate_locked_super(s); |
652 | error = -ENXIO; | 664 | error = -ENXIO; |
653 | goto error_close_devices; | 665 | goto error_free_subvol_name; |
654 | } | 666 | } |
655 | dput(root); | 667 | dput(root); |
656 | root = new_root; | 668 | root = new_root; |
@@ -665,7 +677,6 @@ error_close_devices: | |||
665 | btrfs_close_devices(fs_devices); | 677 | btrfs_close_devices(fs_devices); |
666 | error_free_subvol_name: | 678 | error_free_subvol_name: |
667 | kfree(subvol_name); | 679 | kfree(subvol_name); |
668 | error: | ||
669 | return ERR_PTR(error); | 680 | return ERR_PTR(error); |
670 | } | 681 | } |
671 | 682 | ||
@@ -713,18 +724,25 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
713 | struct list_head *head = &root->fs_info->space_info; | 724 | struct list_head *head = &root->fs_info->space_info; |
714 | struct btrfs_space_info *found; | 725 | struct btrfs_space_info *found; |
715 | u64 total_used = 0; | 726 | u64 total_used = 0; |
727 | u64 total_used_data = 0; | ||
716 | int bits = dentry->d_sb->s_blocksize_bits; | 728 | int bits = dentry->d_sb->s_blocksize_bits; |
717 | __be32 *fsid = (__be32 *)root->fs_info->fsid; | 729 | __be32 *fsid = (__be32 *)root->fs_info->fsid; |
718 | 730 | ||
719 | rcu_read_lock(); | 731 | rcu_read_lock(); |
720 | list_for_each_entry_rcu(found, head, list) | 732 | list_for_each_entry_rcu(found, head, list) { |
733 | if (found->flags & (BTRFS_BLOCK_GROUP_METADATA | | ||
734 | BTRFS_BLOCK_GROUP_SYSTEM)) | ||
735 | total_used_data += found->disk_total; | ||
736 | else | ||
737 | total_used_data += found->disk_used; | ||
721 | total_used += found->disk_used; | 738 | total_used += found->disk_used; |
739 | } | ||
722 | rcu_read_unlock(); | 740 | rcu_read_unlock(); |
723 | 741 | ||
724 | buf->f_namelen = BTRFS_NAME_LEN; | 742 | buf->f_namelen = BTRFS_NAME_LEN; |
725 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; | 743 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; |
726 | buf->f_bfree = buf->f_blocks - (total_used >> bits); | 744 | buf->f_bfree = buf->f_blocks - (total_used >> bits); |
727 | buf->f_bavail = buf->f_bfree; | 745 | buf->f_bavail = buf->f_blocks - (total_used_data >> bits); |
728 | buf->f_bsize = dentry->d_sb->s_blocksize; | 746 | buf->f_bsize = dentry->d_sb->s_blocksize; |
729 | buf->f_type = BTRFS_SUPER_MAGIC; | 747 | buf->f_type = BTRFS_SUPER_MAGIC; |
730 | 748 | ||