All of lore.kernel.org
 help / color / mirror / Atom feed
* [bug]  mkfs.btrfs reports device busy for ext4 mounted disk
@ 2013-02-22  5:29 Anand Jain
  2013-02-22 19:03 ` Zach Brown
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Anand Jain @ 2013-02-22  5:29 UTC (permalink / raw)
  To: linux-btrfs


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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [bug]  mkfs.btrfs reports device busy for ext4 mounted disk
  2013-02-22  5:29 [bug] mkfs.btrfs reports device busy for ext4 mounted disk Anand Jain
@ 2013-02-22 19:03 ` Zach Brown
  2013-02-22 22:30   ` David Sterba
  2013-03-01 10:13 ` [PATCH] btrfs-progs: traverse to backup super-block only when indicated Anand Jain
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
  2 siblings, 1 reply; 22+ messages in thread
From: Zach Brown @ 2013-02-22 19:03 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs

>  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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [bug]  mkfs.btrfs reports device busy for ext4 mounted disk
  2013-02-22 19:03 ` Zach Brown
@ 2013-02-22 22:30   ` David Sterba
  2013-03-01 10:18     ` Anand Jain
  0 siblings, 1 reply; 22+ messages in thread
From: David Sterba @ 2013-02-22 22:30 UTC (permalink / raw)
  To: Zach Brown; +Cc: Anand Jain, linux-btrfs

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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH] btrfs-progs: traverse to backup super-block only when indicated
  2013-02-22  5:29 [bug] mkfs.btrfs reports device busy for ext4 mounted disk Anand Jain
  2013-02-22 19:03 ` Zach Brown
@ 2013-03-01 10:13 ` Anand Jain
  2013-03-01 17:37   ` Eric Sandeen
                     ` (2 more replies)
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
  2 siblings, 3 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-01 10:13 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [bug]  mkfs.btrfs reports device busy for ext4 mounted disk
  2013-02-22 22:30   ` David Sterba
@ 2013-03-01 10:18     ` Anand Jain
  0 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-01 10:18 UTC (permalink / raw)
  To: dsterba, Zach Brown, linux-btrfs



>> 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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] btrfs-progs: traverse to backup super-block only when indicated
  2013-03-01 10:13 ` [PATCH] btrfs-progs: traverse to backup super-block only when indicated Anand Jain
@ 2013-03-01 17:37   ` Eric Sandeen
  2013-03-04  5:20     ` Anand Jain
  2013-03-01 18:27   ` Zach Brown
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
  2 siblings, 1 reply; 22+ messages in thread
From: Eric Sandeen @ 2013-03-01 17:37 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs

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


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] btrfs-progs: traverse to backup super-block only when indicated
  2013-03-01 10:13 ` [PATCH] btrfs-progs: traverse to backup super-block only when indicated Anand Jain
  2013-03-01 17:37   ` Eric Sandeen
@ 2013-03-01 18:27   ` Zach Brown
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
  2 siblings, 0 replies; 22+ messages in thread
From: Zach Brown @ 2013-03-01 18:27 UTC (permalink / raw)
  To: Anand Jain; +Cc: linux-btrfs

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 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] btrfs-progs: traverse to backup super-block only when indicated
  2013-03-01 17:37   ` Eric Sandeen
@ 2013-03-04  5:20     ` Anand Jain
  0 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-04  5:20 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-btrfs



> 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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware
  2013-03-01 10:13 ` [PATCH] btrfs-progs: traverse to backup super-block only when indicated Anand Jain
  2013-03-01 17:37   ` Eric Sandeen
  2013-03-01 18:27   ` Zach Brown
@ 2013-03-27 10:07   ` Anand Jain
  2013-03-27 10:07     ` [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware Anand Jain
                       ` (5 more replies)
  2 siblings, 6 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-27 10:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba

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


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
@ 2013-03-27 10:07     ` Anand Jain
  2013-04-11  9:57       ` [obsoleted] " Anand Jain
  2013-03-27 10:07     ` [PATCH 2/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
                       ` (4 subsequent siblings)
  5 siblings, 1 reply; 22+ messages in thread
