Btrfs: kill delay_iput arg to the wait_ordered functions
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / btrfs / relocation.c
index 1209649..a5a2632 100644 (file)
@@ -335,7 +335,7 @@ static void backref_tree_panic(struct rb_node *rb_node, int errno, u64 bytenr)
        if (bnode->root)
                fs_info = bnode->root->fs_info;
        btrfs_panic(fs_info, errno, "Inconsistency in backref cache "
-                   "found at offset %llu\n", (unsigned long long)bytenr);
+                   "found at offset %llu\n", bytenr);
 }
 
 /*
@@ -641,6 +641,11 @@ int find_inline_backref(struct extent_buffer *leaf, int slot,
                WARN_ON(item_size < sizeof(*ei) + sizeof(*bi));
                return 1;
        }
+       if (key.type == BTRFS_METADATA_ITEM_KEY &&
+           item_size <= sizeof(*ei)) {
+               WARN_ON(item_size < sizeof(*ei));
+               return 1;
+       }
 
        if (key.type == BTRFS_EXTENT_ITEM_KEY) {
                bi = (struct btrfs_tree_block_info *)(ei + 1);
@@ -691,6 +696,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
        int cowonly;
        int ret;
        int err = 0;
+       bool need_check = true;
 
        path1 = btrfs_alloc_path();
        path2 = btrfs_alloc_path();
@@ -914,6 +920,7 @@ again:
                        cur->bytenr);
 
                lower = cur;
+               need_check = true;
                for (; level < BTRFS_MAX_LEVEL; level++) {
                        if (!path2->nodes[level]) {
                                BUG_ON(btrfs_root_bytenr(&root->root_item) !=
@@ -957,14 +964,12 @@ again:
 
                                /*
                                 * add the block to pending list if we
-                                * need check its backrefs. only block
-                                * at 'cur->level + 1' is added to the
-                                * tail of pending list. this guarantees
-                                * we check backrefs from lower level
-                                * blocks to upper level blocks.
+                                * need check its backrefs, we only do this once
+                                * while walking up a tree as we will catch
+                                * anything else later on.
                                 */
-                               if (!upper->checked &&
-                                   level == cur->level + 1) {
+                               if (!upper->checked && need_check) {
+                                       need_check = false;
                                        list_add_tail(&edge->list[UPPER],
                                                      &list);
                                } else
@@ -1543,7 +1548,7 @@ static int get_new_location(struct inode *reloc_inode, u64 *new_bytenr,
               btrfs_file_extent_other_encoding(leaf, fi));
 
        if (num_bytes != btrfs_file_extent_disk_num_bytes(leaf, fi)) {
-               ret = 1;
+               ret = -EINVAL;
                goto out;
        }
 
@@ -1574,7 +1579,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
        u64 end;
        u32 nritems;
        u32 i;
-       int ret;
+       int ret = 0;
        int first = 1;
        int dirty = 0;
 
@@ -1637,11 +1642,13 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
 
                ret = get_new_location(rc->data_inode, &new_bytenr,
                                       bytenr, num_bytes);
-               if (ret > 0) {
-                       WARN_ON(1);
-                       continue;
+               if (ret) {
+                       /*
+                        * Don't have to abort since we've not changed anything
+                        * in the file extent yet.
+                        */
+                       break;
                }
-               BUG_ON(ret < 0);
 
                btrfs_set_file_extent_disk_bytenr(leaf, fi, new_bytenr);
                dirty = 1;
@@ -1651,18 +1658,24 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
                                           num_bytes, parent,
                                           btrfs_header_owner(leaf),
                                           key.objectid, key.offset, 1);
-               BUG_ON(ret);
+               if (ret) {
+                       btrfs_abort_transaction(trans, root, ret);
+                       break;
+               }
 
                ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
                                        parent, btrfs_header_owner(leaf),
                                        key.objectid, key.offset, 1);
-               BUG_ON(ret);
+               if (ret) {
+                       btrfs_abort_transaction(trans, root, ret);
+                       break;
+               }
        }
        if (dirty)
                btrfs_mark_buffer_dirty(leaf);
        if (inode)
                btrfs_add_delayed_iput(inode);
