btrfsck: make sure we fix the block group accounting during repair
authorChris Mason <chris.mason@oracle.com>
Thu, 9 Feb 2012 16:53:33 +0000 (11:53 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 9 Feb 2012 16:53:33 +0000 (11:53 -0500)
The block group accounting is fixed after we check the extent back
references.  This makes sure the accounting is fixed unless we
were not able to repair the backrefs.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
btrfsck.c
extent-tree.c

index 606ebfc..e6fe926 100644 (file)
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -3070,7 +3070,12 @@ repair_abort:
                if (ret) {
                        fprintf(stderr, "failed to repair damaged filesystem, aborting\n");
                        exit(1);
+               } else {
+                       btrfs_fix_block_accounting(trans, root);
                }
+               if (err)
+                       fprintf(stderr, "repaired damaged extent references\n");
+               return ret;
        }
        return err;
 }
@@ -3262,11 +3267,10 @@ int main(int ac, char **av)
        }
 
        ret = check_extents(trans, root, repair);
-       if (ret)
+       if (ret) {
+               fprintf(stderr, "check extents failed with %d!!!!!!!!!\n", ret);
                goto out;
-
-       if (repair)
-               btrfs_fix_block_accounting(trans, root);
+       }
 
        fprintf(stderr, "checking fs roots\n");
        ret = check_fs_roots(root, &root_cache);
index 5c4057e..dd593fe 100644 (file)
@@ -1953,6 +1953,21 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
        return 0;
 }
 
+static int extent_root_pending_ops(struct btrfs_fs_info *info)
+{
+       u64 start;
+       u64 end;
+       int ret;
+
+       ret = find_first_extent_bit(&info->extent_ins, 0, &start,
+                                   &end, EXTENT_LOCKED);
+       if (!ret) {
+               ret = find_first_extent_bit(&info->pending_del, 0, &start, &end,
+                                           EXTENT_LOCKED);
+       }
+       return ret == 0;
+
+}
 static int finish_current_insert(struct btrfs_trans_handle *trans,
                                 struct btrfs_root *extent_root)
 {
@@ -3380,6 +3395,15 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
 
        root = root->fs_info->extent_root;
 
+       while(extent_root_pending_ops(fs_info)) {
+               ret = finish_current_insert(trans, root);
+               if (ret)
+                       return ret;
+               ret = del_pending_extents(trans, root);
+               if (ret)
+                       return ret;
+       }
+
        while(1) {
                cache = btrfs_lookup_block_group(fs_info, start);
                if (!cache)