Anand Jain
2013-Feb-22 05:29 UTC
[bug] mkfs.btrfs reports device busy for ext4 mounted disk
setup: mkfs.btrfs /dev/sdb mkfs.ext4 /dev/sdb && mount /dev/sdb /ext4 mkfs.btrfs /dev/sdc /dev/sdd test case: mkfs.btrfs /dev/sdc /dev/sdd problem: mkfs is fine, however reports the following error .. --- ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy --- findings: First, since previously we have had multi-device btrfs, so mkfs.btrfs would trigger scan for its partner to check if its mounted. Next, since previously we had btrfs on sdb and mkfs.ext4 does not overwrite super-block mirror 1.. so btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) finds btrfs on sdb. So we try to register sdb with the ioctl BTRFS_IOC_SCAN_DEV and fail. unless I am missing something. wipefs (along with the below patch) [PATCH][v2] Btrfs: wipe all the superblock [redhat bugzilla 889888] seems to be only solution as of now. Any idea if there can be a better solution to handle stale btrfs and can be done with in the btrfs limits. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Zach Brown
2013-Feb-22 19:03 UTC
Re: [bug] mkfs.btrfs reports device busy for ext4 mounted disk
> Next, since previously we had btrfs on sdb and mkfs.ext4 > does not overwrite super-block mirror 1.. so > > btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 > sb_bytenr) > > finds btrfs on sdb.btrfs-progs shouldn''t be unconditionally trusting the backup superblocks if the primary is garbage. It should only check the backups if the user specifically asks it to.> unless I am missing something. wipefs (along with the below patch) > [PATCH][v2] Btrfs: wipe all the superblock [redhat bugzilla 889888] > seems to be only solution as of now.This is good practice and will work around the bug in btrfs-progs for now. - z -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Feb-22 22:30 UTC
Re: [bug] mkfs.btrfs reports device busy for ext4 mounted disk
On Fri, Feb 22, 2013 at 11:03:25AM -0800, Zach Brown wrote:> > Next, since previously we had btrfs on sdb and mkfs.ext4 > > does not overwrite super-block mirror 1.. so > > > > btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 > > sb_bytenr) > > > > finds btrfs on sdb. > > btrfs-progs shouldn''t be unconditionally trusting the backup superblocks > if the primary is garbage. It should only check the backups if the user > specifically asks it to.Agreed. Let me add that all the rescue tools should accept a parameter to pick the backup superblocks. Currently fsck -s, select-super -s, restore -u (though I''d like see all the option names unified, ''S'' is my candidate that would not break compatibility). david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-01 10:13 UTC
[PATCH] btrfs-progs: traverse to backup super-block only when indicated
This patch adds 4th parameter to btrfs_scan_one_device() which when set to non-zero value will traverse to check backup super-block. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfs-show.c | 2 +- btrfsctl.c | 2 +- cmds-device.c | 4 ++-- cmds-filesystem.c | 4 ++-- cmds-replace.c | 2 +- disk-io.c | 11 +++++++---- disk-io.h | 3 ++- find-root.c | 6 +++--- utils.c | 19 ++++++++++--------- utils.h | 6 +++--- volumes.c | 4 ++-- volumes.h | 2 +- 12 files changed, 35 insertions(+), 30 deletions(-) diff --git a/btrfs-show.c b/btrfs-show.c index 8210fd2..7b1a35f 100644 --- a/btrfs-show.c +++ b/btrfs-show.c @@ -138,7 +138,7 @@ int main(int ac, char **av) search = av[optind]; } - ret = btrfs_scan_one_dir("/dev", 0); + ret = btrfs_scan_one_dir("/dev", 0, 1); if (ret) fprintf(stderr, "error %d while scanning\n", ret); diff --git a/btrfsctl.c b/btrfsctl.c index 8fd8cc3..5be0961 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -115,7 +115,7 @@ int main(int ac, char **av) if (ac == 2 && strcmp(av[1], "-a") == 0) { fprintf(stderr, "Scanning for Btrfs filesystems\n"); - btrfs_scan_one_dir("/dev", 1); + btrfs_scan_one_dir("/dev", 1, 1); exit(0); } for (i = 1; i < ac; i++) { diff --git a/cmds-device.c b/cmds-device.c index 58df6da..dfc1f56 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -203,9 +203,9 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(1); + ret = btrfs_scan_block_devices(1, 1); else - ret = btrfs_scan_one_dir("/dev", 1); + ret = btrfs_scan_one_dir("/dev", 1, 1); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; diff --git a/cmds-filesystem.c b/cmds-filesystem.c index 2210020..b41457a 100644 --- a/cmds-filesystem.c +++ b/cmds-filesystem.c @@ -257,9 +257,9 @@ static int cmd_show(int argc, char **argv) usage(cmd_show_usage); if(checklist) - ret = btrfs_scan_block_devices(0); + ret = btrfs_scan_block_devices(0, 1); else - ret = btrfs_scan_one_dir("/dev", 0); + ret = btrfs_scan_one_dir("/dev", 0, 1); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); diff --git a/cmds-replace.c b/cmds-replace.c index 4cc32df..788a041 100644 --- a/cmds-replace.c +++ b/cmds-replace.c @@ -275,7 +275,7 @@ static int cmd_start_replace(int argc, char **argv) goto leave_with_error; } ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, 1); if (ret >= 0 && !force_using_targetdev) { fprintf(stderr, "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", diff --git a/disk-io.c b/disk-io.c index 897d0cf..f54c422 100644 --- a/disk-io.c +++ b/disk-io.c @@ -825,7 +825,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED); ret = btrfs_scan_one_device(fp, path, &fs_devices, - &total_devs, sb_bytenr); + &total_devs, sb_bytenr, 1); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", path); @@ -833,7 +833,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1, 0); if (ret) goto out; } @@ -876,7 +876,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fs_info->super_bytenr = sb_bytenr; disk_super = &fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + disk_super, sb_bytenr, 1); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1099,7 +1099,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 rd_sb_mirror) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; @@ -1123,6 +1124,8 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) } for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + if (i > 0 && !rd_sb_mirror) + break; 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 ff87958..2bc8b3e 100644 --- a/disk-io.h +++ b/disk-io.h @@ -59,7 +59,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 rd_sb_mirror); 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/find-root.c b/find-root.c index 20ff972..e84c8b1 100644 --- a/find-root.c +++ b/find-root.c @@ -102,7 +102,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) u64 features; ret = btrfs_scan_one_device(fd, device, &fs_devices, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, 1); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", device); @@ -110,7 +110,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1, 1); if (ret) goto out; } @@ -149,7 +149,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; disk_super = &fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, BTRFS_SUPER_INFO_OFFSET); + disk_super, BTRFS_SUPER_INFO_OFFSET, 1); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.c b/utils.c index 71da787..1f22660 100644 --- a/utils.c +++ b/utils.c @@ -835,12 +835,12 @@ 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 */ if (is_btrfs && total_devs > 1) { - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1, 0))) return ret; } @@ -951,7 +951,7 @@ void btrfs_register_one_device(char *fname) close(fd); } -int btrfs_scan_one_dir(char *dirname, int run_ioctl) +int btrfs_scan_one_dir(char *dirname, int run_ioctl, int rd_sb_mirror) { DIR *dirp = NULL; struct dirent *dirent; @@ -1031,7 +1031,7 @@ again: } ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, rd_sb_mirror); if (ret == 0 && run_ioctl > 0) { btrfs_register_one_device(fullpath); } @@ -1057,13 +1057,13 @@ fail: } int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls) + int run_ioctls, int rd_sb_mirror) { int ret; - ret = btrfs_scan_block_devices(run_ioctls); + ret = btrfs_scan_block_devices(run_ioctls, rd_sb_mirror); if (ret) - ret = btrfs_scan_one_dir("/dev", run_ioctls); + ret = btrfs_scan_one_dir("/dev", run_ioctls, rd_sb_mirror); return ret; } @@ -1294,7 +1294,7 @@ int set_label(const char *btrfs_dev, const char *label) set_label_mounted(btrfs_dev, label); } -int btrfs_scan_block_devices(int run_ioctl) +int btrfs_scan_block_devices(int run_ioctl, int rd_sb_mirror) { struct stat st; @@ -1360,7 +1360,8 @@ scan_again: } ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + rd_sb_mirror); if (ret == 0 && run_ioctl > 0) { btrfs_register_one_device(fullpath); } diff --git a/utils.h b/utils.h index 0b681ed..a71202e 100644 --- a/utils.h +++ b/utils.h @@ -35,9 +35,9 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u64 block_count, u32 io_width, u32 io_align, u32 sectorsize); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls); + int run_ioctls, int rd_sb_mirror); void btrfs_register_one_device(char *fname); -int btrfs_scan_one_dir(char *dirname, int run_ioctl); +int btrfs_scan_one_dir(char *dirname, int run_ioctl, int rd_sb_mirror); int check_mounted(const char *devicename); int check_mounted_where(int fd, const char *file, char *where, int size, struct btrfs_fs_devices **fs_devices_mnt); @@ -45,7 +45,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); int get_mountpt(char *dev, char *mntpt, size_t size); -int btrfs_scan_block_devices(int run_ioctl); +int btrfs_scan_block_devices(int run_ioctl, int rd_sb_mirror); u64 parse_size(char *s); int open_file_or_dir(const char *fname); int get_device_info(int fd, u64 devid, diff --git a/volumes.c b/volumes.c index ca1b402..8e4dcea 100644 --- a/volumes.c +++ b/volumes.c @@ -211,7 +211,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 rd_sb_mirror) { struct btrfs_super_block *disk_super; char *buf; @@ -225,7 +225,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, rd_sb_mirror); if (ret < 0) { ret = -EIO; goto error_brelse; diff --git a/volumes.h b/volumes.h index 911f788..58110e2 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 rd_sb_mirror); int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len); int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree, struct btrfs_fs_devices *fs_devices); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-01 10:18 UTC
Re: [bug] mkfs.btrfs reports device busy for ext4 mounted disk
>> btrfs-progs shouldn''t be unconditionally trusting the backup superblocks >> if the primary is garbage. It should only check the backups if the user >> specifically asks it to. > > Agreed. Let me add that all the rescue tools should accept a parameter > to pick the backup superblocks. Currently fsck -s, select-super -s, > restore -u (though I''d like see all the option names unified, ''S'' is my > candidate that would not break compatibility).Thank You. Have sent out a patch on this thread for your kind review. Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Mar-01 17:37 UTC
Re: [PATCH] btrfs-progs: traverse to backup super-block only when indicated
On 3/1/13 4:13 AM, Anand Jain wrote:> This patch adds 4th parameter to btrfs_scan_one_device() > which when set to non-zero value will traverse to check > backup super-block. > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > btrfs-show.c | 2 +- > btrfsctl.c | 2 +- > cmds-device.c | 4 ++-- > cmds-filesystem.c | 4 ++-- > cmds-replace.c | 2 +- > disk-io.c | 11 +++++++---- > disk-io.h | 3 ++- > find-root.c | 6 +++--- > utils.c | 19 ++++++++++--------- > utils.h | 6 +++--- > volumes.c | 4 ++-- > volumes.h | 2 +- > 12 files changed, 35 insertions(+), 30 deletions(-) > > diff --git a/btrfs-show.c b/btrfs-show.c > index 8210fd2..7b1a35f 100644 > --- a/btrfs-show.c > +++ b/btrfs-show.c > @@ -138,7 +138,7 @@ int main(int ac, char **av) > search = av[optind]; > } > > - ret = btrfs_scan_one_dir("/dev", 0); > + ret = btrfs_scan_one_dir("/dev", 0, 1);It might be helpful to define some self-documenting macros for the 0/1 boolean args, which otherwise are pretty nonobvious. i.e. BTRFS_SCAN_ALL_SB / BTRFS_SCAN_PRIMARY_SB or something similar, also for the "run_ioctls" arg - maybe BTRFS_SCAN_REGISTER etc? btrfs_scan_one_dir("/dev/", BTRFS_SCAN_REGISTER, BTRFS_SCAN_PRIMARY_SB) is clearer than: btrfs_scan_one_dir("/dev/", 1, 0); Or maybe a flags var: flags = BTRFS_SCAN_REGISTER | BTRFS_SCAN_PRIMARY_SB; btrfs_scan_one_dir("/dev/", flags) Or, depending on how things get called, maybe self-named wrappers: btrfs_scan_one_dir_primary("/dev"); I think anything is better than a string of 0''s & 1''s :) -Eric -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Zach Brown
2013-Mar-01 18:27 UTC
Re: [PATCH] btrfs-progs: traverse to backup super-block only when indicated
On Fri, Mar 01, 2013 at 06:13:20PM +0800, Anand Jain wrote:> This patch adds 4th parameter to btrfs_scan_one_device() > which when set to non-zero value will traverse to check > backup super-block.Cool, thanks for working on this. How''d you decide which callers wanted to scan the backups and which didn''t? Where are the options to force checking the backups? This should be discussed in the commit message.> for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { > + if (i > 0 && !rd_sb_mirror) > + break;FWIW, I probably would have done something like max = rd_sb_mirror ? BTRFS_SUPER_MIRROR_MAX : 1; for (i = 0; i < max; i++) {> - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) > + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1, 0)))I agree with Eric. The ", 1, 0" isn''t great. I guess I''d go for flags (SCAN_REGISTER|SCAN_BACKUPS), but don''t feel strongly about it. Whatever feels least gross to you ;). - z -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-04 05:20 UTC
Re: [PATCH] btrfs-progs: traverse to backup super-block only when indicated
> flags = BTRFS_SCAN_REGISTER | BTRFS_SCAN_PRIMARY_SB; > btrfs_scan_one_dir("/dev/", flags)I just got too flexed into the current way of coding in btrfs-progs :-) But let me get at least this part of the code in the right-way. Thanks Eric for pointing out. -Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
The bug as seen in the last patch below, indicates that we need a mechanisum to tell when to use the backup super_block. To do this it needs a frame-work, and the patch #1 and #2 below provides the same without change in the logic. The last patch uses the framework to fix the bug. v1->v2: Accepts Eric and Zach review. Seprates fix into 3 patches for easy logical understanding Anand Jain (3): btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device btrfsctl.c | 2 +- cmds-device.c | 5 +++-- cmds-filesystem.c | 2 +- cmds-replace.c | 3 ++- disk-io.c | 16 +++++++++++----- disk-io.h | 3 ++- find-root.c | 9 ++++++--- utils.c | 26 +++++++++++++++----------- utils.h | 8 +++++--- volumes.c | 6 ++++-- volumes.h | 2 +- 11 files changed, 51 insertions(+), 31 deletions(-) -- 1.8.1.191.g414c78c -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-08 15:24 UTC
[PATCH 1/3] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
Introduce flag BTRFS_SCAN_REGISTER to replace the parameter run_ioctl which controls calling the function btrfs_register_one_device(). Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfsctl.c | 2 +- cmds-device.c | 4 ++-- disk-io.c | 3 ++- find-root.c | 3 ++- utils.c | 17 +++++++++-------- utils.h | 7 ++++--- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/btrfsctl.c b/btrfsctl.c index 8fd8cc3..75bc52d 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -115,7 +115,7 @@ int main(int ac, char **av) if (ac == 2 && strcmp(av[1], "-a") == 0) { fprintf(stderr, "Scanning for Btrfs filesystems\n"); - btrfs_scan_one_dir("/dev", 1); + btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); exit(0); } for (i = 1; i < ac; i++) { diff --git a/cmds-device.c b/cmds-device.c index 58df6da..1b8f378 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -203,9 +203,9 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(1); + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else - ret = btrfs_scan_one_dir("/dev", 1); + ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; diff --git a/disk-io.c b/disk-io.c index 897d0cf..5197456 100644 --- a/disk-io.c +++ b/disk-io.c @@ -833,7 +833,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/find-root.c b/find-root.c index 20ff972..234daf4 100644 --- a/find-root.c +++ b/find-root.c @@ -110,7 +110,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/utils.c b/utils.c index 1813dda..feee572 100644 --- a/utils.c +++ b/utils.c @@ -840,7 +840,8 @@ int check_mounted_where(int fd, const char *file, char *where, int size, /* scan other devices */ if (is_btrfs && total_devs > 1) { - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, + BTRFS_SCAN_REGISTER))) return ret; } @@ -951,7 +952,7 @@ void btrfs_register_one_device(char *fname) close(fd); } -int btrfs_scan_one_dir(char *dirname, int run_ioctl) +int btrfs_scan_one_dir(char *dirname, u64 flags) { DIR *dirp = NULL; struct dirent *dirent; @@ -1032,7 +1033,7 @@ again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); @@ -1057,13 +1058,13 @@ fail: } int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls) + u64 flags) { int ret; - ret = btrfs_scan_block_devices(run_ioctls); + ret = btrfs_scan_block_devices(flags); if (ret) - ret = btrfs_scan_one_dir("/dev", run_ioctls); + ret = btrfs_scan_one_dir("/dev", flags); return ret; } @@ -1294,7 +1295,7 @@ int set_label(const char *btrfs_dev, const char *label) set_label_mounted(btrfs_dev, label); } -int btrfs_scan_block_devices(int run_ioctl) +int btrfs_scan_block_devices(u64 flags) { struct stat st; @@ -1361,7 +1362,7 @@ scan_again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); diff --git a/utils.h b/utils.h index 0b681ed..c4d0d00 100644 --- a/utils.h +++ b/utils.h @@ -22,6 +22,7 @@ #include "ctree.h" #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_SCAN_REGISTER (1ULL << 1) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, @@ -35,9 +36,9 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u64 block_count, u32 io_width, u32 io_align, u32 sectorsize); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls); + u64 flags); void btrfs_register_one_device(char *fname); -int btrfs_scan_one_dir(char *dirname, int run_ioctl); +int btrfs_scan_one_dir(char *dirname, u64 flags); int check_mounted(const char *devicename); int check_mounted_where(int fd, const char *file, char *where, int size, struct btrfs_fs_devices **fs_devices_mnt); @@ -45,7 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); int get_mountpt(char *dev, char *mntpt, size_t size); -int btrfs_scan_block_devices(int run_ioctl); +int btrfs_scan_block_devices(u64 flags); u64 parse_size(char *s); int open_file_or_dir(const char *fname); int get_device_info(int fd, u64 devid, -- 1.8.1.191.g414c78c -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-08 15:24 UTC
[PATCH 2/3] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
As of now btrfs_read_dev_super() reads the backup super block by default and calling function has no control. However in the following patch we would see that is undesirable. So with the flag BTRFS_SCAN_BACKUP_SB the calling function can now indicate if btrfs_read_dev_super should scan for the backup SB when primary SB fails. This patch just provides the frame-work, keeping all the logic in the code same with or without this patch. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 10 +++++++--- disk-io.h | 3 ++- find-root.c | 3 ++- utils.h | 1 + volumes.c | 4 +++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/disk-io.c b/disk-io.c index 5197456..33e7e78 100644 --- a/disk-io.c +++ b/disk-io.c @@ -877,7 +877,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fs_info->super_bytenr = sb_bytenr; disk_super = &fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + disk_super, sb_bytenr, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1100,7 +1101,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, + u64 flags) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; @@ -1109,6 +1111,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) int ret; u64 transid = 0; u64 bytenr; + int max; if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { ret = pread64(fd, &buf, sizeof(buf), sb_bytenr); @@ -1123,7 +1126,8 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) return 0; } - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + max = flags & BTRFS_SCAN_BACKUP_SB ? BTRFS_SUPER_MIRROR_MAX : 1; + for (i = 0; i < max; 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 ff87958..38c6b4f 100644 --- a/disk-io.h +++ b/disk-io.h @@ -59,7 +59,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, + u64 flags); 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/find-root.c b/find-root.c index 234daf4..c76de2b 100644 --- a/find-root.c +++ b/find-root.c @@ -150,7 +150,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; disk_super = &fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, BTRFS_SUPER_INFO_OFFSET); + disk_super, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.h b/utils.h index c4d0d00..4641ce3 100644 --- a/utils.h +++ b/utils.h @@ -23,6 +23,7 @@ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) #define BTRFS_SCAN_REGISTER (1ULL << 1) +#define BTRFS_SCAN_BACKUP_SB (1ULL << 2) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, diff --git a/volumes.c b/volumes.c index ca1b402..b6e3f29 100644 --- a/volumes.c +++ b/volumes.c @@ -29,6 +29,7 @@ #include "transaction.h" #include "print-tree.h" #include "volumes.h" +#include "utils.h" struct stripe { struct btrfs_device *dev; @@ -225,7 +226,8 @@ 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, + BTRFS_SCAN_BACKUP_SB); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.191.g414c78c -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-08 15:25 UTC
[PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device
bug: ------- mkfs.btrfs /dev/sdb -f && yes| mkfs.ext4 /dev/sdb && mount /dev/sdb /ext4 mkfs.btrfs -f /dev/sdc /dev/sdd (run twice) mkfs.btrfs -f /dev/sdc /dev/sdd :: ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy adding device /dev/sdd id 2 fs created label (null) on /dev/sdc nodesize 4096 leafsize 4096 sectorsize 4096 size 3.11GB -------- Since we run mkfs.btrfs twice above, there is already a stale btrfs when mkfs.btrfs is run for the 2nd time. which kicks in btrfs_scan_for_fsid() to perform a system-wide scan to find the stale btrfs''s partner (to check if that by any chance is mounted) which in process comes across /dev/sdb. Now when it finds /dev/sdb it finds that primary SB is not present and we need to stop him there. This is done by NOT setting BTRFS_SCAN_BACKUP_SB for the function btrfs_scan_for_fsid(). To ensure rest of the logic is unaffected, this patch will ensure BTRFS_SCAN_BACKUP_SB is set for all other places except at check_mounted_where(). Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 3 ++- cmds-filesystem.c | 2 +- cmds-replace.c | 3 ++- disk-io.c | 7 ++++--- find-root.c | 5 +++-- utils.c | 9 ++++++--- volumes.c | 4 ++-- volumes.h | 2 +- 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index 1b8f378..9447e7f 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -203,7 +203,8 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER| + BTRFS_SCAN_BACKUP_SB); else ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); if (ret){ diff --git a/cmds-filesystem.c b/cmds-filesystem.c index 2210020..d2e708d 100644 --- a/cmds-filesystem.c +++ b/cmds-filesystem.c @@ -257,7 +257,7 @@ static int cmd_show(int argc, char **argv) usage(cmd_show_usage); if(checklist) - ret = btrfs_scan_block_devices(0); + ret = btrfs_scan_block_devices(BTRFS_SCAN_BACKUP_SB); else ret = btrfs_scan_one_dir("/dev", 0); diff --git a/cmds-replace.c b/cmds-replace.c index 4cc32df..f6e1619 100644 --- a/cmds-replace.c +++ b/cmds-replace.c @@ -275,7 +275,8 @@ static int cmd_start_replace(int argc, char **argv) goto leave_with_error; } ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret >= 0 && !force_using_targetdev) { fprintf(stderr, "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", diff --git a/disk-io.c b/disk-io.c index 33e7e78..914b567 100644 --- a/disk-io.c +++ b/disk-io.c @@ -825,7 +825,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED); ret = btrfs_scan_one_device(fp, path, &fs_devices, - &total_devs, sb_bytenr); + &total_devs, sb_bytenr, + BTRFS_SCAN_BACKUP_SB); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", path); @@ -834,7 +835,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, if (total_devs != 1) { ret = btrfs_scan_for_fsid(fs_devices, total_devs, - BTRFS_SCAN_REGISTER); + BTRFS_SCAN_REGISTER|BTRFS_SCAN_BACKUP_SB); if (ret) goto out; } @@ -1102,7 +1103,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, } int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, - u64 flags) + u64 flags) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; diff --git a/find-root.c b/find-root.c index c76de2b..40cacf1 100644 --- a/find-root.c +++ b/find-root.c @@ -102,7 +102,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) u64 features; ret = btrfs_scan_one_device(fd, device, &fs_devices, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", device); @@ -111,7 +112,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) if (total_devs != 1) { ret = btrfs_scan_for_fsid(fs_devices, total_devs, - BTRFS_SCAN_REGISTER); + BTRFS_SCAN_REGISTER|BTRFS_SCAN_BACKUP_SB); if (ret) goto out; } diff --git a/utils.c b/utils.c index feee572..95dee29 100644 --- a/utils.c +++ b/utils.c @@ -835,7 +835,8 @@ 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, + BTRFS_SCAN_BACKUP_SB); is_btrfs = (ret >= 0); /* scan other devices */ @@ -1032,7 +1033,8 @@ again: } ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } @@ -1361,7 +1363,8 @@ scan_again: } ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + flags); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } diff --git a/volumes.c b/volumes.c index b6e3f29..e1795e3 100644 --- a/volumes.c +++ b/volumes.c @@ -212,7 +212,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, u64 flags) { struct btrfs_super_block *disk_super; char *buf; @@ -227,7 +227,7 @@ int btrfs_scan_one_device(int fd, const char *path, } disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, disk_super, super_offset, - BTRFS_SCAN_BACKUP_SB); + flags); if (ret < 0) { ret = -EIO; goto error_brelse; diff --git a/volumes.h b/volumes.h index 911f788..f87aa5b 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, u64 flags); int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len); int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree, struct btrfs_fs_devices *fs_devices); -- 1.8.1.191.g414c78c -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Mar-11 15:03 UTC
Re: [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device
On 3/8/13 9:25 AM, Anand Jain wrote:> bug: > ------- > mkfs.btrfs /dev/sdb -f && yes| mkfs.ext4 /dev/sdb && mount /dev/sdb /ext4 > mkfs.btrfs -f /dev/sdc /dev/sdd (run twice) > mkfs.btrfs -f /dev/sdc /dev/sdd > :: > ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy > ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy > adding device /dev/sdd id 2 > fs created label (null) on /dev/sdc > nodesize 4096 leafsize 4096 sectorsize 4096 size 3.11GB > -------- > > Since we run mkfs.btrfs twice above, there is already a stale > btrfs when mkfs.btrfs is run for the 2nd time. which kicks in > btrfs_scan_for_fsid() to perform a system-wide scan to find the > stale btrfs''s partner (to check if that by any chance is mounted) > which in process comes across /dev/sdb. Now when it finds > /dev/sdb it finds that primary SB is not present and we need > to stop him there. > This is done by NOT setting BTRFS_SCAN_BACKUP_SB for the function > btrfs_scan_for_fsid(). To ensure rest of the logic is unaffected, > this patch will ensure BTRFS_SCAN_BACKUP_SB is set for all other > places except at check_mounted_where().Thanks, this seems like progress in the right direction. But that means that many other paths will still scan backups, right? In the following case sdb1 is an ext4-mounted partition w/ a stale btrfs backup superblock present in the middle. # mount /dev/sdb1 /mnt/test # mount | grep sdb1 /dev/sdb1 on /mnt/test type ext4 (rw) # btrfs device scan /dev/sdb1 Scanning for Btrfs filesystems in ''/dev/sdb1'' ERROR: unable to scan the device ''/dev/sdb1'' - Device or resource busy Perhaps this is ok since we explicitly told it to scan an ext4-mounted device. [[But, then if I unmount it: # btrfs device scan /dev/sdb1 Scanning for Btrfs filesystems in ''/dev/sdb1'' ERROR: unable to scan the device ''/dev/sdb1'' - Invalid argument weird, not sure where that came from. :( Unrelated to this question though.]] Also: # btrfs filesystem show /dev/sdb1 Label: none uuid: a96ea6e6-d3d5-444d-9aaf-057ec579dffe Total devices 1 FS bytes used 28.00KB devid 1 size 4.00GB used 445.50MB path /dev/sdb1 whoa, ok, so it''s a currently mounted ext4 device, but filesystem show tells me it''s btrfs? How about this one: # mount /dev/sdb1 /mnt/test # mount | grep sdb1 /dev/sdb1 on /mnt/test type ext4 (rw) # btrfs check /dev/sdb1 Checking filesystem on /dev/sdb1 UUID: a96ea6e6-d3d5-444d-9aaf-057ec579dffe checking extents checking fs roots checking root refs found 28672 bytes used err is 0 total csum bytes: 0 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 22875 file data blocks allocated: 0 referenced 0 Btrfs v0.20-rc1-194-g3deeb4c So my mountged ext4 fs is also a perfectly consistent btrfs fs? and I think the list goes on. IMHO, nothing should be checking the backup superblocks unless explicitly told to. i.e. in e2fsprogs, e2fsck has: -b superblock Instead of using the normal superblock, use an alternative superblock specified by superblock. and debugfs has: -s superblock Causes the file system superblock to be read from the given block number, instead of using the primary superblock I think the backups need to be used for explicit recovery (and maybe to be checked once the primary has been confirmed) and never used during any normal operation, if the first one is found to be missing. -Eric> Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > cmds-device.c | 3 ++- > cmds-filesystem.c | 2 +- > cmds-replace.c | 3 ++- > disk-io.c | 7 ++++--- > find-root.c | 5 +++-- > utils.c | 9 ++++++--- > volumes.c | 4 ++-- > volumes.h | 2 +- > 8 files changed, 21 insertions(+), 14 deletions(-) > > diff --git a/cmds-device.c b/cmds-device.c > index 1b8f378..9447e7f 100644 > --- a/cmds-device.c > +++ b/cmds-device.c > @@ -203,7 +203,8 @@ static int cmd_scan_dev(int argc, char **argv) > > printf("Scanning for Btrfs filesystems\n"); > if(checklist) > - ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); > + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER| > + BTRFS_SCAN_BACKUP_SB); > else > ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); > if (ret){ > diff --git a/cmds-filesystem.c b/cmds-filesystem.c > index 2210020..d2e708d 100644 > --- a/cmds-filesystem.c > +++ b/cmds-filesystem.c > @@ -257,7 +257,7 @@ static int cmd_show(int argc, char **argv) > usage(cmd_show_usage); > > if(checklist) > - ret = btrfs_scan_block_devices(0); > + ret = btrfs_scan_block_devices(BTRFS_SCAN_BACKUP_SB); > else > ret = btrfs_scan_one_dir("/dev", 0); > > diff --git a/cmds-replace.c b/cmds-replace.c > index 4cc32df..f6e1619 100644 > --- a/cmds-replace.c > +++ b/cmds-replace.c > @@ -275,7 +275,8 @@ static int cmd_start_replace(int argc, char **argv) > goto leave_with_error; > } > ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, > - &total_devs, BTRFS_SUPER_INFO_OFFSET); > + &total_devs, BTRFS_SUPER_INFO_OFFSET, > + BTRFS_SCAN_BACKUP_SB); > if (ret >= 0 && !force_using_targetdev) { > fprintf(stderr, > "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", > diff --git a/disk-io.c b/disk-io.c > index 33e7e78..914b567 100644 > --- a/disk-io.c > +++ b/disk-io.c > @@ -825,7 +825,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, > posix_fadvise(fp, 0, 0, POSIX_FADV_DONTNEED); > > ret = btrfs_scan_one_device(fp, path, &fs_devices, > - &total_devs, sb_bytenr); > + &total_devs, sb_bytenr, > + BTRFS_SCAN_BACKUP_SB); > > if (ret) { > fprintf(stderr, "No valid Btrfs found on %s\n", path); > @@ -834,7 +835,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, > > if (total_devs != 1) { > ret = btrfs_scan_for_fsid(fs_devices, total_devs, > - BTRFS_SCAN_REGISTER); > + BTRFS_SCAN_REGISTER|BTRFS_SCAN_BACKUP_SB); > if (ret) > goto out; > } > @@ -1102,7 +1103,7 @@ struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr, > } > > int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, > - u64 flags) > + u64 flags) > { > u8 fsid[BTRFS_FSID_SIZE]; > int fsid_is_initialized = 0; > diff --git a/find-root.c b/find-root.c > index c76de2b..40cacf1 100644 > --- a/find-root.c > +++ b/find-root.c > @@ -102,7 +102,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) > u64 features; > > ret = btrfs_scan_one_device(fd, device, &fs_devices, > - &total_devs, BTRFS_SUPER_INFO_OFFSET); > + &total_devs, BTRFS_SUPER_INFO_OFFSET, > + BTRFS_SCAN_BACKUP_SB); > > if (ret) { > fprintf(stderr, "No valid Btrfs found on %s\n", device); > @@ -111,7 +112,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) > > if (total_devs != 1) { > ret = btrfs_scan_for_fsid(fs_devices, total_devs, > - BTRFS_SCAN_REGISTER); > + BTRFS_SCAN_REGISTER|BTRFS_SCAN_BACKUP_SB); > if (ret) > goto out; > } > diff --git a/utils.c b/utils.c > index feee572..95dee29 100644 > --- a/utils.c > +++ b/utils.c > @@ -835,7 +835,8 @@ 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, > + BTRFS_SCAN_BACKUP_SB); > is_btrfs = (ret >= 0); > > /* scan other devices */ > @@ -1032,7 +1033,8 @@ again: > } > ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, > &num_devices, > - BTRFS_SUPER_INFO_OFFSET); > + BTRFS_SUPER_INFO_OFFSET, > + BTRFS_SCAN_BACKUP_SB); > if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { > btrfs_register_one_device(fullpath); > } > @@ -1361,7 +1363,8 @@ scan_again: > } > ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, > &num_devices, > - BTRFS_SUPER_INFO_OFFSET); > + BTRFS_SUPER_INFO_OFFSET, > + flags); > if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { > btrfs_register_one_device(fullpath); > } > diff --git a/volumes.c b/volumes.c > index b6e3f29..e1795e3 100644 > --- a/volumes.c > +++ b/volumes.c > @@ -212,7 +212,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, u64 flags) > { > struct btrfs_super_block *disk_super; > char *buf; > @@ -227,7 +227,7 @@ int btrfs_scan_one_device(int fd, const char *path, > } > disk_super = (struct btrfs_super_block *)buf; > ret = btrfs_read_dev_super(fd, disk_super, super_offset, > - BTRFS_SCAN_BACKUP_SB); > + flags); > if (ret < 0) { > ret = -EIO; > goto error_brelse; > diff --git a/volumes.h b/volumes.h > index 911f788..f87aa5b 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, u64 flags); > int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len); > int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree, > struct btrfs_fs_devices *fs_devices); >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Mar-11 18:16 UTC
Re: [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device
On Mon, Mar 11, 2013 at 10:03:46AM -0500, Eric Sandeen wrote:> IMHO, nothing should be checking the backup superblocks unless explicitly > told to.That''s the whole point I believe. update the infrastructure, every SB access looks to the first copy unless told by command line options. david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
We need a mechanism to tell when to use the backup super_block. To do this it needs a frame-work, and the patch #1 and #2 below provides the same without change in the logic. The last patch uses the framework to fix the bug(s). v2->v3: Accepts David and Eric review, which would result in disabled access to backup-superblock by default. Dropped the patch [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device Introduced a new patch [PATCH 3/3] btrfs-progs: disable using backup superblock by default v1->v2: Accepts Eric and Zach review. Separates fix into 3 patches for easy logical understanding Anand Jain (3): btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super btrfs-progs: disable using backup superblock by default btrfsctl.c | 2 +- cmds-device.c | 4 ++-- disk-io.c | 13 +++++++++---- disk-io.h | 3 ++- find-root.c | 6 ++++-- utils.c | 17 +++++++++-------- utils.h | 8 +++++--- volumes.c | 4 +++- 8 files changed, 35 insertions(+), 22 deletions(-) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-13 11:44 UTC
[PATCH 1/3 v3] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
Introduce flag BTRFS_SCAN_REGISTER to replace the parameter run_ioctl which controls calling the function btrfs_register_one_device(). Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfsctl.c | 2 +- cmds-device.c | 4 ++-- disk-io.c | 3 ++- find-root.c | 3 ++- utils.c | 17 +++++++++-------- utils.h | 7 ++++--- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/btrfsctl.c b/btrfsctl.c index 8fd8cc3..75bc52d 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -115,7 +115,7 @@ int main(int ac, char **av) if (ac == 2 && strcmp(av[1], "-a") == 0) { fprintf(stderr, "Scanning for Btrfs filesystems\n"); - btrfs_scan_one_dir("/dev", 1); + btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); exit(0); } for (i = 1; i < ac; i++) { diff --git a/cmds-device.c b/cmds-device.c index 58df6da..1b8f378 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -203,9 +203,9 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(1); + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else - ret = btrfs_scan_one_dir("/dev", 1); + ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; diff --git a/disk-io.c b/disk-io.c index a9fd374..8205b3c 100644 --- a/disk-io.c +++ b/disk-io.c @@ -834,7 +834,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/find-root.c b/find-root.c index f99fb76..ca41447 100644 --- a/find-root.c +++ b/find-root.c @@ -110,7 +110,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/utils.c b/utils.c index f68436d..c29861b 100644 --- a/utils.c +++ b/utils.c @@ -840,7 +840,8 @@ int check_mounted_where(int fd, const char *file, char *where, int size, /* scan other devices */ if (is_btrfs && total_devs > 1) { - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, + BTRFS_SCAN_REGISTER))) return ret; } @@ -951,7 +952,7 @@ void btrfs_register_one_device(char *fname) close(fd); } -int btrfs_scan_one_dir(char *dirname, int run_ioctl) +int btrfs_scan_one_dir(char *dirname, u64 flags) { DIR *dirp = NULL; struct dirent *dirent; @@ -1032,7 +1033,7 @@ again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); @@ -1057,13 +1058,13 @@ fail: } int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls) + u64 flags) { int ret; - ret = btrfs_scan_block_devices(run_ioctls); + ret = btrfs_scan_block_devices(flags); if (ret) - ret = btrfs_scan_one_dir("/dev", run_ioctls); + ret = btrfs_scan_one_dir("/dev", flags); return ret; } @@ -1294,7 +1295,7 @@ int set_label(const char *btrfs_dev, const char *label) set_label_mounted(btrfs_dev, label); } -int btrfs_scan_block_devices(int run_ioctl) +int btrfs_scan_block_devices(u64 flags) { struct stat st; @@ -1361,7 +1362,7 @@ scan_again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); diff --git a/utils.h b/utils.h index 0b681ed..c4d0d00 100644 --- a/utils.h +++ b/utils.h @@ -22,6 +22,7 @@ #include "ctree.h" #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_SCAN_REGISTER (1ULL << 1) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, @@ -35,9 +36,9 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u64 block_count, u32 io_width, u32 io_align, u32 sectorsize); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls); + u64 flags); void btrfs_register_one_device(char *fname); -int btrfs_scan_one_dir(char *dirname, int run_ioctl); +int btrfs_scan_one_dir(char *dirname, u64 flags); int check_mounted(const char *devicename); int check_mounted_where(int fd, const char *file, char *where, int size, struct btrfs_fs_devices **fs_devices_mnt); @@ -45,7 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); int get_mountpt(char *dev, char *mntpt, size_t size); -int btrfs_scan_block_devices(int run_ioctl); +int btrfs_scan_block_devices(u64 flags); u64 parse_size(char *s); int open_file_or_dir(const char *fname); int get_device_info(int fd, u64 devid, -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-13 11:44 UTC
[PATCH 2/3 v3] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
As of now btrfs_read_dev_super() reads the backup super block by default and calling function has no control. However in the following patch we would see that is undesirable. So with the flag BTRFS_SCAN_BACKUP_SB the calling function can now indicate if btrfs_read_dev_super should scan for the backup SB when primary SB fails. This patch just provides the frame-work, keeping all the logic in the code same with or without this patch. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 10 +++++++--- disk-io.h | 3 ++- find-root.c | 3 ++- utils.h | 1 + volumes.c | 4 +++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/disk-io.c b/disk-io.c index 8205b3c..796394f 100644 --- a/disk-io.c +++ b/disk-io.c @@ -879,7 +879,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fs_info->super_bytenr = sb_bytenr; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + disk_super, sb_bytenr, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1102,7 +1103,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, + u64 flags) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; @@ -1111,6 +1113,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) int ret; u64 transid = 0; u64 bytenr; + int max; if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { ret = pread64(fd, &buf, sizeof(buf), sb_bytenr); @@ -1125,7 +1128,8 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) return 0; } - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + max = flags & BTRFS_SCAN_BACKUP_SB ? BTRFS_SUPER_MIRROR_MAX : 1; + for (i = 0; i < max; 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 ff87958..38c6b4f 100644 --- a/disk-io.h +++ b/disk-io.h @@ -59,7 +59,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, + u64 flags); 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/find-root.c b/find-root.c index ca41447..9be4fc7 100644 --- a/find-root.c +++ b/find-root.c @@ -150,7 +150,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, BTRFS_SUPER_INFO_OFFSET); + disk_super, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.h b/utils.h index c4d0d00..4641ce3 100644 --- a/utils.h +++ b/utils.h @@ -23,6 +23,7 @@ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) #define BTRFS_SCAN_REGISTER (1ULL << 1) +#define BTRFS_SCAN_BACKUP_SB (1ULL << 2) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, diff --git a/volumes.c b/volumes.c index 3e52d06..1a28cdd 100644 --- a/volumes.c +++ b/volumes.c @@ -29,6 +29,7 @@ #include "transaction.h" #include "print-tree.h" #include "volumes.h" +#include "utils.h" struct stripe { struct btrfs_device *dev; @@ -226,7 +227,8 @@ 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, + BTRFS_SCAN_BACKUP_SB); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-13 11:44 UTC
[PATCH 3/3 v3] btrfs-progs: disable using backup superblock by default
Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 2 +- find-root.c | 2 +- volumes.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/disk-io.c b/disk-io.c index 796394f..030f080 100644 --- a/disk-io.c +++ b/disk-io.c @@ -880,7 +880,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, disk_super, sb_bytenr, - BTRFS_SCAN_BACKUP_SB); + NULL); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/find-root.c b/find-root.c index 9be4fc7..b74cd1e 100644 --- a/find-root.c +++ b/find-root.c @@ -151,7 +151,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, BTRFS_SUPER_INFO_OFFSET, - BTRFS_SCAN_BACKUP_SB); + NULL); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/volumes.c b/volumes.c index 1a28cdd..dfd78fb 100644 --- a/volumes.c +++ b/volumes.c @@ -228,7 +228,7 @@ int btrfs_scan_one_device(int fd, const char *path, } disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, disk_super, super_offset, - BTRFS_SCAN_BACKUP_SB); + NULL); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-13 11:46 UTC
Re: [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device
Thanks Eric and David. I have sent out V3 patch-set which will disable access to backup super-block unless requested by the user. here below are some test cases and results before and after this fix.. which finds the patch works awesome. -------- the original problem which all this started.. mkfs.btrfs /dev/sdb -f && yes| mkfs.ext4 /dev/sdb && mount /dev/sdb /ext4 ~/before/mkfs.btrfs -f /dev/sdc /dev/sdd (run twice) ~/before/mkfs.btrfs -f /dev/sdc /dev/sdd :: ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy adding device /dev/sdd id 2 fs created label (null) on /dev/sdc nodesize 4096 leafsize 4096 sectorsize 4096 size 3.11GB after the fix. # mkfs.btrfs -f /dev/sdc /dev/sdd WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL WARNING! - see http://btrfs.wiki.kernel.org before using adding device /dev/sdd id 2 fs created label (null) on /dev/sdc nodesize 4096 leafsize 4096 sectorsize 4096 size 104.98GB Btrfs v0.20-rc1-238-g170881a-dirty ------------- # umount /ext4 # mkfs.btrfs /dev/sdb /dev/sdc -f && wipefs /dev/sdb There is an existing bug.. # ~/before/btrfs check /dev/sdc --repair enabling repair mode warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already Checking filesystem on /dev/sdc UUID: e03c477d-b696-46c1-bf79-43b8b8454f11 checking extents checking fs roots checking root refs btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. Aborted (core dumped) # and its still there even after this patch :-) # btrfs check /dev/sdc --repair enabling repair mode warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already Checking filesystem on /dev/sdc UUID: e03c477d-b696-46c1-bf79-43b8b8454f11 checking extents checking fs roots checking root refs btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. Aborted (core dumped) ------------------------- # mkfs.btrfs /dev/sdb /dev/sdc -f && yes|mkfs.ext4 /dev/sdb without the fix # ~/before/btrfs restore -o /dev/sdb ~/tmp ERROR: device scan failed ''/dev/sdb'' - Invalid argument ERROR: device scan failed ''/dev/sdb'' - Invalid argument Root objectid is 5 with the fix # btrfs restore -o /dev/sdb ~/tmp No valid Btrfs found on /dev/sdb Could not open root, trying backup super Root objectid is 5 now I say to use sb backup 1.. # btrfs restore -u 1 -o /dev/sdb ~/tmp Root objectid is 5 # echo $? 0 -------------- # mkfs.btrfs /dev/sdb /dev/sdc -f && yes|mkfs.ext4 /dev/sdb # ~/before/btrfs check /dev/sdc --repair enabling repair mode ERROR: device scan failed ''/dev/sdb'' - Invalid argument ERROR: device scan failed ''/dev/sdb'' - Invalid argument Checking filesystem on /dev/sdc UUID: 5dc5c663-eeea-4ec2-b8fe-170157f5d68d checking extents checking fs roots checking root refs found 28672 bytes used err is 0 total csum bytes: 0 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 22420 file data blocks allocated: 0 referenced 0 Btrfs v0.20-rc1-235-gdd21bc1 # mkfs.btrfs /dev/sdb /dev/sdc -f && yes|mkfs.ext4 /dev/sdb since now new code doesn''t read backup SB of devid1 it hits the earlier known bug. # btrfs check /dev/sdc --repair enabling repair mode warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already Checking filesystem on /dev/sdc UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 checking extents checking fs roots checking root refs btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. Aborted (core dumped) So user would need to fix the devid1 first. # btrfs check /dev/sdb --repair enabling repair mode No valid Btrfs found on /dev/sdb # btrfs check -s 1 /dev/sdb --repair using SB copy 1, bytenr 67108864 enabling repair mode Checking filesystem on /dev/sdb UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 checking extents checking fs roots checking root refs found 28672 bytes used err is 0 total csum bytes: 0 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 22420 file data blocks allocated: 0 referenced 0 Btrfs v0.20-rc1-238-g170881a-dirty # btrfs check /dev/sdc --repair enabling repair mode warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already Checking filesystem on /dev/sdc UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 checking extents checking fs roots checking root refs btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. Aborted (core dumped) Need to write back the backup SB to primary SB. IMO when -s 1 was given it had the chance to fix primary.. this can be fixed later. # ./btrfs-select-super -s 1 /dev/sdb using SB copy 1, bytenr 67108864 ERROR: device scan failed ''/dev/sdb'' - Invalid argument # btrfs check /dev/sdc --repair enabling repair mode Checking filesystem on /dev/sdc UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 checking extents checking fs roots checking root refs found 28672 bytes used err is 0 total csum bytes: 0 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 22420 file data blocks allocated: 0 referenced 0 Btrfs v0.20-rc1-238-g170881a-dirty --------------------------------------------------------------- I am not sure if I have a wipe -a working for btrfs, so I would clean using dd. # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024+64)) 8+0 records in 8+0 records out 8 bytes (8 B) copied, 0.000324503 s, 24.7 kB/s # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024*1024+64)) 8+0 records in 8+0 records out 8 bytes (8 B) copied, 0.000364635 s, 21.9 kB/s # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((256*1024*1024*1024+64)) dd: `/dev/sdb'': cannot seek: Invalid argument 0+0 records in 0+0 records out 0 bytes (0 B) copied, 0.000430846 s, 0.0 kB/s This behavior is same before and after the patch. # btrfs check /dev/sdb No valid Btrfs found on /dev/sdb # btrfs check /dev/sdb -s 1 using SB copy 1, bytenr 67108864 No valid Btrfs found on /dev/sdb # btrfs check /dev/sdb -s 2 using SB copy 2, bytenr 274877906944 No valid Btrfs found on /dev/sdb # ------------------------ # mkfs.btrfs /dev/sdb /dev/sdc -f && mount /dev/sdc /btrfs # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024+64)) # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024*1024+64)) # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((256*1024*1024*1024+64)) # mkfs.btrfs /dev/sdb WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL WARNING! - see http://btrfs.wiki.kernel.org before using /dev/sdb is mounted # umount /btrfs # mkfs.btrfs /dev/sdb WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL WARNING! - see http://btrfs.wiki.kernel.org before using /dev/sdb appears to contain an existing filesystem (btrfs). Use the -f option to force overwrite. # ------------------------- # mkfs.btrfs /dev/sdd /dev/sde -f WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL WARNING! - see http://btrfs.wiki.kernel.org before using adding device /dev/sde id 2 fs created label (null) on /dev/sdd nodesize 4096 leafsize 4096 sectorsize 4096 size 93.22GB Btrfs v0.20-rc1-238-g170881a-dirty # mount /dev/sde /btrfs # umount /btrfs # dd if=/dev/zero bs=1 count=8 of=/dev/sde seek=$((64*1024+64)) 8+0 records in 8+0 records out 8 bytes (8 B) copied, 0.0149415 s, 0.5 kB/s remove /dev/sdd # x="0 0 3 0" # echo "scsi remove-single-device $x" > /proc/scsi/scsi # lsscsi [0:0:0:0] disk Sun boot1 V1.0 /dev/sda [0:0:2:0] disk Sun boot3 V1.0 /dev/sdc [0:0:4:0] disk Sun boot5 V1.0 /dev/sde [0:1:0:0] disk SEAGATE ST914602SSUN146G 0603 - [0:1:1:0] disk SEAGATE ST914602SSUN146G 0603 - [0:3:0:0] enclosu ADAPTEC Virtual SGPIO 0 0001 - # btrfs check /dev/sde No valid Btrfs found on /dev/sde # btrfs check /dev/sde -s 1 using SB copy 1, bytenr 67108864 warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already Checking filesystem on /dev/sde UUID: fa08122d-832f-4f32-87ee-58eb9380d5da checking extents checking fs roots checking root refs found 815104 bytes used err is 0 total csum bytes: 0 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 21476 file data blocks allocated: 786432 referenced 786432 Btrfs v0.20-rc1-238-g170881a-dirty # ./btrfs-select-super -s 1 /dev/sde using SB copy 1, bytenr 67108864 ERROR: device scan failed ''/dev/sdc'' - Invalid argument warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already # btrfs check /dev/sde warning, device 1 is missing warning, device 1 is missing warning devid 1 not found already Checking filesystem on /dev/sde UUID: fa08122d-832f-4f32-87ee-58eb9380d5da checking extents checking fs roots checking root refs found 815104 bytes used err is 0 total csum bytes: 0 total tree bytes: 28672 total fs tree bytes: 8192 btree space waste bytes: 21476 file data blocks allocated: 786432 referenced 786432 Btrfs v0.20-rc1-238-g170881a-dirty # --------------- Thanks, Anand On 03/12/2013 02:16 AM, David Sterba wrote:> On Mon, Mar 11, 2013 at 10:03:46AM -0500, Eric Sandeen wrote: >> IMHO, nothing should be checking the backup superblocks unless explicitly >> told to. > > That''s the whole point I believe. > > update the infrastructure, every SB access looks to the first copy > unless told by command line options. > > > david > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
We need a mechanism to tell when to use the backup super_block. To do this it needs a frame-work, and the patch #1 and #2 below provides the same without change in the logic. The last patch uses the framework to fix the bug(s). v3->v4: Fixed some warnings introduced by patch #3 below, sorry my mistake. v2->v3: Accepts David and Eric review, which would result in disabled access to backup-superblock by default. Dropped the patch [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device Introduced a new patch [PATCH 3/3] btrfs-progs: disable using backup superblock by default v1->v2: Accepts Eric and Zach review. Separates fix into 3 patches for easy logical understanding Anand Jain (3): btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super btrfs-progs: disable using backup superblock by default btrfsctl.c | 2 +- cmds-device.c | 4 ++-- disk-io.c | 13 +++++++++---- disk-io.h | 3 ++- find-root.c | 6 ++++-- utils.c | 17 +++++++++-------- utils.h | 8 +++++--- volumes.c | 4 +++- 8 files changed, 35 insertions(+), 22 deletions(-) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-14 03:05 UTC
[PATCH 1/3 v4] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
Introduce flag BTRFS_SCAN_REGISTER to replace the parameter run_ioctl which controls calling the function btrfs_register_one_device(). Signed-off-by: Anand Jain <anand.jain@oracle.com> --- btrfsctl.c | 2 +- cmds-device.c | 4 ++-- disk-io.c | 3 ++- find-root.c | 3 ++- utils.c | 17 +++++++++-------- utils.h | 7 ++++--- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/btrfsctl.c b/btrfsctl.c index 8fd8cc3..75bc52d 100644 --- a/btrfsctl.c +++ b/btrfsctl.c @@ -115,7 +115,7 @@ int main(int ac, char **av) if (ac == 2 && strcmp(av[1], "-a") == 0) { fprintf(stderr, "Scanning for Btrfs filesystems\n"); - btrfs_scan_one_dir("/dev", 1); + btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); exit(0); } for (i = 1; i < ac; i++) { diff --git a/cmds-device.c b/cmds-device.c index 58df6da..1b8f378 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -203,9 +203,9 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(1); + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else - ret = btrfs_scan_one_dir("/dev", 1); + ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; diff --git a/disk-io.c b/disk-io.c index a9fd374..8205b3c 100644 --- a/disk-io.c +++ b/disk-io.c @@ -834,7 +834,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/find-root.c b/find-root.c index f99fb76..ca41447 100644 --- a/find-root.c +++ b/find-root.c @@ -110,7 +110,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/utils.c b/utils.c index f68436d..c29861b 100644 --- a/utils.c +++ b/utils.c @@ -840,7 +840,8 @@ int check_mounted_where(int fd, const char *file, char *where, int size, /* scan other devices */ if (is_btrfs && total_devs > 1) { - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, + BTRFS_SCAN_REGISTER))) return ret; } @@ -951,7 +952,7 @@ void btrfs_register_one_device(char *fname) close(fd); } -int btrfs_scan_one_dir(char *dirname, int run_ioctl) +int btrfs_scan_one_dir(char *dirname, u64 flags) { DIR *dirp = NULL; struct dirent *dirent; @@ -1032,7 +1033,7 @@ again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); @@ -1057,13 +1058,13 @@ fail: } int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls) + u64 flags) { int ret; - ret = btrfs_scan_block_devices(run_ioctls); + ret = btrfs_scan_block_devices(flags); if (ret) - ret = btrfs_scan_one_dir("/dev", run_ioctls); + ret = btrfs_scan_one_dir("/dev", flags); return ret; } @@ -1294,7 +1295,7 @@ int set_label(const char *btrfs_dev, const char *label) set_label_mounted(btrfs_dev, label); } -int btrfs_scan_block_devices(int run_ioctl) +int btrfs_scan_block_devices(u64 flags) { struct stat st; @@ -1361,7 +1362,7 @@ scan_again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); diff --git a/utils.h b/utils.h index 0b681ed..c4d0d00 100644 --- a/utils.h +++ b/utils.h @@ -22,6 +22,7 @@ #include "ctree.h" #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_SCAN_REGISTER (1ULL << 1) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, @@ -35,9 +36,9 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u64 block_count, u32 io_width, u32 io_align, u32 sectorsize); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls); + u64 flags); void btrfs_register_one_device(char *fname); -int btrfs_scan_one_dir(char *dirname, int run_ioctl); +int btrfs_scan_one_dir(char *dirname, u64 flags); int check_mounted(const char *devicename); int check_mounted_where(int fd, const char *file, char *where, int size, struct btrfs_fs_devices **fs_devices_mnt); @@ -45,7 +46,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); int get_mountpt(char *dev, char *mntpt, size_t size); -int btrfs_scan_block_devices(int run_ioctl); +int btrfs_scan_block_devices(u64 flags); u64 parse_size(char *s); int open_file_or_dir(const char *fname); int get_device_info(int fd, u64 devid, -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-14 03:05 UTC
[PATCH 2/3 v4] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
As of now btrfs_read_dev_super() reads the backup super block by default and calling function has no control. However in the following patch we would see that is undesirable. So with the flag BTRFS_SCAN_BACKUP_SB the calling function can now indicate if btrfs_read_dev_super should scan for the backup SB when primary SB fails. This patch just provides the frame-work, keeping all the logic in the code same with or without this patch. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 10 +++++++--- disk-io.h | 3 ++- find-root.c | 3 ++- utils.h | 1 + volumes.c | 4 +++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/disk-io.c b/disk-io.c index 8205b3c..796394f 100644 --- a/disk-io.c +++ b/disk-io.c @@ -879,7 +879,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fs_info->super_bytenr = sb_bytenr; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + disk_super, sb_bytenr, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1102,7 +1103,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, + u64 flags) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; @@ -1111,6 +1113,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) int ret; u64 transid = 0; u64 bytenr; + int max; if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { ret = pread64(fd, &buf, sizeof(buf), sb_bytenr); @@ -1125,7 +1128,8 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) return 0; } - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + max = flags & BTRFS_SCAN_BACKUP_SB ? BTRFS_SUPER_MIRROR_MAX : 1; + for (i = 0; i < max; 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 ff87958..38c6b4f 100644 --- a/disk-io.h +++ b/disk-io.h @@ -59,7 +59,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, + u64 flags); 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/find-root.c b/find-root.c index ca41447..9be4fc7 100644 --- a/find-root.c +++ b/find-root.c @@ -150,7 +150,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, BTRFS_SUPER_INFO_OFFSET); + disk_super, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.h b/utils.h index c4d0d00..4641ce3 100644 --- a/utils.h +++ b/utils.h @@ -23,6 +23,7 @@ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) #define BTRFS_SCAN_REGISTER (1ULL << 1) +#define BTRFS_SCAN_BACKUP_SB (1ULL << 2) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, diff --git a/volumes.c b/volumes.c index 3e52d06..1a28cdd 100644 --- a/volumes.c +++ b/volumes.c @@ -29,6 +29,7 @@ #include "transaction.h" #include "print-tree.h" #include "volumes.h" +#include "utils.h" struct stripe { struct btrfs_device *dev; @@ -226,7 +227,8 @@ 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, + BTRFS_SCAN_BACKUP_SB); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-14 03:05 UTC
[PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 2 +- find-root.c | 2 +- volumes.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/disk-io.c b/disk-io.c index 796394f..c2e1c8a 100644 --- a/disk-io.c +++ b/disk-io.c @@ -880,7 +880,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, disk_super, sb_bytenr, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/find-root.c b/find-root.c index 9be4fc7..9923209 100644 --- a/find-root.c +++ b/find-root.c @@ -151,7 +151,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, BTRFS_SUPER_INFO_OFFSET, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/volumes.c b/volumes.c index 1a28cdd..9003412 100644 --- a/volumes.c +++ b/volumes.c @@ -228,7 +228,7 @@ int btrfs_scan_one_device(int fd, const char *path, } disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, disk_super, super_offset, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Mar-14 04:36 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
On 3/13/13 10:05 PM, Anand Jain wrote: <maybe a little more commit log would be good?> So here is what confuses me now. :) *every* caller of btrfs_read_dev_super() is now called with 0 for the flags variable, so it never reads the backup under any circumstance. If it''s always called w/ 0, what is the point of the argument? Is there another patch you have planned that would use this argument later? -Eric> Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > disk-io.c | 2 +- > find-root.c | 2 +- > volumes.c | 2 +- > 3 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/disk-io.c b/disk-io.c > index 796394f..c2e1c8a 100644 > --- a/disk-io.c > +++ b/disk-io.c > @@ -880,7 +880,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, > disk_super = fs_info->super_copy; > ret =(fs_devices->latest_bdev,> disk_super, sb_bytenr, > - BTRFS_SCAN_BACKUP_SB); > + 0ull);Isn''t just "0" enough? -Eric> if (ret) { > printk("No valid btrfs found\n"); > goto out_devices; > diff --git a/find-root.c b/find-root.c > index 9be4fc7..9923209 100644 > --- a/find-root.c > +++ b/find-root.c > @@ -151,7 +151,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, BTRFS_SUPER_INFO_OFFSET, > - BTRFS_SCAN_BACKUP_SB); > + 0ull); > if (ret) { > printk("No valid btrfs found\n"); > goto out_devices; > diff --git a/volumes.c b/volumes.c > index 1a28cdd..9003412 100644 > --- a/volumes.c > +++ b/volumes.c > @@ -228,7 +228,7 @@ int btrfs_scan_one_device(int fd, const char *path, > } > disk_super = (struct btrfs_super_block *)buf; > ret = btrfs_read_dev_super(fd, disk_super, super_offset, > - BTRFS_SCAN_BACKUP_SB); > + 0ull); > if (ret < 0) { > ret = -EIO; > goto error_brelse; >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-14 08:51 UTC
Re: [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device
just for the record, this patch also fixes the following 2 issues.. sdc contains primary-SB of ext4 and backup SB of btrfs # blkid /dev/sdc /dev/sdc: UUID="4450e281-db04-4736-a03e-1ce6deda74f3" TYPE="ext4" # # btrfs-show-super -i 1 /dev/sdc superblock: bytenr=67108864, device=/dev/sdc :: ---- # ~/before/btrfs dev scan Scanning for Btrfs filesystems ERROR: device scan failed ''/dev/sdc'' - Invalid argument # btrfs dev scan Scanning for Btrfs filesystems ---- ----- # ~/before/btrfs fi show :: Label: none uuid: aa8b3f0c-3ade-490a-a35d-dd62dbd9cc07 Total devices 2 FS bytes used 796.00KB devid 2 size 59.99GB used 2.01GB path /dev/sdc *** Some devices missing :: Btrfs v0.20-rc1-235-gdd21bc1 # # btrfs fi show Label: none uuid: 0d690e00-a34f-4c6b-9660-c6b1b6684ecc Total devices 1 FS bytes used 28.00KB devid 1 size 59.99GB used 2.04GB path /dev/sdb Label: none uuid: fa08122d-832f-4f32-87ee-58eb9380d5da Total devices 2 FS bytes used 796.00KB devid 2 size 48.23GB used 2.01GB path /dev/sde devid 1 size 44.99GB used 2.03GB path /dev/sdd Btrfs v0.20-rc1-238-g5d571b4-dirty ----- Thanks, Anand On 03/13/2013 07:46 PM, Anand Jain wrote:> > > Thanks Eric and David. > > I have sent out V3 patch-set which will disable access > to backup super-block unless requested by the user. > > here below are some test cases and results before and > after this fix.. which finds the patch works awesome. > > > -------- > the original problem which all this started.. > > mkfs.btrfs /dev/sdb -f && yes| mkfs.ext4 /dev/sdb && mount /dev/sdb /ext4 > ~/before/mkfs.btrfs -f /dev/sdc /dev/sdd (run twice) > ~/before/mkfs.btrfs -f /dev/sdc /dev/sdd > :: > ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy > ERROR: unable to scan the device ''/dev/sdb'' - Device or resource busy > adding device /dev/sdd id 2 > fs created label (null) on /dev/sdc > nodesize 4096 leafsize 4096 sectorsize 4096 size 3.11GB > > > after the fix. > > # mkfs.btrfs -f /dev/sdc /dev/sdd > > WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL > WARNING! - see http://btrfs.wiki.kernel.org before using > > adding device /dev/sdd id 2 > fs created label (null) on /dev/sdc > nodesize 4096 leafsize 4096 sectorsize 4096 size 104.98GB > Btrfs v0.20-rc1-238-g170881a-dirty > ------------- > > # umount /ext4 > > # mkfs.btrfs /dev/sdb /dev/sdc -f && wipefs /dev/sdb > > There is an existing bug.. > > # ~/before/btrfs check /dev/sdc --repair > enabling repair mode > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > Checking filesystem on /dev/sdc > UUID: e03c477d-b696-46c1-bf79-43b8b8454f11 > checking extents > checking fs roots > checking root refs > btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. > Aborted (core dumped) > # > > and its still there even after this patch :-) > > # btrfs check /dev/sdc --repair > enabling repair mode > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > Checking filesystem on /dev/sdc > UUID: e03c477d-b696-46c1-bf79-43b8b8454f11 > checking extents > checking fs roots > checking root refs > btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. > Aborted (core dumped) > > ------------------------- > > > # mkfs.btrfs /dev/sdb /dev/sdc -f && yes|mkfs.ext4 /dev/sdb > > without the fix > # ~/before/btrfs restore -o /dev/sdb ~/tmp > ERROR: device scan failed ''/dev/sdb'' - Invalid argument > ERROR: device scan failed ''/dev/sdb'' - Invalid argument > Root objectid is 5 > > with the fix > > # btrfs restore -o /dev/sdb ~/tmp > No valid Btrfs found on /dev/sdb > Could not open root, trying backup super > Root objectid is 5 > > now I say to use sb backup 1.. > > # btrfs restore -u 1 -o /dev/sdb ~/tmp > Root objectid is 5 > # echo $? > 0 > > -------------- > > # mkfs.btrfs /dev/sdb /dev/sdc -f && yes|mkfs.ext4 /dev/sdb > > # ~/before/btrfs check /dev/sdc --repair > enabling repair mode > ERROR: device scan failed ''/dev/sdb'' - Invalid argument > ERROR: device scan failed ''/dev/sdb'' - Invalid argument > Checking filesystem on /dev/sdc > UUID: 5dc5c663-eeea-4ec2-b8fe-170157f5d68d > checking extents > checking fs roots > checking root refs > found 28672 bytes used err is 0 > total csum bytes: 0 > total tree bytes: 28672 > total fs tree bytes: 8192 > btree space waste bytes: 22420 > file data blocks allocated: 0 > referenced 0 > Btrfs v0.20-rc1-235-gdd21bc1 > > # mkfs.btrfs /dev/sdb /dev/sdc -f && yes|mkfs.ext4 /dev/sdb > > since now new code doesn''t read backup SB of devid1 > it hits the earlier known bug. > > # btrfs check /dev/sdc --repair > enabling repair mode > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > Checking filesystem on /dev/sdc > UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 > checking extents > checking fs roots > checking root refs > btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. > Aborted (core dumped) > > So user would need to fix the devid1 first. > > # btrfs check /dev/sdb --repair > enabling repair mode > No valid Btrfs found on /dev/sdb > > # btrfs check -s 1 /dev/sdb --repair > using SB copy 1, bytenr 67108864 > enabling repair mode > Checking filesystem on /dev/sdb > UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 > checking extents > checking fs roots > checking root refs > found 28672 bytes used err is 0 > total csum bytes: 0 > total tree bytes: 28672 > total fs tree bytes: 8192 > btree space waste bytes: 22420 > file data blocks allocated: 0 > referenced 0 > Btrfs v0.20-rc1-238-g170881a-dirty > > # btrfs check /dev/sdc --repair > enabling repair mode > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > Checking filesystem on /dev/sdc > UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 > checking extents > checking fs roots > checking root refs > btrfs: extent-tree.c:2553: btrfs_reserve_extent: Assertion `!(ret)'' failed. > Aborted (core dumped) > > Need to write back the backup SB to primary SB. > IMO when -s 1 was given it had the chance to fix > primary.. this can be fixed later. > > # ./btrfs-select-super -s 1 /dev/sdb > using SB copy 1, bytenr 67108864 > ERROR: device scan failed ''/dev/sdb'' - Invalid argument > > # btrfs check /dev/sdc --repair > enabling repair mode > Checking filesystem on /dev/sdc > UUID: daa0dc6d-35b6-43ab-8333-894710a5b917 > checking extents > checking fs roots > checking root refs > found 28672 bytes used err is 0 > total csum bytes: 0 > total tree bytes: 28672 > total fs tree bytes: 8192 > btree space waste bytes: 22420 > file data blocks allocated: 0 > referenced 0 > Btrfs v0.20-rc1-238-g170881a-dirty > --------------------------------------------------------------- > > > I am not sure if I have a wipe -a working for btrfs, > so I would clean using dd. > > # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024+64)) > 8+0 records in > 8+0 records out > 8 bytes (8 B) copied, 0.000324503 s, 24.7 kB/s > > # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024*1024+64)) > 8+0 records in > 8+0 records out > 8 bytes (8 B) copied, 0.000364635 s, 21.9 kB/s > > # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((256*1024*1024*1024+64)) > dd: `/dev/sdb'': cannot seek: Invalid argument > 0+0 records in > 0+0 records out > 0 bytes (0 B) copied, 0.000430846 s, 0.0 kB/s > > This behavior is same before and after the patch. > > # btrfs check /dev/sdb > No valid Btrfs found on /dev/sdb > # btrfs check /dev/sdb -s 1 > using SB copy 1, bytenr 67108864 > No valid Btrfs found on /dev/sdb > # btrfs check /dev/sdb -s 2 > using SB copy 2, bytenr 274877906944 > No valid Btrfs found on /dev/sdb > # > ------------------------ > > # mkfs.btrfs /dev/sdb /dev/sdc -f && mount /dev/sdc /btrfs > > # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024+64)) > # dd if=/dev/zero bs=1 count=8 of=/dev/sdb seek=$((64*1024*1024+64)) > # dd if=/dev/zero bs=1 count=8 of=/dev/sdb > seek=$((256*1024*1024*1024+64)) > > # mkfs.btrfs /dev/sdb > > WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL > WARNING! - see http://btrfs.wiki.kernel.org before using > > /dev/sdb is mounted > > > # umount /btrfs > > # mkfs.btrfs /dev/sdb > > WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL > WARNING! - see http://btrfs.wiki.kernel.org before using > > /dev/sdb appears to contain an existing filesystem (btrfs). > Use the -f option to force overwrite. > # > > ------------------------- > > > # mkfs.btrfs /dev/sdd /dev/sde -f > > WARNING! - Btrfs v0.20-rc1-238-g170881a-dirty IS EXPERIMENTAL > WARNING! - see http://btrfs.wiki.kernel.org before using > > adding device /dev/sde id 2 > fs created label (null) on /dev/sdd > nodesize 4096 leafsize 4096 sectorsize 4096 size 93.22GB > Btrfs v0.20-rc1-238-g170881a-dirty > # mount /dev/sde /btrfs > # umount /btrfs > # dd if=/dev/zero bs=1 count=8 of=/dev/sde seek=$((64*1024+64)) > 8+0 records in > 8+0 records out > 8 bytes (8 B) copied, 0.0149415 s, 0.5 kB/s > > remove /dev/sdd > > # x="0 0 3 0" > # echo "scsi remove-single-device $x" > /proc/scsi/scsi > # lsscsi > [0:0:0:0] disk Sun boot1 V1.0 /dev/sda > [0:0:2:0] disk Sun boot3 V1.0 /dev/sdc > [0:0:4:0] disk Sun boot5 V1.0 /dev/sde > [0:1:0:0] disk SEAGATE ST914602SSUN146G 0603 - > [0:1:1:0] disk SEAGATE ST914602SSUN146G 0603 - > [0:3:0:0] enclosu ADAPTEC Virtual SGPIO 0 0001 - > > > # btrfs check /dev/sde > No valid Btrfs found on /dev/sde > > # btrfs check /dev/sde -s 1 > using SB copy 1, bytenr 67108864 > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > Checking filesystem on /dev/sde > UUID: fa08122d-832f-4f32-87ee-58eb9380d5da > checking extents > checking fs roots > checking root refs > found 815104 bytes used err is 0 > total csum bytes: 0 > total tree bytes: 28672 > total fs tree bytes: 8192 > btree space waste bytes: 21476 > file data blocks allocated: 786432 > referenced 786432 > Btrfs v0.20-rc1-238-g170881a-dirty > > # ./btrfs-select-super -s 1 /dev/sde > using SB copy 1, bytenr 67108864 > ERROR: device scan failed ''/dev/sdc'' - Invalid argument > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > > # btrfs check /dev/sde > warning, device 1 is missing > warning, device 1 is missing > warning devid 1 not found already > Checking filesystem on /dev/sde > UUID: fa08122d-832f-4f32-87ee-58eb9380d5da > checking extents > checking fs roots > checking root refs > found 815104 bytes used err is 0 > total csum bytes: 0 > total tree bytes: 28672 > total fs tree bytes: 8192 > btree space waste bytes: 21476 > file data blocks allocated: 786432 > referenced 786432 > Btrfs v0.20-rc1-238-g170881a-dirty > # > --------------- > > > Thanks, Anand > > > On 03/12/2013 02:16 AM, David Sterba wrote: >> On Mon, Mar 11, 2013 at 10:03:46AM -0500, Eric Sandeen wrote: >>> IMHO, nothing should be checking the backup superblocks unless >>> explicitly >>> told to. >> >> That''s the whole point I believe. >> >> update the infrastructure, every SB access looks to the first copy >> unless told by command line options. >> >> >> david >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-14 08:56 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
On 03/14/2013 12:36 PM, Eric Sandeen wrote:> On 3/13/13 10:05 PM, Anand Jain wrote: > > <maybe a little more commit log would be good?> > > So here is what confuses me now. :) > > *every* caller of btrfs_read_dev_super() is now called with > 0 for the flags variable, so it never reads the backup > under any circumstance. > > If it''s always called w/ 0, what is the point of the argument? > Is there another patch you have planned that would use this argument > later?Thanks for the review. yes true. as of now it (BTRFS_SCAN_BACKUP_SB) only serves the purpose if in future should we need it. purpose is something like a user initiated thread which should to go to the backup-SB if primary-SB is not found ?. Or I can drop BTRFS_SCAN_BACKUP_SB idea depending on how it is convenient as a whole. Thanks, Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Mar-14 14:47 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
On 3/14/13 3:56 AM, Anand Jain wrote:> > > On 03/14/2013 12:36 PM, Eric Sandeen wrote: >> On 3/13/13 10:05 PM, Anand Jain wrote: >> >> <maybe a little more commit log would be good?> >> >> So here is what confuses me now. :) >> >> *every* caller of btrfs_read_dev_super() is now called with >> 0 for the flags variable, so it never reads the backup >> under any circumstance. >> >> If it''s always called w/ 0, what is the point of the argument? >> Is there another patch you have planned that would use this argument >> later? > > Thanks for the review. yes true. as of now it (BTRFS_SCAN_BACKUP_SB) > only serves the purpose if in future should we need it. > purpose is something like a user initiated thread which > should to go to the backup-SB if primary-SB is not found ?. > Or I can drop BTRFS_SCAN_BACKUP_SB idea depending on how > it is convenient as a whole.See what others think, perhaps, but if nobody is using it, I think it should just go away. I''d call it "dead code." :) But I am surprised that none of the commands which accept alternate superblock locations find their way into btrfs_read_dev_super() - that seems odd to me. Is it re-implemented or open-coded in other places? -Eric> Thanks, Anand > >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Mar-14 14:49 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
On 3/14/13 9:47 AM, Eric Sandeen wrote:> On 3/14/13 3:56 AM, Anand Jain wrote: >> >> >> On 03/14/2013 12:36 PM, Eric Sandeen wrote: >>> On 3/13/13 10:05 PM, Anand Jain wrote: >>> >>> <maybe a little more commit log would be good?> >>> >>> So here is what confuses me now. :) >>> >>> *every* caller of btrfs_read_dev_super() is now called with >>> 0 for the flags variable, so it never reads the backup >>> under any circumstance. >>> >>> If it''s always called w/ 0, what is the point of the argument? >>> Is there another patch you have planned that would use this argument >>> later? >> >> Thanks for the review. yes true. as of now it (BTRFS_SCAN_BACKUP_SB) >> only serves the purpose if in future should we need it. >> purpose is something like a user initiated thread which >> should to go to the backup-SB if primary-SB is not found ?. >> Or I can drop BTRFS_SCAN_BACKUP_SB idea depending on how >> it is convenient as a whole. > > See what others think, perhaps, but if nobody is using it, I think > it should just go away. I''d call it "dead code." :) > > But I am surprised that none of the commands which accept alternate > superblock locations find their way into btrfs_read_dev_super() - > that seems odd to me. Is it re-implemented or open-coded in other > places?So to be clearer, rather than removing the code right away, maybe it''s worth a look to see if the other commands which *want* backup superblocks should be using this same code. Then you''d have a reason for your new flag. :) -Eric> -Eric > > >> Thanks, Anand >> >>-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-15 12:03 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
>>>> <maybe a little more commit log would be good?> >>>> >>>> So here is what confuses me now. :) >>>> >>>> *every* caller of btrfs_read_dev_super() is now called with >>>> 0 for the flags variable, so it never reads the backup >>>> under any circumstance. >>>> >>>> If it''s always called w/ 0, what is the point of the argument? >>>> Is there another patch you have planned that would use this argument >>>> later? >>> >>> Thanks for the review. yes true. as of now it (BTRFS_SCAN_BACKUP_SB) >>> only serves the purpose if in future should we need it. >>> purpose is something like a user initiated thread which >>> should to go to the backup-SB if primary-SB is not found ?. >>> Or I can drop BTRFS_SCAN_BACKUP_SB idea depending on how >>> it is convenient as a whole. >> >> See what others think, perhaps, but if nobody is using it, I think >> it should just go away. I''d call it "dead code." :) >> >> But I am surprised that none of the commands which accept alternate >> superblock locations find their way into btrfs_read_dev_super() - >> that seems odd to me. Is it re-implemented or open-coded in other >> places? > > So to be clearer, rather than removing the code right away, maybe > it''s worth a look to see if the other commands which *want* backup > superblocks should be using this same code. Then you''d have a reason > for your new flag. :)when non primary SB (sb_bytenr) is specified in btrfs_read_dev_super() (that is when user is involved) it would directly fetch it. so its not a problem when we know which SB to read other than the primary SB. However when primary SB is specified it would look for only primary SB unless BTRFS_SCAN_BACKUP_SB flag is set (with the patch). Now, do we need this flag ? looks like Yes ! (sorry to change my opinion here though) and as below.. In some cases when user is _not_ involved. Like in check_mounted(). In a multi dev btrfs mounted fs. If by any chance the primary SB is corrupted then we would say the device is NOT mounted even if it is mounted. eg: # mkfs.btrfs /dev/sdb /dev/sdc -f && mount /dev/sdb /btrfs # ./check-mounted /dev/sdc its btrfs /dev/sdc is currently mounted. Aborting. # dd if=/dev/zero of=/dev/sdc count=8 seek=$(((64 * 1024)/512)) # ./check-mounted /dev/sdc Not mounted # cat /proc/mounts | egrep btrfs /dev/sdb /btrfs btrfs rw,seclabel,relatime,noacl,space_cache 0 0 So we have to set BTRFS_SCAN_BACKUP_SB for check_mounted() But the above scenario is not simple enough to be practical though. -Anand -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Eric Sandeen
2013-Mar-15 16:34 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
On 3/15/13 7:03 AM, Anand Jain wrote:> > >>>>> <maybe a little more commit log would be good?> >>>>> >>>>> So here is what confuses me now. :) >>>>> >>>>> *every* caller of btrfs_read_dev_super() is now called with >>>>> 0 for the flags variable, so it never reads the backup >>>>> under any circumstance. >>>>> >>>>> If it''s always called w/ 0, what is the point of the argument? >>>>> Is there another patch you have planned that would use this argument >>>>> later? >>>> >>>> Thanks for the review. yes true. as of now it (BTRFS_SCAN_BACKUP_SB) >>>> only serves the purpose if in future should we need it. >>>> purpose is something like a user initiated thread which >>>> should to go to the backup-SB if primary-SB is not found ?. >>>> Or I can drop BTRFS_SCAN_BACKUP_SB idea depending on how >>>> it is convenient as a whole. >>> >>> See what others think, perhaps, but if nobody is using it, I think >>> it should just go away. I''d call it "dead code." :) >>> >>> But I am surprised that none of the commands which accept alternate >>> superblock locations find their way into btrfs_read_dev_super() - >>> that seems odd to me. Is it re-implemented or open-coded in other >>> places? >> >> So to be clearer, rather than removing the code right away, maybe >> it''s worth a look to see if the other commands which *want* backup >> superblocks should be using this same code. Then you''d have a reason >> for your new flag. :) > > > when non primary SB (sb_bytenr) is specified in btrfs_read_dev_super() > (that is when user is involved) it would directly fetch it. so its > not a problem when we know which SB to read other than the primary SB.Oh, right - I had forgotten that, I''m sorry. So the behavior is: if sb_bytenr is specified and it is not the first sb, read it and return it on success. Otherwise, read the first superblock and return it if it''s ok. If it''s bad, and *if* your new flag is set, continue reading other superblocks until a good one is found, or return failure if none are found. Now that I think about it, that''s a somewhat convoluted set of behaviors for one function.> However when primary SB is specified it would look for only primary SB > unless BTRFS_SCAN_BACKUP_SB flag is set (with the patch).Right, ok.> Now, do we > need this flag ? looks like Yes ! (sorry to change my opinion here > though) and as below.. > > In some cases when user is _not_ involved. Like in > > check_mounted(). > > In a multi dev btrfs mounted fs. If by any chance the primary SB > is corrupted then we would say the device is NOT mounted even > if it is mounted. > > eg: > # mkfs.btrfs /dev/sdb /dev/sdc -f && mount /dev/sdb /btrfs > # ./check-mounted /dev/sdc > its btrfs > /dev/sdc is currently mounted. Aborting. > # dd if=/dev/zero of=/dev/sdc count=8 seek=$(((64 * 1024)/512)) > # ./check-mounted /dev/sdcwhat is "./check-mounted?"> Not mounted > # cat /proc/mounts | egrep btrfs > /dev/sdb /btrfs btrfs rw,seclabel,relatime,noacl,space_cache 0 0 > > > So we have to set BTRFS_SCAN_BACKUP_SB for check_mounted() > But the above scenario is not simple enough to be practical though.(Seems like a mount check would be best implemented by asking the kernel which devices are in use for mounted btrfs filesystems, rather than scanning the block devices directly, but maybe that''s a different issue.) I guess I need to stop & think more carefully about this, it seems like I am not seeing the whole picture. The overall goal here is to not discover "btrfs" devices which actually only have stale backup superblocks present, right? The loop in btrfs_read_dev_super() might be ok for verifying backups, but it should probably fail outright on the first bad one it finds, or at least if the primary is bad; the user would be notified of the inconsistency and could take corrective action w/ fsck or whatnot, right? -Eric> > -Anand-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-18 03:39 UTC
Re: [PATCH 3/3 v4] btrfs-progs: disable using backup superblock by default
>> # mkfs.btrfs /dev/sdb /dev/sdc -f && mount /dev/sdb /btrfs >> # ./check-mounted /dev/sdc >> its btrfs >> /dev/sdc is currently mounted. Aborting. >> # dd if=/dev/zero of=/dev/sdc count=8 seek=$(((64 * 1024)/512)) >> # ./check-mounted /dev/sdc > > what is "./check-mounted?"sorry forgot to mention.. check-mounted is small prog it unit-tests check_mounted() function (Find the diff below.)>> Not mounted >> # cat /proc/mounts | egrep btrfs >> /dev/sdb /btrfs btrfs rw,seclabel,relatime,noacl,space_cache 0 0 >> >> >> So we have to set BTRFS_SCAN_BACKUP_SB for check_mounted() >> But the above scenario is not simple enough to be practical though. > > (Seems like a mount check would be best implemented by asking the kernel > which devices are in use for mounted btrfs filesystems, rather than > scanning the block devices directly, but maybe that''s a different issue.) > > I guess I need to stop & think more carefully about this, it seems like > I am not seeing the whole picture. > > The overall goal here is to not discover "btrfs" devices which actually > only have stale backup superblocks present, right? > > The loop in btrfs_read_dev_super() might be ok for verifying backups, > but it should probably fail outright on the first bad one it finds, > or at least if the primary is bad; the user would be notified of the > inconsistency and could take corrective action w/ fsck or whatnot, right?This logic is not be suitable for the function check_mounted(). The above test case just demonstrates that. This is about btrfs on multi-dev and we use one dev to mount and another dev to check if its mounted, now if the primary SB is corrupted on this (latter) dev we still need to find its mounted by reading from the backup SB, so setting the BTRFS_SCAN_BACKUP_SB will help. Thanks, Anand --------------------------------------------------------------------- diff --git a/Makefile b/Makefile index d102dee..c97e6b7 100644 --- a/Makefile +++ b/Makefile @@ -159,6 +159,10 @@ btrfs-select-super: $(objects) $(libs) btrfs-select-super.o @echo " [LD] $@" $(Q)$(CC) $(CFLAGS) -o btrfs-select-super $(objects) btrfs-select-super.o $(LDFLAGS) $(LIBS) +check-mounted: $(objects) $(libs) check-mounted.o + @echo " [LD] $@" + $(Q)$(CC) $(CFLAGS) -o check-mounted $(objects) check-mounted.o $(LDFLAGS) $(LIBS) + btrfstune: $(objects) $(libs) btrfstune.o @echo " [LD] $@" $(Q)$(CC) $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS) @@ -205,7 +209,7 @@ clean : @echo "Cleaning" $(Q)rm -f $(progs) cscope.out *.o .*.d btrfs-convert btrfs-image btrfs-select-super \ btrfs-zero-log btrfstune dir-test ioctl-test quick-test send-test btrfs.static btrfsck \ - version.h \ + version.h check-mounted\ $(libs) $(lib_links) $(Q)$(MAKE) $(MAKEOPTS) -C man $@ diff --git a/check-mounted.c b/check-mounted.c new file mode 100644 index 0000000..781edec --- /dev/null +++ b/check-mounted.c @@ -0,0 +1,31 @@ + +#define _XOPEN_SOURCE 500 +#define _GNU_SOURCE 1 +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include "kerncompat.h" +#include "ctree.h" +#include "disk-io.h" +#include "print-tree.h" +#include "transaction.h" +#include "list.h" +#include "version.h" +#include "utils.h" + +int main(int ac, char **av) +{ + int ret; + + if((ret = check_mounted(av[optind])) < 0) { + fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret)); + return ret; + } else if(ret) { + fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]); + return -EBUSY; + } + printf("Not mounted\n"); + return 0; +} ------------------------------------------------------------------------------ -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-27 10:07 UTC
[PATCH 0/5 v5] access to backup-sb and btrfs'' multipath aware
We need a mechanism to tell when to use the backup super_block. To do this it needs a frame-work, and the patch #2 and #3 below provides the same without change in the logic. Its been found and posted to the list that check_mounted needs access to the backup-sb. so patch #3 adds flags parameter to the function btrfs_scan_one_device so that _only_ check_mounted can set the flag to access the backup-sb. patch#4 below is to enable and disable acecss to backup-sb for only certain threads v4->v5: Rebase with integration-20130321 and with my own changes (patch #1) Allow check_mounted thread-path to use backup-sb v3->v4: Fixed some warnings introduced by patch #3 below, sorry my mistake. v2->v3: Accepts David and Eric review, which would result in disabled access to backup-superblock by default. Dropped the patch [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device Introduced a new patch [PATCH 3/3] btrfs-progs: disable using backup superblock by default v1->v2: Accepts Eric and Zach review. Separates fix into 3 patches for easy logical understanding Anand Jain (5): btrfs-progs: make btrfs dev scan multi path aware btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super btrfs-progs: introduce passing flags to btrfs_scan_one_device btrfs-progs: disable using backup superblock by default cmds-device.c | 57 +++++++++++++++++++++++++++++++++++++++++---------------- cmds-replace.c | 2 +- disk-io.c | 15 ++++++++++----- disk-io.h | 3 ++- find-root.c | 9 ++++++--- utils.c | 57 +++++++++++++++++++++++++++++++++++++++------------------ utils.h | 8 +++++--- volumes.c | 6 ++++-- volumes.h | 2 +- 9 files changed, 109 insertions(+), 50 deletions(-) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-27 10:07 UTC
[PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware
We should avoid using non multi-path (mp) path for mp disks As of now there is no good way (like api) to check that. A workaround way is to check if the O_EXCL open is unsuccessful. This is safe since otherwise the BTRFS_IOC_SCAN_DEV ioctl would fail if the disk-path can not be opened with the flag O_EXCL set. This patch also includes some (error) print format changes related to the btrfs dev scan.. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 53 +++++++++++++++++++++++++++++++++++++++-------------- utils.c | 31 ++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index 41e79d3..b8d05fd 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -185,7 +185,7 @@ static const char * const cmd_scan_dev_usage[] = { static int cmd_scan_dev(int argc, char **argv) { - int i, fd, e; + int i, fd, e, ret = 0; int checklist = 1; int devstart = 1; @@ -197,6 +197,21 @@ static int cmd_scan_dev(int argc, char **argv) devstart += 1; } + fd = open("/dev/btrfs-control", O_RDWR); + e = errno; + if (fd < 0) { + FILE *mfd = popen("lsmod | grep btrfs", "r"); + char buf[16]; + + if (fread (buf, 1, sizeof (buf), mfd) > 0) + fprintf(stderr, "ERROR: failed to open "\ + "/dev/btrfs-control - %s\n", strerror(e)); + else + fprintf(stderr, "ERROR: btrfs kernel module "\ + "is not loaded\n"); + return 10; + } + if(argc<=devstart){ int ret; @@ -210,20 +225,30 @@ static int cmd_scan_dev(int argc, char **argv) fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; } + printf("done\n"); return 0; } - fd = open("/dev/btrfs-control", O_RDWR); - if (fd < 0) { - perror("failed to open /dev/btrfs-control"); - return 10; - } - + printf("Scanning for Btrfs in\n"); for( i = devstart ; i < argc ; i++ ){ + int fdt; struct btrfs_ioctl_vol_args args; - int ret; + printf(" %s ", argv[i]); + fflush(stdout); - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); + /* + * If for a multipath (mp) disk user provides the + * non-mp path then open with flag O_EXCL will fail, + * (also ioctl opens with O_EXCL), So test it before + * calling ioctl. + */ + fdt = open(argv[i], O_RDONLY|O_EXCL); + if (fdt < 0) { + perror("ERROR"); + ret = -1; + continue; + } + close(fdt); strncpy_null(args.name, argv[i]); /* @@ -235,15 +260,15 @@ static int cmd_scan_dev(int argc, char **argv) e = errno; if( ret < 0 ){ - close(fd); - fprintf(stderr, "ERROR: unable to scan the device ''%s'' - %s\n", - argv[i], strerror(e)); - return 11; + fprintf(stderr, "ERROR: unable to scan - %s\n", + strerror(e)); + ret = -1; } + printf("found\n"); } close(fd); - return 0; + return ret; } static const char * const cmd_ready_dev_usage[] = { diff --git a/utils.c b/utils.c index a4f7b06..3a0d444 100644 --- a/utils.c +++ b/utils.c @@ -1105,25 +1105,32 @@ again: if (!S_ISBLK(st.st_mode)) { continue; } - fd = open(fullpath, O_RDONLY); + fd = open(fullpath, O_RDONLY|O_EXCL); if (fd < 0) { /* ignore the following errors: ENXIO (device don''t exists) ENOMEDIUM (No medium found -> like a cd tray empty) + EBUSY (when mp disk is opened + using non-mp path). */ - if(errno != ENXIO && errno != ENOMEDIUM) + if(errno != ENXIO && errno != ENOMEDIUM && + errno != EBUSY) fprintf(stderr, "failed to read %s: %s\n", fullpath, strerror(errno)); continue; } + close(fd); + + fd = open(fullpath, O_RDONLY); ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); + close(fd); + if (ret == 0 && run_ioctl > 0) { btrfs_register_one_device(fullpath); } - close(fd); } if (!list_empty(&pending_list)) { free(pending); @@ -1442,19 +1449,29 @@ scan_again: continue; } - fd = open(fullpath, O_RDONLY); + /* This will fail for the multi path devices + * when non multipath path is used. So we avoid + * sending it to the kernel which eventually will + * fail. + */ + fd = open(fullpath, O_RDONLY|O_EXCL); if (fd < 0) { - fprintf(stderr, "failed to open %s: %s\n", - fullpath, strerror(errno)); + if (errno != EBUSY) { + fprintf(stderr, "failed to open %s: %s\n", + fullpath, strerror(errno)); + } continue; } + close(fd); + + fd = open(fullpath, O_RDONLY); ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); + close(fd); if (ret == 0 && run_ioctl > 0) { btrfs_register_one_device(fullpath); } - close(fd); } fclose(proc_partitions); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-27 10:07 UTC
[PATCH 2/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
Introduce flag BTRFS_SCAN_REGISTER to replace the parameter run_ioctl which controls calling the function btrfs_register_one_device(). Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 4 ++-- disk-io.c | 3 ++- find-root.c | 3 ++- utils.c | 17 +++++++++-------- utils.h | 7 ++++--- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index b8d05fd..edff0bf 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -218,9 +218,9 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(1); + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else - ret = btrfs_scan_one_dir("/dev", 1); + ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; diff --git a/disk-io.c b/disk-io.c index be4abb8..6a03e9c 100644 --- a/disk-io.c +++ b/disk-io.c @@ -835,7 +835,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/find-root.c b/find-root.c index 810d835..16920ed 100644 --- a/find-root.c +++ b/find-root.c @@ -110,7 +110,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/utils.c b/utils.c index 3a0d444..15645c1 100644 --- a/utils.c +++ b/utils.c @@ -927,7 +927,8 @@ int check_mounted_where(int fd, const char *file, char *where, int size, /* scan other devices */ if (is_btrfs && total_devs > 1) { - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, + BTRFS_SCAN_REGISTER))) return ret; } @@ -1039,7 +1040,7 @@ void btrfs_register_one_device(char *fname) close(fd); } -int btrfs_scan_one_dir(char *dirname, int run_ioctl) +int btrfs_scan_one_dir(char *dirname, u64 flags) { DIR *dirp = NULL; struct dirent *dirent; @@ -1128,7 +1129,7 @@ again: BTRFS_SUPER_INFO_OFFSET); close(fd); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } } @@ -1152,13 +1153,13 @@ fail: } int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls) + u64 flags) { int ret; - ret = btrfs_scan_block_devices(run_ioctls); + ret = btrfs_scan_block_devices(flags); if (ret) - ret = btrfs_scan_one_dir("/dev", run_ioctls); + ret = btrfs_scan_one_dir("/dev", flags); return ret; } @@ -1391,7 +1392,7 @@ int set_label(const char *btrfs_dev, const char *label) set_label_mounted(btrfs_dev, label); } -int btrfs_scan_block_devices(int run_ioctl) +int btrfs_scan_block_devices(u64 flags) { struct stat st; @@ -1469,7 +1470,7 @@ scan_again: &num_devices, BTRFS_SUPER_INFO_OFFSET); close(fd); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } } diff --git a/utils.h b/utils.h index 4dcdc31..1de5143 100644 --- a/utils.h +++ b/utils.h @@ -23,6 +23,7 @@ #include "ctree.h" #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_SCAN_REGISTER (1ULL << 1) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, @@ -36,9 +37,9 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u64 block_count, u32 io_width, u32 io_align, u32 sectorsize); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls); + u64 flags); void btrfs_register_one_device(char *fname); -int btrfs_scan_one_dir(char *dirname, int run_ioctl); +int btrfs_scan_one_dir(char *dirname, u64 flags); int check_mounted(const char *devicename); int check_mounted_where(int fd, const char *file, char *where, int size, struct btrfs_fs_devices **fs_devices_mnt); @@ -46,7 +47,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); int get_mountpt(char *dev, char *mntpt, size_t size); -int btrfs_scan_block_devices(int run_ioctl); +int btrfs_scan_block_devices(u64 flags); u64 parse_size(char *s); int open_file_or_dir(const char *fname); int get_device_info(int fd, u64 devid, -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-27 10:07 UTC
[PATCH 3/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
As of now btrfs_read_dev_super() reads the backup super block by default and calling function has no control. However in the following patch we would see that is undesirable. So with the flag BTRFS_SCAN_BACKUP_SB the calling function can now indicate if btrfs_read_dev_super should scan for the backup SB when primary SB fails. This patch just provides the frame-work, keeping all the logic in the code same with or without this patch. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 10 +++++++--- disk-io.h | 3 ++- find-root.c | 3 ++- utils.h | 1 + volumes.c | 4 +++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/disk-io.c b/disk-io.c index 6a03e9c..8d68c2e 100644 --- a/disk-io.c +++ b/disk-io.c @@ -880,7 +880,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fs_info->super_bytenr = sb_bytenr; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + disk_super, sb_bytenr, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1103,7 +1104,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, + u64 flags) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; @@ -1112,6 +1114,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) int ret; u64 transid = 0; u64 bytenr; + int max; if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { ret = pread64(fd, &buf, sizeof(buf), sb_bytenr); @@ -1126,7 +1129,8 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) return 0; } - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + max = flags & BTRFS_SCAN_BACKUP_SB ? BTRFS_SUPER_MIRROR_MAX : 1; + for (i = 0; i < max; 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 ff87958..40b7222 100644 --- a/disk-io.h +++ b/disk-io.h @@ -59,7 +59,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, + u64 flags); 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/find-root.c b/find-root.c index 16920ed..0b08358 100644 --- a/find-root.c +++ b/find-root.c @@ -151,7 +151,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, BTRFS_SUPER_INFO_OFFSET); + disk_super, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.h b/utils.h index 1de5143..ab22b02 100644 --- a/utils.h +++ b/utils.h @@ -24,6 +24,7 @@ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) #define BTRFS_SCAN_REGISTER (1ULL << 1) +#define BTRFS_SCAN_BACKUP_SB (1ULL << 2) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, diff --git a/volumes.c b/volumes.c index 3e52d06..1113cb5 100644 --- a/volumes.c +++ b/volumes.c @@ -29,6 +29,7 @@ #include "transaction.h" #include "print-tree.h" #include "volumes.h" +#include "utils.h" struct stripe { struct btrfs_device *dev; @@ -226,7 +227,8 @@ 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, + BTRFS_SCAN_BACKUP_SB); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-27 10:07 UTC
[PATCH 4/5 v5] btrfs-progs: introduce passing flags to btrfs_scan_one_device
check_mounted would need to check backup SB to see if the device is mounted to accommodate the situation when the primary SB is corrupted (even in multi dev btrfs). so we need flag to communicate to btrfs_read_dev_super to check backup SB. this patch will just introduce the flag with access to backup SB disable. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-replace.c | 2 +- disk-io.c | 2 +- find-root.c | 3 ++- utils.c | 9 ++++++--- volumes.c | 2 +- volumes.h | 2 +- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cmds-replace.c b/cmds-replace.c index 6397bb5..ab34388 100644 --- a/cmds-replace.c +++ b/cmds-replace.c @@ -280,7 +280,7 @@ static int cmd_start_replace(int argc, char **argv) goto leave_with_error; } ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, 0ull); if (ret >= 0 && !force_using_targetdev) { fprintf(stderr, "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", diff --git a/disk-io.c b/disk-io.c index 8d68c2e..82c3b66 100644 --- a/disk-io.c +++ b/disk-io.c @@ -827,7 +827,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fprintf(stderr, "Warning, could not drop caches\n"); ret = btrfs_scan_one_device(fp, path, &fs_devices, - &total_devs, sb_bytenr); + &total_devs, sb_bytenr, 0ull); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", path); diff --git a/find-root.c b/find-root.c index 0b08358..eac3d79 100644 --- a/find-root.c +++ b/find-root.c @@ -102,7 +102,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) u64 features; ret = btrfs_scan_one_device(fd, device, &fs_devices, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, + 0ull); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", device); diff --git a/utils.c b/utils.c index 15645c1..a2001de 100644 --- a/utils.c +++ b/utils.c @@ -922,7 +922,8 @@ 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, + 0ull); is_btrfs = (ret >= 0); /* scan other devices */ @@ -1126,7 +1127,8 @@ again: fd = open(fullpath, O_RDONLY); ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + 0ull); close(fd); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { @@ -1468,7 +1470,8 @@ scan_again: fd = open(fullpath, O_RDONLY); ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + 0ull); close(fd); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); diff --git a/volumes.c b/volumes.c index 1113cb5..a18b219 100644 --- a/volumes.c +++ b/volumes.c @@ -213,7 +213,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, u64 flags) { struct btrfs_super_block *disk_super; char *buf; diff --git a/volumes.h b/volumes.h index 911f788..f87aa5b 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, u64 flags); int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len); int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree, struct btrfs_fs_devices *fs_devices); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Mar-27 10:07 UTC
[PATCH 5/5 v5] btrfs-progs: disable using backup superblock by default
except for check_mounted rest of the function thread should have the access to the backup SB disabled. this patch will just do that. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 2 +- find-root.c | 2 +- utils.c | 2 +- volumes.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/disk-io.c b/disk-io.c index 82c3b66..589b37a 100644 --- a/disk-io.c +++ b/disk-io.c @@ -881,7 +881,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, disk_super, sb_bytenr, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/find-root.c b/find-root.c index eac3d79..27512df 100644 --- a/find-root.c +++ b/find-root.c @@ -153,7 +153,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, BTRFS_SUPER_INFO_OFFSET, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.c b/utils.c index a2001de..b9b675d 100644 --- a/utils.c +++ b/utils.c @@ -923,7 +923,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, - 0ull); + BTRFS_SCAN_BACKUP_SB); is_btrfs = (ret >= 0); /* scan other devices */ diff --git a/volumes.c b/volumes.c index a18b219..2de69af 100644 --- a/volumes.c +++ b/volumes.c @@ -228,7 +228,7 @@ int btrfs_scan_one_device(int fd, const char *path, } disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, disk_super, super_offset, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
anand jain
2013-Mar-27 23:17 UTC
Re: [PATCH 0/5 v5] access to backup-sb and btrfs'' multipath aware
Any review comments on this ? pls. Thanks, Anand On 27/03/2013 18:07, Anand Jain wrote:> We need a mechanism to tell when to use the backup super_block. > To do this it needs a frame-work, and the patch #2 and #3 below > provides the same without change in the logic. > > Its been found and posted to the list that check_mounted needs > access to the backup-sb. so patch #3 adds flags parameter > to the function btrfs_scan_one_device so that _only_ > check_mounted can set the flag to access the backup-sb. > > patch#4 below is to enable and disable acecss to backup-sb > for only certain threads > > v4->v5: > Rebase with integration-20130321 and with my own changes (patch #1) > Allow check_mounted thread-path to use backup-sb > > v3->v4: > Fixed some warnings introduced by patch #3 below, > sorry my mistake. > > v2->v3: > Accepts David and Eric review, which would result in disabled > access to backup-superblock by default. > Dropped the patch > [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device > Introduced a new patch > [PATCH 3/3] btrfs-progs: disable using backup superblock by default > > v1->v2: > Accepts Eric and Zach review. > Separates fix into 3 patches for easy logical understanding > > Anand Jain (5): > btrfs-progs: make btrfs dev scan multi path aware > btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl > btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for > btrfs_read_dev_super > btrfs-progs: introduce passing flags to btrfs_scan_one_device > btrfs-progs: disable using backup superblock by default > > cmds-device.c | 57 +++++++++++++++++++++++++++++++++++++++++---------------- > cmds-replace.c | 2 +- > disk-io.c | 15 ++++++++++----- > disk-io.h | 3 ++- > find-root.c | 9 ++++++--- > utils.c | 57 +++++++++++++++++++++++++++++++++++++++------------------ > utils.h | 8 +++++--- > volumes.c | 6 ++++-- > volumes.h | 2 +- > 9 files changed, 109 insertions(+), 50 deletions(-) >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
We need a mechanism to tell when to use the backup super_block. To do this it needs a frame-work, and the patch #1 and #2 below provides the same without change in the logic. Its been found and posted to the list that check_mounted needs access to the backup-sb and find-root as well. so patch #3 provides frame work so that threads which need the access to the backup sb can set the flag. further, patch#4 disables backup-sb access except for check_mounted patch#5 provides backup-sb access to find-root v5->v6: Dropped patch btrfs-progs: make btrfs dev scan multi path aware sorry its a wrong patch, further this branch does not find the problem this patch was trying to address Added patch#5 ----------------- v4->v5: Rebase with integration-20130321 and with my own changes (patch #1) Allow check_mounted thread-path to use backup-sb v3->v4: Fixed some warnings introduced by patch #3 below, sorry my mistake. v2->v3: Accepts David and Eric review, which would result in disabled access to backup-superblock by default. Dropped the patch [PATCH 3/3] btrfs-progs: use BTRFS_SCAN_BACKUP_SB flag in btrfs_scan_one_device Introduced a new patch [PATCH 3/3] btrfs-progs: disable using backup superblock by default v1->v2: Accepts Eric and Zach review. Separates fix into 3 patches for easy logical understanding Anand Jain (5): btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super btrfs-progs: introduce passing flags to btrfs_scan_one_device btrfs-progs: disable using backup superblock by default btrfs-progs: btrfs-find-root should scan backup-sb cmds-device.c | 4 ++-- cmds-replace.c | 2 +- disk-io.c | 15 ++++++++++----- disk-io.h | 3 ++- find-root.c | 9 ++++++--- utils.c | 29 +++++++++++++++++------------ utils.h | 8 +++++--- volumes.c | 6 ++++-- volumes.h | 2 +- 9 files changed, 48 insertions(+), 30 deletions(-) -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 1/5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
Introduce flag BTRFS_SCAN_REGISTER to replace the parameter run_ioctl which controls calling the function btrfs_register_one_device(). Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-device.c | 4 ++-- disk-io.c | 3 ++- find-root.c | 3 ++- utils.c | 20 +++++++++++--------- utils.h | 7 ++++--- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cmds-device.c b/cmds-device.c index 41e79d3..a90fb67 100644 --- a/cmds-device.c +++ b/cmds-device.c @@ -203,9 +203,9 @@ static int cmd_scan_dev(int argc, char **argv) printf("Scanning for Btrfs filesystems\n"); if(checklist) - ret = btrfs_scan_block_devices(1); + ret = btrfs_scan_block_devices(BTRFS_SCAN_REGISTER); else - ret = btrfs_scan_one_dir("/dev", 1); + ret = btrfs_scan_one_dir("/dev", BTRFS_SCAN_REGISTER); if (ret){ fprintf(stderr, "ERROR: error %d while scanning\n", ret); return 18; diff --git a/disk-io.c b/disk-io.c index be4abb8..6a03e9c 100644 --- a/disk-io.c +++ b/disk-io.c @@ -835,7 +835,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/find-root.c b/find-root.c index 810d835..16920ed 100644 --- a/find-root.c +++ b/find-root.c @@ -110,7 +110,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) } if (total_devs != 1) { - ret = btrfs_scan_for_fsid(fs_devices, total_devs, 1); + ret = btrfs_scan_for_fsid(fs_devices, total_devs, + BTRFS_SCAN_REGISTER); if (ret) goto out; } diff --git a/utils.c b/utils.c index a4f7b06..a15789e 100644 --- a/utils.c +++ b/utils.c @@ -927,7 +927,8 @@ int check_mounted_where(int fd, const char *file, char *where, int size, /* scan other devices */ if (is_btrfs && total_devs > 1) { - if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, 1))) + if((ret = btrfs_scan_for_fsid(fs_devices_mnt, total_devs, + BTRFS_SCAN_REGISTER))) return ret; } @@ -1039,7 +1040,7 @@ void btrfs_register_one_device(char *fname) close(fd); } -int btrfs_scan_one_dir(char *dirname, int run_ioctl) +int btrfs_scan_one_dir(char *dirname, u64 flags) { DIR *dirp = NULL; struct dirent *dirent; @@ -1112,7 +1113,8 @@ again: ENOMEDIUM (No medium found -> like a cd tray empty) */ - if(errno != ENXIO && errno != ENOMEDIUM) + if(errno != ENXIO && errno != ENOMEDIUM && + errno != EBUSY) fprintf(stderr, "failed to read %s: %s\n", fullpath, strerror(errno)); continue; @@ -1120,7 +1122,7 @@ again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); @@ -1145,13 +1147,13 @@ fail: } int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls) + u64 flags) { int ret; - ret = btrfs_scan_block_devices(run_ioctls); + ret = btrfs_scan_block_devices(flags); if (ret) - ret = btrfs_scan_one_dir("/dev", run_ioctls); + ret = btrfs_scan_one_dir("/dev", flags); return ret; } @@ -1384,7 +1386,7 @@ int set_label(const char *btrfs_dev, const char *label) set_label_mounted(btrfs_dev, label); } -int btrfs_scan_block_devices(int run_ioctl) +int btrfs_scan_block_devices(u64 flags) { struct stat st; @@ -1451,7 +1453,7 @@ scan_again: ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, BTRFS_SUPER_INFO_OFFSET); - if (ret == 0 && run_ioctl > 0) { + if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } close(fd); diff --git a/utils.h b/utils.h index 4dcdc31..1de5143 100644 --- a/utils.h +++ b/utils.h @@ -23,6 +23,7 @@ #include "ctree.h" #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_SCAN_REGISTER (1ULL << 1) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, @@ -36,9 +37,9 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, u64 block_count, u32 io_width, u32 io_align, u32 sectorsize); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, - int run_ioctls); + u64 flags); void btrfs_register_one_device(char *fname); -int btrfs_scan_one_dir(char *dirname, int run_ioctl); +int btrfs_scan_one_dir(char *dirname, u64 flags); int check_mounted(const char *devicename); int check_mounted_where(int fd, const char *file, char *where, int size, struct btrfs_fs_devices **fs_devices_mnt); @@ -46,7 +47,7 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); int get_mountpt(char *dev, char *mntpt, size_t size); -int btrfs_scan_block_devices(int run_ioctl); +int btrfs_scan_block_devices(u64 flags); u64 parse_size(char *s); int open_file_or_dir(const char *fname); int get_device_info(int fd, u64 devid, -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 2/5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
As of now btrfs_read_dev_super() reads the backup super block by default and calling function has no control. However in the following patch we would see that is undesirable. So with the flag BTRFS_SCAN_BACKUP_SB the calling function can now indicate if btrfs_read_dev_super should scan for the backup SB when primary SB fails. This patch just provides the frame-work, keeping all the logic in the code same with or without this patch. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 10 +++++++--- disk-io.h | 3 ++- find-root.c | 3 ++- utils.h | 1 + volumes.c | 4 +++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/disk-io.c b/disk-io.c index 6a03e9c..8d68c2e 100644 --- a/disk-io.c +++ b/disk-io.c @@ -880,7 +880,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fs_info->super_bytenr = sb_bytenr; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, sb_bytenr); + disk_super, sb_bytenr, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; @@ -1103,7 +1104,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, + u64 flags) { u8 fsid[BTRFS_FSID_SIZE]; int fsid_is_initialized = 0; @@ -1112,6 +1114,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) int ret; u64 transid = 0; u64 bytenr; + int max; if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { ret = pread64(fd, &buf, sizeof(buf), sb_bytenr); @@ -1126,7 +1129,8 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr) return 0; } - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + max = flags & BTRFS_SCAN_BACKUP_SB ? BTRFS_SUPER_MIRROR_MAX : 1; + for (i = 0; i < max; 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 ff87958..40b7222 100644 --- a/disk-io.h +++ b/disk-io.h @@ -59,7 +59,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, + u64 flags); 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/find-root.c b/find-root.c index 16920ed..0b08358 100644 --- a/find-root.c +++ b/find-root.c @@ -151,7 +151,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET; disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, - disk_super, BTRFS_SUPER_INFO_OFFSET); + disk_super, BTRFS_SUPER_INFO_OFFSET, + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.h b/utils.h index 1de5143..ab22b02 100644 --- a/utils.h +++ b/utils.h @@ -24,6 +24,7 @@ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) #define BTRFS_SCAN_REGISTER (1ULL << 1) +#define BTRFS_SCAN_BACKUP_SB (1ULL << 2) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, diff --git a/volumes.c b/volumes.c index 3e52d06..1113cb5 100644 --- a/volumes.c +++ b/volumes.c @@ -29,6 +29,7 @@ #include "transaction.h" #include "print-tree.h" #include "volumes.h" +#include "utils.h" struct stripe { struct btrfs_device *dev; @@ -226,7 +227,8 @@ 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, + BTRFS_SCAN_BACKUP_SB); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 3/5] btrfs-progs: introduce passing flags to btrfs_scan_one_device
check_mounted would need to check backup SB to see if the device is mounted to accommodate the situation when the primary SB is corrupted (even in multi dev btrfs). so we need flag to communicate to btrfs_read_dev_super to check backup SB. this patch will just introduce the flag with access to backup SB disable. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- cmds-replace.c | 2 +- disk-io.c | 2 +- find-root.c | 3 ++- utils.c | 9 ++++++--- volumes.c | 2 +- volumes.h | 2 +- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cmds-replace.c b/cmds-replace.c index 6397bb5..ab34388 100644 --- a/cmds-replace.c +++ b/cmds-replace.c @@ -280,7 +280,7 @@ static int cmd_start_replace(int argc, char **argv) goto leave_with_error; } ret = btrfs_scan_one_device(fddstdev, dstdev, &fs_devices_mnt, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, 0ull); if (ret >= 0 && !force_using_targetdev) { fprintf(stderr, "Error, target device %s contains filesystem, use ''-f'' to force overwriting.\n", diff --git a/disk-io.c b/disk-io.c index 8d68c2e..82c3b66 100644 --- a/disk-io.c +++ b/disk-io.c @@ -827,7 +827,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, fprintf(stderr, "Warning, could not drop caches\n"); ret = btrfs_scan_one_device(fp, path, &fs_devices, - &total_devs, sb_bytenr); + &total_devs, sb_bytenr, 0ull); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", path); diff --git a/find-root.c b/find-root.c index 0b08358..eac3d79 100644 --- a/find-root.c +++ b/find-root.c @@ -102,7 +102,8 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) u64 features; ret = btrfs_scan_one_device(fd, device, &fs_devices, - &total_devs, BTRFS_SUPER_INFO_OFFSET); + &total_devs, BTRFS_SUPER_INFO_OFFSET, + 0ull); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", device); diff --git a/utils.c b/utils.c index a15789e..3b46889 100644 --- a/utils.c +++ b/utils.c @@ -922,7 +922,8 @@ 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, + 0ull); is_btrfs = (ret >= 0); /* scan other devices */ @@ -1121,7 +1122,8 @@ again: } ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + 0ull); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } @@ -1452,7 +1454,8 @@ scan_again: } ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, &num_devices, - BTRFS_SUPER_INFO_OFFSET); + BTRFS_SUPER_INFO_OFFSET, + 0ull); if (ret == 0 && flags & BTRFS_SCAN_REGISTER) { btrfs_register_one_device(fullpath); } diff --git a/volumes.c b/volumes.c index 1113cb5..a18b219 100644 --- a/volumes.c +++ b/volumes.c @@ -213,7 +213,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, u64 flags) { struct btrfs_super_block *disk_super; char *buf; diff --git a/volumes.h b/volumes.h index 911f788..f87aa5b 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, u64 flags); int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len); int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree, struct btrfs_fs_devices *fs_devices); -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 4/5] btrfs-progs: disable using backup superblock by default
except for check_mounted Signed-off-by: Anand Jain <anand.jain@oracle.com> --- disk-io.c | 2 +- find-root.c | 2 +- utils.c | 2 +- volumes.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/disk-io.c b/disk-io.c index 82c3b66..589b37a 100644 --- a/disk-io.c +++ b/disk-io.c @@ -881,7 +881,7 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, disk_super = fs_info->super_copy; ret = btrfs_read_dev_super(fs_devices->latest_bdev, disk_super, sb_bytenr, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/find-root.c b/find-root.c index eac3d79..27512df 100644 --- a/find-root.c +++ b/find-root.c @@ -153,7 +153,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, BTRFS_SUPER_INFO_OFFSET, - BTRFS_SCAN_BACKUP_SB); + 0ull); if (ret) { printk("No valid btrfs found\n"); goto out_devices; diff --git a/utils.c b/utils.c index 3b46889..27574a0 100644 --- a/utils.c +++ b/utils.c @@ -923,7 +923,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, - 0ull); + BTRFS_SCAN_BACKUP_SB); is_btrfs = (ret >= 0); /* scan other devices */ diff --git a/volumes.c b/volumes.c index a18b219..b555ded 100644 --- a/volumes.c +++ b/volumes.c @@ -228,7 +228,7 @@ int btrfs_scan_one_device(int fd, const char *path, } disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, disk_super, super_offset, - BTRFS_SCAN_BACKUP_SB); + flags); if (ret < 0) { ret = -EIO; goto error_brelse; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-05 05:54 UTC
[PATCH 5/5] btrfs-progs: btrfs-find-root should scan backup-sb
since idea is to scan and report all the sb in the dev, we should let it so look for backup SB by setting the flag BTRFS_SCAN_BACKUP_SB Signed-off-by: Anand Jain <anand.jain@oracle.com> --- find-root.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/find-root.c b/find-root.c index 27512df..e4ad6ac 100644 --- a/find-root.c +++ b/find-root.c @@ -103,7 +103,7 @@ static struct btrfs_root *open_ctree_broken(int fd, const char *device) ret = btrfs_scan_one_device(fd, device, &fs_devices, &total_devs, BTRFS_SUPER_INFO_OFFSET, - 0ull); + BTRFS_SCAN_BACKUP_SB); if (ret) { fprintf(stderr, "No valid Btrfs found on %s\n", device); @@ -153,7 +153,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, BTRFS_SUPER_INFO_OFFSET, - 0ull); + BTRFS_SCAN_BACKUP_SB); if (ret) { printk("No valid btrfs found\n"); goto out_devices; -- 1.8.1.227.g44fe835 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Anand Jain
2013-Apr-11 09:57 UTC
Re: [obsoleted] [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware
This patch is replaced By: btrfs-progs: avoid ioctl for multipath-dev with its non-multipath path which is also sent to this mailing list. thanks, Anand On 03/27/2013 06:07 PM, Anand Jain wrote:> We should avoid using non multi-path (mp) path for mp disks > As of now there is no good way (like api) to check that. > A workaround way is to check if the O_EXCL open is unsuccessful. > This is safe since otherwise the BTRFS_IOC_SCAN_DEV ioctl would > fail if the disk-path can not be opened with the flag O_EXCL set. > > This patch also includes some (error) print format changes related > to the btrfs dev scan.. > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > cmds-device.c | 53 +++++++++++++++++++++++++++++++++++++++-------------- > utils.c | 31 ++++++++++++++++++++++++------- > 2 files changed, 63 insertions(+), 21 deletions(-) > > diff --git a/cmds-device.c b/cmds-device.c > index 41e79d3..b8d05fd 100644 > --- a/cmds-device.c > +++ b/cmds-device.c > @@ -185,7 +185,7 @@ static const char * const cmd_scan_dev_usage[] = { > > static int cmd_scan_dev(int argc, char **argv) > { > - int i, fd, e; > + int i, fd, e, ret = 0; > int checklist = 1; > int devstart = 1; > > @@ -197,6 +197,21 @@ static int cmd_scan_dev(int argc, char **argv) > devstart += 1; > } > > + fd = open("/dev/btrfs-control", O_RDWR); > + e = errno; > + if (fd < 0) { > + FILE *mfd = popen("lsmod | grep btrfs", "r"); > + char buf[16]; > + > + if (fread (buf, 1, sizeof (buf), mfd) > 0) > + fprintf(stderr, "ERROR: failed to open "\ > + "/dev/btrfs-control - %s\n", strerror(e)); > + else > + fprintf(stderr, "ERROR: btrfs kernel module "\ > + "is not loaded\n"); > + return 10; > + } > + > if(argc<=devstart){ > > int ret; > @@ -210,20 +225,30 @@ static int cmd_scan_dev(int argc, char **argv) > fprintf(stderr, "ERROR: error %d while scanning\n", ret); > return 18; > } > + printf("done\n"); > return 0; > } > > - fd = open("/dev/btrfs-control", O_RDWR); > - if (fd < 0) { > - perror("failed to open /dev/btrfs-control"); > - return 10; > - } > - > + printf("Scanning for Btrfs in\n"); > for( i = devstart ; i < argc ; i++ ){ > + int fdt; > struct btrfs_ioctl_vol_args args; > - int ret; > + printf(" %s ", argv[i]); > + fflush(stdout); > > - printf("Scanning for Btrfs filesystems in ''%s''\n", argv[i]); > + /* > + * If for a multipath (mp) disk user provides the > + * non-mp path then open with flag O_EXCL will fail, > + * (also ioctl opens with O_EXCL), So test it before > + * calling ioctl. > + */ > + fdt = open(argv[i], O_RDONLY|O_EXCL); > + if (fdt < 0) { > + perror("ERROR"); > + ret = -1; > + continue; > + } > + close(fdt); > > strncpy_null(args.name, argv[i]); > /* > @@ -235,15 +260,15 @@ static int cmd_scan_dev(int argc, char **argv) > e = errno; > > if( ret < 0 ){ > - close(fd); > - fprintf(stderr, "ERROR: unable to scan the device ''%s'' - %s\n", > - argv[i], strerror(e)); > - return 11; > + fprintf(stderr, "ERROR: unable to scan - %s\n", > + strerror(e)); > + ret = -1; > } > + printf("found\n"); > } > > close(fd); > - return 0; > + return ret; > } > > static const char * const cmd_ready_dev_usage[] = { > diff --git a/utils.c b/utils.c > index a4f7b06..3a0d444 100644 > --- a/utils.c > +++ b/utils.c > @@ -1105,25 +1105,32 @@ again: > if (!S_ISBLK(st.st_mode)) { > continue; > } > - fd = open(fullpath, O_RDONLY); > + fd = open(fullpath, O_RDONLY|O_EXCL); > if (fd < 0) { > /* ignore the following errors: > ENXIO (device don''t exists) > ENOMEDIUM (No medium found -> > like a cd tray empty) > + EBUSY (when mp disk is opened > + using non-mp path). > */ > - if(errno != ENXIO && errno != ENOMEDIUM) > + if(errno != ENXIO && errno != ENOMEDIUM && > + errno != EBUSY) > fprintf(stderr, "failed to read %s: %s\n", > fullpath, strerror(errno)); > continue; > } > + close(fd); > + > + fd = open(fullpath, O_RDONLY); > ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, > &num_devices, > BTRFS_SUPER_INFO_OFFSET); > + close(fd); > + > if (ret == 0 && run_ioctl > 0) { > btrfs_register_one_device(fullpath); > } > - close(fd); > } > if (!list_empty(&pending_list)) { > free(pending); > @@ -1442,19 +1449,29 @@ scan_again: > continue; > } > > - fd = open(fullpath, O_RDONLY); > + /* This will fail for the multi path devices > + * when non multipath path is used. So we avoid > + * sending it to the kernel which eventually will > + * fail. > + */ > + fd = open(fullpath, O_RDONLY|O_EXCL); > if (fd < 0) { > - fprintf(stderr, "failed to open %s: %s\n", > - fullpath, strerror(errno)); > + if (errno != EBUSY) { > + fprintf(stderr, "failed to open %s: %s\n", > + fullpath, strerror(errno)); > + } > continue; > } > + close(fd); > + > + fd = open(fullpath, O_RDONLY); > ret = btrfs_scan_one_device(fd, fullpath, &tmp_devices, > &num_devices, > BTRFS_SUPER_INFO_OFFSET); > + close(fd); > if (ret == 0 && run_ioctl > 0) { > btrfs_register_one_device(fullpath); > } > - close(fd); > } > > fclose(proc_partitions); >-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html