Merge branch 'alloc_path' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh...
[linux-2.6.git] / fs / btrfs / tree-log.c
index a794b9f..babee65 100644 (file)
@@ -382,7 +382,6 @@ insert:
                } else if (found_size < item_size) {
                        ret = btrfs_extend_item(trans, root, path,
                                                item_size - found_size);
-                       BUG_ON(ret);
                }
        } else if (ret) {
                return ret;
@@ -590,6 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
                                                ins.objectid, ins.offset,
                                                0, root->root_key.objectid,
                                                key->objectid, offset);
+                               BUG_ON(ret);
                        } else {
                                /*
                                 * insert the extent pointer in the extent
@@ -614,7 +614,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
 
                        ret = btrfs_lookup_csums_range(root->log_root,
                                                csum_start, csum_end - 1,
-                                               &ordered_sums);
+                                               &ordered_sums, 0);
                        BUG_ON(ret);
                        while (!list_empty(&ordered_sums)) {
                                struct btrfs_ordered_sum *sums;
@@ -678,7 +678,10 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans,
        btrfs_release_path(path);
 
        inode = read_one_inode(root, location.objectid);
-       BUG_ON(!inode);
+       if (!inode) {
+               kfree(name);
+               return -EIO;
+       }
 
        ret = link_to_fixup_dir(trans, root, path, location.objectid);
        BUG_ON(ret);
@@ -817,7 +820,10 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
                return -ENOENT;
 
        inode = read_one_inode(root, key->objectid);
-       BUG_ON(!inode);
+       if (!inode) {
+               iput(dir);
+               return -EIO;
+       }
 
        ref_ptr = btrfs_item_ptr_offset(eb, slot);
        ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
@@ -1051,11 +1057,13 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
                        break;
 
                ret = btrfs_del_item(trans, root, path);
-               BUG_ON(ret);
+               if (ret)
+                       goto out;
 
                btrfs_release_path(path);
                inode = read_one_inode(root, key.offset);
-               BUG_ON(!inode);
+               if (!inode)
+                       return -EIO;
 
                ret = fixup_inode_link_count(trans, root, inode);
                BUG_ON(ret);
@@ -1069,8 +1077,10 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
                 */
                key.offset = (u64)-1;
        }
+       ret = 0;
+out:
        btrfs_release_path(path);
-       return 0;
+       return ret;
 }
 
 
@@ -1089,7 +1099,8 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
        struct inode *inode;
 
        inode = read_one_inode(root, objectid);
-       BUG_ON(!inode);
+       if (!inode)
+               return -EIO;
 
        key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID;
        btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY);
@@ -1176,7 +1187,8 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
        int ret;
 
        dir = read_one_inode(root, key->objectid);
-       BUG_ON(!dir);
+       if (!dir)
+               return -EIO;
 
        name_len = btrfs_dir_name_len(eb, di);
        name = kmalloc(name_len, GFP_NOFS);
@@ -1432,7 +1444,10 @@ again:
                        btrfs_release_path(path);
                        btrfs_release_path(log_path);
                        inode = read_one_inode(root, location.objectid);
-                       BUG_ON(!inode);
+                       if (!inode) {
+                               kfree(name);
+                               return -EIO;
+                       }
 
                        ret = link_to_fixup_dir(trans, root,
                                                path, location.objectid);
@@ -1602,7 +1617,8 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
                return 0;
 
        path = btrfs_alloc_path();
-       BUG_ON(!path);
+       if (!path)
+               return -ENOMEM;
 
        nritems = btrfs_header_nritems(eb);
        for (i = 0; i < nritems; i++) {
@@ -1708,15 +1724,17 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
                        return -ENOMEM;
 
                if (*level == 1) {
-                       wc->process_func(root, next, wc, ptr_gen);
+                       ret = wc->process_func(root, next, wc, ptr_gen);
+                       if (ret)
+                               return ret;
 
                        path->slots[*level]++;
                        if (wc->free) {
                                btrfs_read_buffer(next, ptr_gen);
 
                                btrfs_tree_lock(next);
-                               clean_tree_block(trans, root, next);
                                btrfs_set_lock_blocking(next);
+                               clean_tree_block(trans, root, next);
                                btrfs_wait_tree_block_writeback(next);
                                btrfs_tree_unlock(next);
 
@@ -1773,16 +1791,19 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
                                parent = path->nodes[*level + 1];
 
                        root_owner = btrfs_header_owner(parent);
-                       wc->process_func(root, path->nodes[*level], wc,
+                       ret = wc->process_func(root, path->nodes[*level], wc,
                                 btrfs_header_generation(path->nodes[*level]));
+                       if (ret)
+                               return ret;
+
                        if (wc->free) {
                                struct extent_buffer *next;
 
                                next = path->nodes[*level];
 
                                btrfs_tree_lock(next);
-                               clean_tree_block(trans, root, next);
                                btrfs_set_lock_blocking(next);
+                               clean_tree_block(trans, root, next);
                                btrfs_wait_tree_block_writeback(next);
                                btrfs_tree_unlock(next);
 
@@ -1849,8 +1870,8 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
                        next = path->nodes[orig_level];
 
                        btrfs_tree_lock(next);
-                       clean_tree_block(trans, log, next);
                        btrfs_set_lock_blocking(next);
+                       clean_tree_block(trans, log, next);
                        btrfs_wait_tree_block_writeback(next);
                        btrfs_tree_unlock(next);
 
@@ -2094,7 +2115,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         * the running transaction open, so a full commit can't hop
         * in and cause problems either.
         */
+       btrfs_scrub_pause_super(root);
        write_ctree_super(trans, root->fs_info->tree_root, 1);
+       btrfs_scrub_continue_super(root);
        ret = 0;
 
        mutex_lock(&root->log_mutex);
@@ -2587,7 +2610,8 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
                        break;
 
                ret = btrfs_del_item(trans, log, path);
-               BUG_ON(ret);
+               if (ret)
+                       break;
                btrfs_release_path(path);
        }
        btrfs_release_path(path);
@@ -2665,6 +2689,9 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
                        extent = btrfs_item_ptr(src, start_slot + i,
                                                struct btrfs_file_extent_item);
 
+                       if (btrfs_file_extent_generation(src, extent) < trans->transid)
+                               continue;
+
                        found_type = btrfs_file_extent_type(src, extent);
                        if (found_type == BTRFS_FILE_EXTENT_REG ||
                            found_type == BTRFS_FILE_EXTENT_PREALLOC) {
@@ -2689,7 +2716,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
                                ret = btrfs_lookup_csums_range(
                                                log->fs_info->csum_root,
                                                ds + cs, ds + cs + cl - 1,
-                                               &ordered_sums);
+                                               &ordered_sums, 0);
                                BUG_ON(ret);
                        }
                }
@@ -3156,7 +3183,7 @@ again:
                tmp_key.offset = (u64)-1;
 
                wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key);
-               BUG_ON(!wc.replay_dest);
+               BUG_ON(IS_ERR_OR_NULL(wc.replay_dest));
 
                wc.replay_dest->log_root = log;
                btrfs_record_root_in_trans(trans, wc.replay_dest);