btrfs-progs: add option to disable backtrace usage
[platform/upstream/btrfs-progs.git] / chunk-recover.c
index 9c44b49..aa38916 100644 (file)
@@ -42,8 +42,6 @@
 #include "btrfsck.h"
 #include "commands.h"
 
-#define BTRFS_NUM_MIRRORS                      2
-
 struct recover_control {
        int verbose;
        int yes;
@@ -71,8 +69,8 @@ struct extent_record {
        struct cache_extent cache;
        u64 generation;
        u8 csum[BTRFS_CSUM_SIZE];
-       struct btrfs_device *devices[BTRFS_NUM_MIRRORS];
-       u64 offsets[BTRFS_NUM_MIRRORS];
+       struct btrfs_device *devices[BTRFS_MAX_MIRRORS];
+       u64 offsets[BTRFS_MAX_MIRRORS];
        int nmirrors;
 };
 
@@ -128,7 +126,7 @@ again:
                            memcmp(exist->csum, rec->csum, BTRFS_CSUM_SIZE)) {
                                ret = -EEXIST;
                        } else {
-                               BUG_ON(exist->nmirrors >= BTRFS_NUM_MIRRORS);
+                               BUG_ON(exist->nmirrors >= BTRFS_MAX_MIRRORS);
                                exist->devices[exist->nmirrors] = device;
                                exist->offsets[exist->nmirrors] = offset;
                                exist->nmirrors++;
@@ -1283,7 +1281,7 @@ open_ctree_with_broken_chunk(struct recover_control *rc)
 
        disk_super = fs_info->super_copy;
        ret = btrfs_read_dev_super(fs_info->fs_devices->latest_bdev,
-                                  disk_super, fs_info->super_bytenr);
+                                  disk_super, fs_info->super_bytenr, 1);
        if (ret) {
                fprintf(stderr, "No valid btrfs found\n");
                goto out_devices;
@@ -1342,14 +1340,14 @@ static int recover_prepare(struct recover_control *rc, char *path)
                return -1;
        }
 
-       sb = malloc(sizeof(struct btrfs_super_block));
+       sb = malloc(BTRFS_SUPER_INFO_SIZE);
        if (!sb) {
                fprintf(stderr, "allocating memory for sb failed.\n");
                ret = -ENOMEM;
                goto fail_close_fd;
        }
 
-       ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET);
+       ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET, 1);
        if (ret) {
                fprintf(stderr, "read super block error\n");
                goto fail_free_sb;
@@ -1368,7 +1366,7 @@ static int recover_prepare(struct recover_control *rc, char *path)
                goto fail_free_sb;
        }
 
-       ret = btrfs_scan_fs_devices(fd, path, &fs_devices, 0, 1);
+       ret = btrfs_scan_fs_devices(fd, path, &fs_devices, 0, 1, 1);
        if (ret)
                goto fail_free_sb;
 
@@ -1785,6 +1783,23 @@ static inline int count_devext_records(struct list_head *record_list)
        return num_of_records;
 }
 
+static int fill_chunk_up(struct chunk_record *chunk, struct list_head *devexts,
+                        struct recover_control *rc)
+{
+       int ret = 0;
+       int i;
+
+       for (i = 0; i < chunk->num_stripes; i++) {
+               if (!chunk->stripes[i].devid) {
+                       ret = insert_stripe(devexts, rc, chunk, i);
+                       if (ret)
+                               break;
+               }
+       }
+
+       return ret;
+}
+
 #define EQUAL_STRIPE (1 << 0)
 
 static int rebuild_raid_data_chunk_stripes(struct recover_control *rc,
@@ -1918,9 +1933,9 @@ next_csum:
                num_unordered = count_devext_records(&unordered);
                if (chunk->type_flags & BTRFS_BLOCK_GROUP_RAID6
                                        && num_unordered == 2) {
-                       list_splice_init(&unordered, &chunk->dextents);
                        btrfs_release_path(&path);
-                       return 0;
+                       ret = fill_chunk_up(chunk, &unordered, rc);
+                       return ret;
                }
 
                goto next_stripe;
@@ -1965,14 +1980,7 @@ out:
                        & BTRFS_BLOCK_GROUP_RAID5)
                 || (num_unordered == 3 && chunk->type_flags
                        & BTRFS_BLOCK_GROUP_RAID6)) {
-                       for (i = 0; i < chunk->num_stripes; i++) {
-                               if (!chunk->stripes[i].devid) {
-                                       ret = insert_stripe(&unordered, rc,
-                                                       chunk, i);
-                                       if (ret)
-                                               break;
-                               }
-                       }
+                       ret = fill_chunk_up(chunk, &unordered, rc);
                }
        }
 fail_out: