[PATCH 2/4] btrfs-progs: Allow btrfs_read_dev_super() to read all 3 super for super_recover.
Btrfs-progs superblock checksum check is somewhat too restricted for super-recover, since current btrfs-progs will only read the 1st superblock and if you need super-recover the 1st superblock is possibly already damaged. The fix is introducing super_recover parameter for btrfs_read_dev_super() and callers to allow scan backup superblocks if needed. Signed-off-by: Qu Wenruo quwen...@cn.fujitsu.com --- btrfs-find-root.c | 4 ++-- chunk-recover.c | 6 +++--- cmds-filesystem.c | 2 +- disk-io.c | 17 ++--- disk-io.h | 5 +++-- super-recover.c | 2 +- utils.c | 11 ++- volumes.c | 4 ++-- volumes.h | 2 +- 9 files changed, 29 insertions(+), 24 deletions(-) diff --git a/btrfs-find-root.c b/btrfs-find-root.c index 25d79f1..e31a9b5 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 613d715..9baedd7 100644 --- a/chunk-recover.c +++ b/chunk-recover.c @@ -1283,7 +1283,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; @@ -1349,7 +1349,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; @@ -1368,7 +1368,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 306f715..d2e46dc 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 e447af8..1bd9fae 100644 --- a/disk-io.c +++ b/disk-io.c @@ -980,7 +980,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; @@ -988,7 +988,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; @@ -1076,7 +1076,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; @@ -1096,9 +1097,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, -
[PATCH 2/4] btrfs-progs: Allow btrfs_read_dev_super() to read all 3 super for super_recover.
Btrfs-progs superblock checksum check is somewhat too restricted for super-recover, since current btrfs-progs will only read the 1st superblock and if you need super-recover the 1st superblock is possibly already damaged. The fix is introducing super_recover parameter for btrfs_read_dev_super() and callers to allow scan backup superblocks if needed. Signed-off-by: Qu Wenruo quwen...@cn.fujitsu.com --- btrfs-find-root.c | 4 ++-- chunk-recover.c | 6 +++--- cmds-filesystem.c | 2 +- disk-io.c | 17 ++--- disk-io.h | 5 +++-- super-recover.c | 2 +- utils.c | 11 ++- volumes.c | 4 ++-- volumes.h | 2 +- 9 files changed, 29 insertions(+), 24 deletions(-) diff --git a/btrfs-find-root.c b/btrfs-find-root.c index 25d79f1..e31a9b5 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 613d715..9baedd7 100644 --- a/chunk-recover.c +++ b/chunk-recover.c @@ -1283,7 +1283,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; @@ -1349,7 +1349,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; @@ -1368,7 +1368,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 306f715..d2e46dc 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 e447af8..1bd9fae 100644 --- a/disk-io.c +++ b/disk-io.c @@ -980,7 +980,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; @@ -988,7 +988,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; @@ -1076,7 +1076,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; @@ -1096,9 +1097,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, -
Re: [PATCH 2/4] btrfs-progs: Allow btrfs_read_dev_super() to read all 3 super for super_recover.
On Thu, Jul 03, 2014 at 05:36:36PM +0800, Qu Wenruo wrote: @@ -1182,7 +1183,8 @@ 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 recover_super) + int max_super = recover_super ? BTRFS_SUPER_MIRROR_MAX : 1; Minor tweak, I've renamed it to super_recover as this is used everywhere else. No need to resend the patch. -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html