diff options
author | Arne Jansen <sensille@gmx.net> | 2011-09-13 09:23:30 -0400 |
---|---|---|
committer | Jan Schmidt <list.btrfs@jan-o-sch.net> | 2012-07-12 04:54:38 -0400 |
commit | bcef60f249034f69e89e544461cbfecb68975595 (patch) | |
tree | 5c87fae683428fc6b5576ac807f7f04b0c7268d5 /fs/btrfs/disk-io.c | |
parent | edf39272db4810282360f7362d43ade1d524c913 (diff) |
Btrfs: quota tree support and startup
Init the quota tree along with the others on open_ctree
and close_ctree. Add the quota tree to the list of well
known trees in btrfs_read_fs_root_no_name.
Signed-off-by: Arne Jansen <sensille@gmx.net>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index eca054974425..87d9391c0576 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1472,6 +1472,9 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, | |||
1472 | return fs_info->dev_root; | 1472 | return fs_info->dev_root; |
1473 | if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) | 1473 | if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) |
1474 | return fs_info->csum_root; | 1474 | return fs_info->csum_root; |
1475 | if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID) | ||
1476 | return fs_info->quota_root ? fs_info->quota_root : | ||
1477 | ERR_PTR(-ENOENT); | ||
1475 | again: | 1478 | again: |
1476 | spin_lock(&fs_info->fs_roots_radix_lock); | 1479 | spin_lock(&fs_info->fs_roots_radix_lock); |
1477 | root = radix_tree_lookup(&fs_info->fs_roots_radix, | 1480 | root = radix_tree_lookup(&fs_info->fs_roots_radix, |
@@ -1899,6 +1902,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1899 | free_extent_buffer(info->extent_root->commit_root); | 1902 | free_extent_buffer(info->extent_root->commit_root); |
1900 | free_extent_buffer(info->csum_root->node); | 1903 | free_extent_buffer(info->csum_root->node); |
1901 | free_extent_buffer(info->csum_root->commit_root); | 1904 | free_extent_buffer(info->csum_root->commit_root); |
1905 | if (info->quota_root) { | ||
1906 | free_extent_buffer(info->quota_root->node); | ||
1907 | free_extent_buffer(info->quota_root->commit_root); | ||
1908 | } | ||
1902 | 1909 | ||
1903 | info->tree_root->node = NULL; | 1910 | info->tree_root->node = NULL; |
1904 | info->tree_root->commit_root = NULL; | 1911 | info->tree_root->commit_root = NULL; |
@@ -1908,6 +1915,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1908 | info->extent_root->commit_root = NULL; | 1915 | info->extent_root->commit_root = NULL; |
1909 | info->csum_root->node = NULL; | 1916 | info->csum_root->node = NULL; |
1910 | info->csum_root->commit_root = NULL; | 1917 | info->csum_root->commit_root = NULL; |
1918 | if (info->quota_root) { | ||
1919 | info->quota_root->node = NULL; | ||
1920 | info->quota_root->commit_root = NULL; | ||
1921 | } | ||
1911 | 1922 | ||
1912 | if (chunk_root) { | 1923 | if (chunk_root) { |
1913 | free_extent_buffer(info->chunk_root->node); | 1924 | free_extent_buffer(info->chunk_root->node); |
@@ -1938,6 +1949,7 @@ int open_ctree(struct super_block *sb, | |||
1938 | struct btrfs_root *csum_root; | 1949 | struct btrfs_root *csum_root; |
1939 | struct btrfs_root *chunk_root; | 1950 | struct btrfs_root *chunk_root; |
1940 | struct btrfs_root *dev_root; | 1951 | struct btrfs_root *dev_root; |
1952 | struct btrfs_root *quota_root; | ||
1941 | struct btrfs_root *log_tree_root; | 1953 | struct btrfs_root *log_tree_root; |
1942 | int ret; | 1954 | int ret; |
1943 | int err = -EINVAL; | 1955 | int err = -EINVAL; |
@@ -1949,9 +1961,10 @@ int open_ctree(struct super_block *sb, | |||
1949 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); | 1961 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); |
1950 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); | 1962 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); |
1951 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); | 1963 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); |
1964 | quota_root = fs_info->quota_root = btrfs_alloc_root(fs_info); | ||
1952 | 1965 | ||
1953 | if (!tree_root || !extent_root || !csum_root || | 1966 | if (!tree_root || !extent_root || !csum_root || |
1954 | !chunk_root || !dev_root) { | 1967 | !chunk_root || !dev_root || !quota_root) { |
1955 | err = -ENOMEM; | 1968 | err = -ENOMEM; |
1956 | goto fail; | 1969 | goto fail; |
1957 | } | 1970 | } |
@@ -2441,6 +2454,17 @@ retry_root_backup: | |||
2441 | goto recovery_tree_root; | 2454 | goto recovery_tree_root; |
2442 | csum_root->track_dirty = 1; | 2455 | csum_root->track_dirty = 1; |
2443 | 2456 | ||
2457 | ret = find_and_setup_root(tree_root, fs_info, | ||
2458 | BTRFS_QUOTA_TREE_OBJECTID, quota_root); | ||
2459 | if (ret) { | ||
2460 | kfree(quota_root); | ||
2461 | quota_root = fs_info->quota_root = NULL; | ||
2462 | } else { | ||
2463 | quota_root->track_dirty = 1; | ||
2464 | fs_info->quota_enabled = 1; | ||
2465 | fs_info->pending_quota_state = 1; | ||
2466 | } | ||
2467 | |||
2444 | fs_info->generation = generation; | 2468 | fs_info->generation = generation; |
2445 | fs_info->last_trans_committed = generation; | 2469 | fs_info->last_trans_committed = generation; |
2446 | 2470 | ||
@@ -2500,6 +2524,9 @@ retry_root_backup: | |||
2500 | " integrity check module %s\n", sb->s_id); | 2524 | " integrity check module %s\n", sb->s_id); |
2501 | } | 2525 | } |
2502 | #endif | 2526 | #endif |
2527 | ret = btrfs_read_qgroup_config(fs_info); | ||
2528 | if (ret) | ||
2529 | goto fail_trans_kthread; | ||
2503 | 2530 | ||
2504 | /* do not make disk changes in broken FS */ | 2531 | /* do not make disk changes in broken FS */ |
2505 | if (btrfs_super_log_root(disk_super) != 0 && | 2532 | if (btrfs_super_log_root(disk_super) != 0 && |
@@ -2510,7 +2537,7 @@ retry_root_backup: | |||
2510 | printk(KERN_WARNING "Btrfs log replay required " | 2537 | printk(KERN_WARNING "Btrfs log replay required " |
2511 | "on RO media\n"); | 2538 | "on RO media\n"); |
2512 | err = -EIO; | 2539 | err = -EIO; |
2513 | goto fail_trans_kthread; | 2540 | goto fail_qgroup; |
2514 | } | 2541 | } |
2515 | blocksize = | 2542 | blocksize = |
2516 | btrfs_level_size(tree_root, | 2543 | btrfs_level_size(tree_root, |
@@ -2519,7 +2546,7 @@ retry_root_backup: | |||
2519 | log_tree_root = btrfs_alloc_root(fs_info); | 2546 | log_tree_root = btrfs_alloc_root(fs_info); |
2520 | if (!log_tree_root) { | 2547 | if (!log_tree_root) { |
2521 | err = -ENOMEM; | 2548 | err = -ENOMEM; |
2522 | goto fail_trans_kthread; | 2549 | goto fail_qgroup; |
2523 | } | 2550 | } |
2524 | 2551 | ||
2525 | __setup_root(nodesize, leafsize, sectorsize, stripesize, | 2552 | __setup_root(nodesize, leafsize, sectorsize, stripesize, |
@@ -2559,7 +2586,7 @@ retry_root_backup: | |||
2559 | printk(KERN_WARNING | 2586 | printk(KERN_WARNING |
2560 | "btrfs: failed to recover relocation\n"); | 2587 | "btrfs: failed to recover relocation\n"); |
2561 | err = -EINVAL; | 2588 | err = -EINVAL; |
2562 | goto fail_trans_kthread; | 2589 | goto fail_qgroup; |
2563 | } | 2590 | } |
2564 | } | 2591 | } |
2565 | 2592 | ||
@@ -2569,10 +2596,10 @@ retry_root_backup: | |||
2569 | 2596 | ||
2570 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); | 2597 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); |
2571 | if (!fs_info->fs_root) | 2598 | if (!fs_info->fs_root) |
2572 | goto fail_trans_kthread; | 2599 | goto fail_qgroup; |
2573 | if (IS_ERR(fs_info->fs_root)) { | 2600 | if (IS_ERR(fs_info->fs_root)) { |
2574 | err = PTR_ERR(fs_info->fs_root); | 2601 | err = PTR_ERR(fs_info->fs_root); |
2575 | goto fail_trans_kthread; | 2602 | goto fail_qgroup; |
2576 | } | 2603 | } |
2577 | 2604 | ||
2578 | if (sb->s_flags & MS_RDONLY) | 2605 | if (sb->s_flags & MS_RDONLY) |
@@ -2596,6 +2623,8 @@ retry_root_backup: | |||
2596 | 2623 | ||
2597 | return 0; | 2624 | return 0; |
2598 | 2625 | ||
2626 | fail_qgroup: | ||
2627 | btrfs_free_qgroup_config(fs_info); | ||
2599 | fail_trans_kthread: | 2628 | fail_trans_kthread: |
2600 | kthread_stop(fs_info->transaction_kthread); | 2629 | kthread_stop(fs_info->transaction_kthread); |
2601 | fail_cleaner: | 2630 | fail_cleaner: |
@@ -3194,6 +3223,8 @@ int close_ctree(struct btrfs_root *root) | |||
3194 | fs_info->closing = 2; | 3223 | fs_info->closing = 2; |
3195 | smp_mb(); | 3224 | smp_mb(); |
3196 | 3225 | ||
3226 | btrfs_free_qgroup_config(root->fs_info); | ||
3227 | |||
3197 | if (fs_info->delalloc_bytes) { | 3228 | if (fs_info->delalloc_bytes) { |
3198 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", | 3229 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", |
3199 | (unsigned long long)fs_info->delalloc_bytes); | 3230 | (unsigned long long)fs_info->delalloc_bytes); |
@@ -3213,6 +3244,10 @@ int close_ctree(struct btrfs_root *root) | |||
3213 | free_extent_buffer(fs_info->dev_root->commit_root); | 3244 | free_extent_buffer(fs_info->dev_root->commit_root); |
3214 | free_extent_buffer(fs_info->csum_root->node); | 3245 | free_extent_buffer(fs_info->csum_root->node); |
3215 | free_extent_buffer(fs_info->csum_root->commit_root); | 3246 | free_extent_buffer(fs_info->csum_root->commit_root); |
3247 | if (fs_info->quota_root) { | ||
3248 | free_extent_buffer(fs_info->quota_root->node); | ||
3249 | free_extent_buffer(fs_info->quota_root->commit_root); | ||
3250 | } | ||
3216 | 3251 | ||
3217 | btrfs_free_block_groups(fs_info); | 3252 | btrfs_free_block_groups(fs_info); |
3218 | 3253 | ||