Btrfs: generic data structure to build unique lists
[cascardo/linux.git] / fs / btrfs / relocation.c
index 59bb176..dff29d5 100644 (file)
@@ -1174,6 +1174,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
                        list_add_tail(&new_edge->list[UPPER],
                                      &new_node->lower);
                }
+       } else {
+               list_add_tail(&new_node->lower, &cache->leaves);
        }
 
        rb_node = tree_insert(&cache->rb_root, new_node->bytenr,
@@ -2041,8 +2043,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
                BUG_ON(IS_ERR(trans));
                trans->block_rsv = rc->block_rsv;
 
-               ret = btrfs_block_rsv_check(trans, root, rc->block_rsv,
-                                           min_reserved, 0);
+               ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved);
                if (ret) {
                        BUG_ON(ret != -EAGAIN);
                        ret = btrfs_commit_transaction(trans, root);
@@ -2152,8 +2153,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 again:
        if (!err) {
                num_bytes = rc->merging_rsv_size;
-               ret = btrfs_block_rsv_add(NULL, root, rc->block_rsv,
-                                         num_bytes);
+               ret = btrfs_block_rsv_add(root, rc->block_rsv, num_bytes);
                if (ret)
                        err = ret;
        }
@@ -2427,7 +2427,7 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans,
        num_bytes = calcu_metadata_size(rc, node, 1) * 2;
 
        trans->block_rsv = rc->block_rsv;
-       ret = btrfs_block_rsv_add(trans, root, rc->block_rsv, num_bytes);
+       ret = btrfs_block_rsv_add(root, rc->block_rsv, num_bytes);
        if (ret) {
                if (ret == -EAGAIN)
                        rc->commit_transaction = 1;
@@ -2922,6 +2922,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
        unsigned long last_index;
        struct page *page;
        struct file_ra_state *ra;
+       gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
        int nr = 0;
        int ret = 0;
 
@@ -2956,7 +2957,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
                                                  ra, NULL, index,
                                                  last_index + 1 - index);
                        page = find_or_create_page(inode->i_mapping, index,
-                                                  GFP_NOFS);
+                                                  mask);
                        if (!page) {
                                btrfs_delalloc_release_metadata(inode,
                                                        PAGE_CACHE_SIZE);
@@ -3323,8 +3324,11 @@ static int find_data_references(struct reloc_control *rc,
        }
 
        key.objectid = ref_objectid;
-       key.offset = ref_offset;
        key.type = BTRFS_EXTENT_DATA_KEY;
+       if (ref_offset > ((u64)-1 << 32))
+               key.offset = 0;
+       else
+               key.offset = ref_offset;
 
        path->search_commit_root = 1;
        path->skip_locking = 1;
@@ -3645,14 +3649,11 @@ int prepare_to_relocate(struct reloc_control *rc)
         * btrfs_init_reloc_root will use them when there
         * is no reservation in transaction handle.
         */
-       ret = btrfs_block_rsv_add(NULL, rc->extent_root, rc->block_rsv,
+       ret = btrfs_block_rsv_add(rc->extent_root, rc->block_rsv,
                                  rc->extent_root->nodesize * 256);
        if (ret)
                return ret;
 
-       rc->block_rsv->refill_used = 1;
-       btrfs_add_durable_block_rsv(rc->extent_root->fs_info, rc->block_rsv);
-
        memset(&rc->cluster, 0, sizeof(rc->cluster));
        rc->search_start = rc->block_group->key.objectid;
        rc->extents_found = 0;
@@ -3777,8 +3778,7 @@ restart:
                        }
                }
 
-               ret = btrfs_block_rsv_check(trans, rc->extent_root,
-                                           rc->block_rsv, 0, 5);
+               ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5);
                if (ret < 0) {
                        if (ret != -EAGAIN) {
                                err = ret;