diff options
author | Wang Shilong <wangsl-fnst@cn.fujitsu.com> | 2013-04-07 06:24:57 -0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-05-06 15:54:37 -0400 |
commit | 7708f029dca5f1b9e9d6ea01ab10cd83e4c74ff2 (patch) | |
tree | bcaa238c4e7f5ccb19382fb1035aba79a69b6a4f /fs/btrfs/qgroup.c | |
parent | d4e3991b9945906528c7abb627d759ea43f53bce (diff) |
Btrfs: creating the subvolume qgroup automatically when enabling quota
Creating the subvolume/snapshots(including root subvolume) qgroup
auotomatically when enabling quota.
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Reviewed-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/qgroup.c')
-rw-r--r-- | fs/btrfs/qgroup.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 33b0bea50b45..5be5a39dedc4 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -781,11 +781,15 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, | |||
781 | struct btrfs_fs_info *fs_info) | 781 | struct btrfs_fs_info *fs_info) |
782 | { | 782 | { |
783 | struct btrfs_root *quota_root; | 783 | struct btrfs_root *quota_root; |
784 | struct btrfs_root *tree_root = fs_info->tree_root; | ||
784 | struct btrfs_path *path = NULL; | 785 | struct btrfs_path *path = NULL; |
785 | struct btrfs_qgroup_status_item *ptr; | 786 | struct btrfs_qgroup_status_item *ptr; |
786 | struct extent_buffer *leaf; | 787 | struct extent_buffer *leaf; |
787 | struct btrfs_key key; | 788 | struct btrfs_key key; |
789 | struct btrfs_key found_key; | ||
790 | struct btrfs_qgroup *qgroup = NULL; | ||
788 | int ret = 0; | 791 | int ret = 0; |
792 | int slot; | ||
789 | 793 | ||
790 | spin_lock(&fs_info->qgroup_lock); | 794 | spin_lock(&fs_info->qgroup_lock); |
791 | if (fs_info->quota_root) { | 795 | if (fs_info->quota_root) { |
@@ -832,7 +836,58 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, | |||
832 | 836 | ||
833 | btrfs_mark_buffer_dirty(leaf); | 837 | btrfs_mark_buffer_dirty(leaf); |
834 | 838 | ||
839 | key.objectid = 0; | ||
840 | key.type = BTRFS_ROOT_REF_KEY; | ||
841 | key.offset = 0; | ||
842 | |||
843 | btrfs_release_path(path); | ||
844 | ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0); | ||
845 | if (ret > 0) | ||
846 | goto out_add_root; | ||
847 | if (ret < 0) | ||
848 | goto out_free_path; | ||
849 | |||
850 | |||
851 | while (1) { | ||
852 | slot = path->slots[0]; | ||
853 | leaf = path->nodes[0]; | ||
854 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | ||
855 | |||
856 | if (found_key.type == BTRFS_ROOT_REF_KEY) { | ||
857 | ret = add_qgroup_item(trans, quota_root, | ||
858 | found_key.offset); | ||
859 | if (ret) | ||
860 | goto out_free_path; | ||
861 | |||
862 | spin_lock(&fs_info->qgroup_lock); | ||
863 | qgroup = add_qgroup_rb(fs_info, found_key.offset); | ||
864 | if (IS_ERR(qgroup)) { | ||
865 | spin_unlock(&fs_info->qgroup_lock); | ||
866 | ret = PTR_ERR(qgroup); | ||
867 | goto out_free_path; | ||
868 | } | ||
869 | spin_unlock(&fs_info->qgroup_lock); | ||
870 | } | ||
871 | ret = btrfs_next_item(tree_root, path); | ||
872 | if (ret < 0) | ||
873 | goto out_free_path; | ||
874 | if (ret) | ||
875 | break; | ||
876 | } | ||
877 | |||
878 | out_add_root: | ||
879 | btrfs_release_path(path); | ||
880 | ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID); | ||
881 | if (ret) | ||
882 | goto out_free_path; | ||
883 | |||
835 | spin_lock(&fs_info->qgroup_lock); | 884 | spin_lock(&fs_info->qgroup_lock); |
885 | qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID); | ||
886 | if (IS_ERR(qgroup)) { | ||
887 | spin_unlock(&fs_info->qgroup_lock); | ||
888 | ret = PTR_ERR(qgroup); | ||
889 | goto out_free_path; | ||
890 | } | ||
836 | fs_info->quota_root = quota_root; | 891 | fs_info->quota_root = quota_root; |
837 | fs_info->pending_quota_state = 1; | 892 | fs_info->pending_quota_state = 1; |
838 | spin_unlock(&fs_info->qgroup_lock); | 893 | spin_unlock(&fs_info->qgroup_lock); |