[PATCH 2/4] btrfs-progs: Allow btrfs_read_dev_super() to read all 3 super for super_recover.

2014-07-03 Thread Qu Wenruo
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.

2014-07-03 Thread Qu Wenruo
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.

2014-07-03 Thread David Sterba
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