-       return 0;
+       return ret;
 }
 
 static noinline_for_stack
@@ -2314,8 +2327,13 @@ again:
                        BUG_ON(root->reloc_root != reloc_root);
 
                        ret = merge_reloc_root(rc, root);
-                       if (ret)
+                       if (ret) {
+                               __update_reloc_root(reloc_root, 1);
+                               free_extent_buffer(reloc_root->node);
+                               free_extent_buffer(reloc_root->commit_root);
+                               kfree(reloc_root);
                                goto out;
+                       }
                } else {
                        list_del_init(&reloc_root->root_list);
                }
@@ -2344,9 +2362,6 @@ again:
                        if (IS_ERR(root))
                                continue;
 
-                       if (btrfs_root_refs(&root->root_item) == 0)
-                               continue;
-
                        trans = btrfs_join_transaction(root);
                        BUG_ON(IS_ERR(trans));
 
@@ -3628,7 +3643,7 @@ int add_data_references(struct reloc_control *rc,
        unsigned long ptr;
        unsigned long end;
        u32 blocksize = btrfs_level_size(rc->extent_root, 0);
-       int ret;
+       int ret = 0;
        int err = 0;
 
        eb = path->nodes[0];
@@ -3655,6 +3670,10 @@ int add_data_references(struct reloc_control *rc,
                } else {
                        BUG();
                }
+               if (ret) {
+                       err = ret;
+                       goto out;
+               }
                ptr += btrfs_extent_inline_ref_size(key.type);
        }
        WARN_ON(ptr > end);
@@ -3700,6 +3719,7 @@ int add_data_references(struct reloc_control *rc,
                }
                path->slots[0]++;
        }
+out:
        btrfs_release_path(path);
        if (err)
                free_block_list(blocks);
@@ -4219,15 +4239,14 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
        }
 
        printk(KERN_INFO "btrfs: relocating block group %llu flags %llu\n",
-              (unsigned long long)rc->block_group->key.objectid,
-              (unsigned long long)rc->block_group->flags);
+              rc->block_group->key.objectid, rc->block_group->flags);
 
        ret = btrfs_start_all_delalloc_inodes(fs_info, 0);
        if (ret < 0) {
                err = ret;
                goto out;
        }
-       btrfs_wait_all_ordered_extents(fs_info, 0);
+       btrfs_wait_all_ordered_extents(fs_info);
 
        while (1) {
                mutex_lock(&fs_info->cleaner_mutex);
@@ -4242,7 +4261,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
                        break;
 
                printk(KERN_INFO "btrfs: found %llu extents\n",
-                       (unsigned long long)rc->extents_found);
+                       rc->extents_found);
 
                if (rc->stage == MOVE_DATA_EXTENTS && rc->found_file_extent) {
                        btrfs_wait_ordered_range(rc->data_inode, 0, (u64)-1);
@@ -4488,19 +4507,19 @@ out:
        return ret;
 }
 
-void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root, struct extent_buffer *buf,
-                          struct extent_buffer *cow)
+int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
+                         struct btrfs_root *root, struct extent_buffer *buf,
+                         struct extent_buffer *cow)
 {
        struct reloc_control *rc;
        struct backref_node *node;
        int first_cow = 0;
        int level;
-       int ret;
+       int ret = 0;
 
        rc = root->fs_info->reloc_ctl;
        if (!rc)
-               return;
+               return 0;
 
        BUG_ON(rc->stage == UPDATE_DATA_PTRS &&
               root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID);
@@ -4536,10 +4555,9 @@ void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
                        rc->nodes_relocated += buf->len;
        }
 
-       if (level == 0 && first_cow && rc->stage == UPDATE_DATA_PTRS) {
+       if (level == 0 && first_cow && rc->stage == UPDATE_DATA_PTRS)
                ret = replace_file_extents(trans, rc, root, cow);
-               BUG_ON(ret);
-       }
+       return ret;
 }
 
 /*