summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--btrfs-find-root.c4
-rw-r--r--chunk-recover.c6
-rw-r--r--cmds-filesystem.c2
-rw-r--r--disk-io.c17
-rw-r--r--disk-io.h5
-rw-r--r--super-recover.c2
-rw-r--r--utils.c11
-rw-r--r--volumes.c4
-rw-r--r--volumes.h2
9 files changed, 29 insertions, 24 deletions
diff --git a/btrfs-find-root.c b/btrfs-find-root.c
index 25d79f1a..e31a9b59 100644
--- a/btrfs-find-root.c
+++ b/btrfs-find-root.c
@@ -82,7 +82,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device)
return NULL;
}
- ret = btrfs_scan_fs_devices(fd, device, &fs_devices, 0, 1);
+ ret = btrfs_scan_fs_devices(fd, device, &fs_devices, 0, 1, 1);
if (ret)
goto out;
@@ -94,7 +94,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device)
disk_super = fs_info->super_copy;
ret = btrfs_read_dev_super(fs_devices->latest_bdev,
- disk_super, fs_info->super_bytenr);
+ disk_super, fs_info->super_bytenr, 1);
if (ret) {
printk("No valid btrfs found\n");
goto out_devices;
diff --git a/chunk-recover.c b/chunk-recover.c
index b638ada6..14c25a75 100644
--- a/chunk-recover.c
+++ b/chunk-recover.c
@@ -1281,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;
@@ -1347,7 +1347,7 @@ static int recover_prepare(struct recover_control *rc, char *path)
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;
@@ -1366,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;
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 6d7c13e6..46754998 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -513,7 +513,7 @@ static int dev_to_fsid(char *dev, __u8 *fsid)
disk_super = (struct btrfs_super_block *)buf;
ret = btrfs_read_dev_super(fd, disk_super,
- BTRFS_SUPER_INFO_OFFSET);
+ BTRFS_SUPER_INFO_OFFSET, 0);
if (ret)
goto out;
diff --git a/disk-io.c b/disk-io.c
index a54025e7..f71f5ca7 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -992,7 +992,7 @@ void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info)
int btrfs_scan_fs_devices(int fd, const char *path,
struct btrfs_fs_devices **fs_devices,
- u64 sb_bytenr, int run_ioctl)
+ u64 sb_bytenr, int run_ioctl, int super_recover)
{
u64 total_devs;
int ret;
@@ -1000,7 +1000,7 @@ int btrfs_scan_fs_devices(int fd, const char *path,
sb_bytenr = BTRFS_SUPER_INFO_OFFSET;
ret = btrfs_scan_one_device(fd, path, fs_devices,
- &total_devs, sb_bytenr);
+ &total_devs, sb_bytenr, super_recover);
if (ret) {
fprintf(stderr, "No valid Btrfs found on %s\n", path);
return ret;
@@ -1088,7 +1088,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
fs_info->on_restoring = 1;
ret = btrfs_scan_fs_devices(fp, path, &fs_devices, sb_bytenr,
- !(flags & OPEN_CTREE_RECOVER_SUPER));
+ !(flags & OPEN_CTREE_RECOVER_SUPER),
+ (flags & OPEN_CTREE_RECOVER_SUPER));
if (ret)
goto out;
@@ -1108,9 +1109,9 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path,
disk_super = fs_info->super_copy;
if (!(flags & OPEN_CTREE_RECOVER_SUPER))
ret = btrfs_read_dev_super(fs_devices->latest_bdev,
- disk_super, sb_bytenr);
+ disk_super, sb_bytenr, 1);
else
- ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr);
+ ret = btrfs_read_dev_super(fp, disk_super, sb_bytenr, 0);
if (ret) {
printk("No valid btrfs found\n");
goto out_devices;
@@ -1194,13 +1195,15 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
return info->fs_root;
}
-int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr)
+int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
+ int super_recover)
{
u8 fsid[BTRFS_FSID_SIZE];
int fsid_is_initialized = 0;
struct btrfs_super_block buf;
int i;
int ret;
+ int max_super = super_recover ? BTRFS_SUPER_MIRROR_MAX : 1;
u64 transid = 0;
u64 bytenr;
@@ -1224,7 +1227,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr)
* later supers, using BTRFS_SUPER_MIRROR_MAX instead
*/
- for (i = 0; i < 1; i++) {
+ for (i = 0; i < max_super; i++) {
bytenr = btrfs_sb_offset(i);
ret = pread64(fd, &buf, sizeof(buf), bytenr);
if (ret < sizeof(buf))
diff --git a/disk-io.h b/disk-io.h
index 941a3da6..13d4420a 100644
--- a/disk-io.h
+++ b/disk-io.h
@@ -68,7 +68,7 @@ void btrfs_release_all_roots(struct btrfs_fs_info *fs_info);
void btrfs_cleanup_all_caches(struct btrfs_fs_info *fs_info);
int btrfs_scan_fs_devices(int fd, const char *path,
struct btrfs_fs_devices **fs_devices, u64 sb_bytenr,
- int run_ioctl);
+ int run_ioctl, int super_recover);
int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info);
struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr,
@@ -82,7 +82,8 @@ int close_ctree(struct btrfs_root *root);
int write_all_supers(struct btrfs_root *root);
int write_ctree_super(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
-int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr);
+int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
+ int super_recover);
int btrfs_map_bh_to_logical(struct btrfs_root *root, struct extent_buffer *bh,
u64 logical);
struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
diff --git a/super-recover.c b/super-recover.c
index cd6ba372..767de4ba 100644
--- a/super-recover.c
+++ b/super-recover.c
@@ -292,7 +292,7 @@ int btrfs_recover_superblocks(const char *dname,
}
init_recover_superblock(&recover);
- ret = btrfs_scan_fs_devices(fd, dname, &recover.fs_devices, 0, 0);
+ ret = btrfs_scan_fs_devices(fd, dname, &recover.fs_devices, 0, 0, 1);
close(fd);
if (ret) {
ret = 1;
diff --git a/utils.c b/utils.c
index 27a0079c..f9ad946e 100644
--- a/utils.c
+++ b/utils.c
@@ -1163,7 +1163,7 @@ int check_mounted_where(int fd, const char *file, char *where, int size,
/* scan the initial device */
ret = btrfs_scan_one_device(fd, file, &fs_devices_mnt,
- &total_devs, BTRFS_SUPER_INFO_OFFSET);
+ &total_devs, BTRFS_SUPER_INFO_OFFSET, 0);
is_btrfs = (ret >= 0);
/* scan other devices */
@@ -1325,7 +1325,7 @@ again:
}
ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
&num_devices,
- BTRFS_SUPER_INFO_OFFSET);
+ BTRFS_SUPER_INFO_OFFSET, 0);
if (ret == 0 && run_ioctl > 0) {
btrfs_register_one_device(fullpath);
}
@@ -1668,7 +1668,7 @@ scan_again:
}
ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices,
&num_devices,
- BTRFS_SUPER_INFO_OFFSET);
+ BTRFS_SUPER_INFO_OFFSET, 0);
if (ret == 0 && run_ioctl > 0) {
btrfs_register_one_device(fullpath);
}
@@ -1880,7 +1880,8 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args,
fi_args->num_devices = 1;
disk_super = (struct btrfs_super_block *)buf;
- ret = btrfs_read_dev_super(fd, disk_super, BTRFS_SUPER_INFO_OFFSET);
+ ret = btrfs_read_dev_super(fd, disk_super,
+ BTRFS_SUPER_INFO_OFFSET, 0);
if (ret < 0) {
ret = -EIO;
goto out;
@@ -2229,7 +2230,7 @@ int btrfs_scan_lblkid(int update_kernel)
continue;
}
ret = btrfs_scan_one_device(fd, path, &tmp_devices,
- &num_devices, BTRFS_SUPER_INFO_OFFSET);
+ &num_devices, BTRFS_SUPER_INFO_OFFSET, 0);
if (ret) {
printf("ERROR: could not scan %s\n", path);
close (fd);
diff --git a/volumes.c b/volumes.c
index 36f60501..f623a444 100644
--- a/volumes.c
+++ b/volumes.c
@@ -233,7 +233,7 @@ fail:
int btrfs_scan_one_device(int fd, const char *path,
struct btrfs_fs_devices **fs_devices_ret,
- u64 *total_devs, u64 super_offset)
+ u64 *total_devs, u64 super_offset, int super_recover)
{
struct btrfs_super_block *disk_super;
char *buf;
@@ -246,7 +246,7 @@ int btrfs_scan_one_device(int fd, const char *path,
goto error;
}
disk_super = (struct btrfs_super_block *)buf;
- ret = btrfs_read_dev_super(fd, disk_super, super_offset);
+ ret = btrfs_read_dev_super(fd, disk_super, super_offset, super_recover);
if (ret < 0) {
ret = -EIO;
goto error_brelse;
diff --git a/volumes.h b/volumes.h
index c7e764bf..447dd4b8 100644
--- a/volumes.h
+++ b/volumes.h
@@ -179,7 +179,7 @@ int btrfs_update_device(struct btrfs_trans_handle *trans,
struct btrfs_device *device);
int btrfs_scan_one_device(int fd, const char *path,
struct btrfs_fs_devices **fs_devices_ret,
- u64 *total_devs, u64 super_offset);
+ u64 *total_devs, u64 super_offset, int super_recover);
int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len);
struct list_head *btrfs_scanned_uuids(void);
int btrfs_add_system_chunk(struct btrfs_trans_handle *trans,