From: Anand Jain @ 2013-03-27 10:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba

 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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
  2013-03-27 10:07     ` [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware Anand Jain
@ 2013-03-27 10:07     ` Anand Jain
  2013-03-27 10:07     ` [PATCH 3/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super Anand Jain
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-27 10:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
  2013-03-27 10:07     ` [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware Anand Jain
  2013-03-27 10:07     ` [PATCH 2/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
@ 2013-03-27 10:07     ` Anand Jain
  2013-03-27 10:07     ` [PATCH 4/5 v5] btrfs-progs: introduce passing flags to btrfs_scan_one_device Anand Jain
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-27 10:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/5 v5] btrfs-progs: introduce passing flags to btrfs_scan_one_device
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
                       ` (2 preceding siblings ...)
  2013-03-27 10:07     ` [PATCH 3/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super Anand Jain
@ 2013-03-27 10:07     ` Anand Jain
  2013-03-27 10:07     ` [PATCH 5/5 v5] btrfs-progs: disable using backup superblock by default Anand Jain
  2013-03-27 23:17     ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware anand jain
  5 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-27 10:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/5 v5] btrfs-progs: disable using backup superblock by default
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
                       ` (3 preceding siblings ...)
  2013-03-27 10:07     ` [PATCH 4/5 v5] btrfs-progs: introduce passing flags to btrfs_scan_one_device Anand Jain
@ 2013-03-27 10:07     ` Anand Jain
  2013-03-27 23:17     ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware anand jain
  5 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-03-27 10:07 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware
  2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
                       ` (4 preceding siblings ...)
  2013-03-27 10:07     ` [PATCH 5/5 v5] btrfs-progs: disable using backup superblock by default Anand Jain
@ 2013-03-27 23:17     ` anand jain
  5 siblings, 0 replies; 22+ messages in thread
From: anand jain @ 2013-03-27 23:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: sandeen, dsterba


  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(-)
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* v6: access to backup superblock
  2013-02-22  5:29 [bug] mkfs.btrfs reports device busy for ext4 mounted disk Anand Jain
  2013-02-22 19:03 ` Zach Brown
  2013-03-01 10:13 ` [PATCH] btrfs-progs: traverse to backup super-block only when indicated Anand Jain
@ 2013-04-05  5:54 ` Anand Jain
  2013-04-05  5:54   ` [PATCH 1/5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
                     ` (4 more replies)
  2 siblings, 5 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-05  5:54 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
@ 2013-04-05  5:54   ` Anand Jain
  2013-04-05  5:54   ` [PATCH 2/5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super Anand Jain
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-05  5:54 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
  2013-04-05  5:54   ` [PATCH 1/5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
@ 2013-04-05  5:54   ` Anand Jain
  2013-04-05  5:54   ` [PATCH 3/5] btrfs-progs: introduce passing flags to btrfs_scan_one_device Anand Jain
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-05  5:54 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/5] btrfs-progs: introduce passing flags to btrfs_scan_one_device
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
  2013-04-05  5:54   ` [PATCH 1/5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
  2013-04-05  5:54   ` [PATCH 2/5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super Anand Jain
@ 2013-04-05  5:54   ` Anand Jain
  2013-04-05  5:54   ` [PATCH 4/5] btrfs-progs: disable using backup superblock by default Anand Jain
  2013-04-05  5:54   ` [PATCH 5/5] btrfs-progs: btrfs-find-root should scan backup-sb Anand Jain
  4 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-05  5:54 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/5] btrfs-progs: disable using backup superblock by default
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
                     ` (2 preceding siblings ...)
  2013-04-05  5:54   ` [PATCH 3/5] btrfs-progs: introduce passing flags to btrfs_scan_one_device Anand Jain
@ 2013-04-05  5:54   ` Anand Jain
  2013-04-05  5:54   ` [PATCH 5/5] btrfs-progs: btrfs-find-root should scan backup-sb Anand Jain
  4 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-05  5:54 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/5] btrfs-progs: btrfs-find-root should scan backup-sb
  2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
                     ` (3 preceding siblings ...)
  2013-04-05  5:54   ` [PATCH 4/5] btrfs-progs: disable using backup superblock by default Anand Jain
@ 2013-04-05  5:54   ` Anand Jain
  4 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-05  5:54 UTC (permalink / raw)
  To: linux-btrfs

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


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [obsoleted] [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware
  2013-03-27 10:07     ` [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware Anand Jain
@ 2013-04-11  9:57       ` Anand Jain
  0 siblings, 0 replies; 22+ messages in thread
From: Anand Jain @ 2013-04-11  9:57 UTC (permalink / raw)
  To: linux-btrfs


  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);
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2013-04-11  9:56 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-22  5:29 [bug] mkfs.btrfs reports device busy for ext4 mounted disk Anand Jain
2013-02-22 19:03 ` Zach Brown
2013-02-22 22:30   ` David Sterba
2013-03-01 10:18     ` Anand Jain
2013-03-01 10:13 ` [PATCH] btrfs-progs: traverse to backup super-block only when indicated Anand Jain
2013-03-01 17:37   ` Eric Sandeen
2013-03-04  5:20     ` Anand Jain
2013-03-01 18:27   ` Zach Brown
2013-03-27 10:07   ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware Anand Jain
2013-03-27 10:07     ` [PATCH 1/5 v5] btrfs-progs: make btrfs dev scan multi path aware Anand Jain
2013-04-11  9:57       ` [obsoleted] " Anand Jain
2013-03-27 10:07     ` [PATCH 2/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
2013-03-27 10:07     ` [PATCH 3/5 v5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super Anand Jain
2013-03-27 10:07     ` [PATCH 4/5 v5] btrfs-progs: introduce passing flags to btrfs_scan_one_device Anand Jain
2013-03-27 10:07     ` [PATCH 5/5 v5] btrfs-progs: disable using backup superblock by default Anand Jain
2013-03-27 23:17     ` [PATCH 0/5 v5] access to backup-sb and btrfs' multipath aware anand jain
2013-04-05  5:54 ` v6: access to backup superblock Anand Jain
2013-04-05  5:54   ` [PATCH 1/5] btrfs-progs: Introduce flag BTRFS_SCAN_REGISTER to replace run_ioctl Anand Jain
2013-04-05  5:54   ` [PATCH 2/5] btrfs-progs: Introduce flag BTRFS_SCAN_BACKUP_SB for btrfs_read_dev_super Anand Jain
2013-04-05  5:54   ` [PATCH 3/5] btrfs-progs: introduce passing flags to btrfs_scan_one_device Anand Jain
2013-04-05  5:54   ` [PATCH 4/5] btrfs-progs: disable using backup superblock by default Anand Jain
2013-04-05  5:54   ` [PATCH 5/5] btrfs-progs: btrfs-find-root should scan backup-sb Anand Jain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.