]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/btrfs/relocation.c
Btrfs: Integrate metadata reservation with start_transaction
[net-next-2.6.git] / fs / btrfs / relocation.c
index 0b23942cbc0dfc5296afe724759013c14188ac54..145a468c300d4123a3b13d8a59277d3127e2ae76 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
 #include <linux/rbtree.h>
+#include <linux/slab.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -1648,7 +1649,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
        }
 
        if (level == 0 && rc->stage == UPDATE_DATA_PTRS) {
-               trans = btrfs_start_transaction(root, 1);
+               trans = btrfs_start_transaction(root, 0);
 
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &key, 0);
@@ -1674,7 +1675,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
        while (1) {
                leaf = NULL;
                replaced = 0;
-               trans = btrfs_start_transaction(root, 1);
+               trans = btrfs_start_transaction(root, 0);
                max_level = level;
 
                ret = walk_down_reloc_tree(reloc_root, path, &level);
@@ -1802,7 +1803,7 @@ static void merge_func(struct btrfs_work *work)
 
                merge_reloc_root(async->rc, root);
 
-               trans = btrfs_start_transaction(root, 1);
+               trans = btrfs_start_transaction(root, 0);
                btrfs_update_reloc_root(trans, root);
                btrfs_end_transaction(trans, root);
        }
@@ -3296,11 +3297,11 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
        rc->create_reloc_root = 1;
        set_reloc_control(rc);
 
-       trans = btrfs_start_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root, 1);
        btrfs_commit_transaction(trans, rc->extent_root);
 
        while (1) {
-               trans = btrfs_start_transaction(rc->extent_root, 1);
+               trans = btrfs_start_transaction(rc->extent_root, 0);
 
                ret = find_next_extent(trans, rc, path);
                if (ret < 0)
@@ -3410,7 +3411,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
        smp_mb();
 
        if (rc->extents_found > 0) {
-               trans = btrfs_start_transaction(rc->extent_root, 1);
+               trans = btrfs_join_transaction(rc->extent_root, 1);
                btrfs_commit_transaction(trans, rc->extent_root);
        }
 
@@ -3419,7 +3420,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
        unset_reloc_control(rc);
 
        /* get rid of pinned extents */
-       trans = btrfs_start_transaction(rc->extent_root, 1);
+       trans = btrfs_join_transaction(rc->extent_root, 1);
        btrfs_commit_transaction(trans, rc->extent_root);
 
        return err;
@@ -3474,7 +3475,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
        if (IS_ERR(root))
                return ERR_CAST(root);
 
-       trans = btrfs_start_transaction(root, 1);
+       trans = btrfs_start_transaction(root, 6);
        BUG_ON(!trans);
 
        err = btrfs_find_free_objectid(trans, root, objectid, &objectid);
@@ -3513,6 +3514,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        struct btrfs_fs_info *fs_info = extent_root->fs_info;
        struct reloc_control *rc;
        int ret;
+       int rw = 0;
        int err = 0;
 
        rc = kzalloc(sizeof(*rc), GFP_NOFS);
@@ -3523,15 +3525,22 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        extent_io_tree_init(&rc->processed_blocks, NULL, GFP_NOFS);
        INIT_LIST_HEAD(&rc->reloc_roots);
 
+       rc->extent_root = extent_root;
        rc->block_group = btrfs_lookup_block_group(fs_info, group_start);
        BUG_ON(!rc->block_group);
 
+       if (!rc->block_group->ro) {
+               ret = btrfs_set_block_group_ro(extent_root, rc->block_group);
+               if (ret) {
+                       err = ret;
+                       goto out;
+               }
+               rw = 1;
+       }
+
        btrfs_init_workers(&rc->workers, "relocate",
                           fs_info->thread_pool_size, NULL);
 
-       rc->extent_root = extent_root;
-       btrfs_prepare_block_group_relocation(extent_root, rc->block_group);
-
        rc->data_inode = create_reloc_inode(fs_info, rc->block_group);
        if (IS_ERR(rc->data_inode)) {
                err = PTR_ERR(rc->data_inode);
@@ -3596,6 +3605,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        WARN_ON(rc->block_group->reserved > 0);
        WARN_ON(btrfs_block_group_used(&rc->block_group->item) > 0);
 out:
+       if (err && rw)
+               btrfs_set_block_group_rw(extent_root, rc->block_group);
        iput(rc->data_inode);
        btrfs_stop_workers(&rc->workers);
        btrfs_put_block_group(rc->block_group);
@@ -3608,7 +3619,7 @@ static noinline_for_stack int mark_garbage_root(struct btrfs_root *root)
        struct btrfs_trans_handle *trans;
        int ret;
 
-       trans = btrfs_start_transaction(root->fs_info->tree_root, 1);
+       trans = btrfs_start_transaction(root->fs_info->tree_root, 0);
 
        memset(&root->root_item.drop_progress, 0,
                sizeof(root->root_item.drop_progress));