* [PATCH 1/3 v3] btrfs-progs: there is devid 0 when replace is running @ 2014-02-24 11:43 Anand Jain 2014-02-24 11:43 ` [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid Anand Jain 2014-02-24 11:43 ` [PATCH 3/3] btrfs-progs: Fix bug when scanned for devid which was missing and deleted Anand Jain 0 siblings, 2 replies; 5+ messages in thread From: Anand Jain @ 2014-02-24 11:43 UTC (permalink / raw) To: linux-btrfs From: Anand Jain <anand.jain@oracle.com> as of now, when we replace a disk, it is added to the dev list with devid 0. And we fail to obtain details of devid 0 because we don't query devid 0 at all. reproducer: btrfs rep start /dev/sdb /dev/sdf /btrfs btrfs fi show Label: none uuid: f8fb9819-16c8-47b7-b62f-0ff90f8c56cd Total devices 3 FS bytes used 1.94GiB devid 1 size 1.10GiB used 1.10GiB path /dev/sdb devid 2 size 1.10GiB used 1.08GiB path /dev/sdc devid 0 size 0.00 used 0.00 path this patch will make it proper by querying devid 0. btrfs repl start /dev/sdb /dev/sdf /btrfs btrfs fi show /btrfs Label: none uuid: f8fb9819-16c8-47b7-b62f-0ff90f8c56cd Total devices 3 FS bytes used 1.94GiB devid 0 size 1.10GiB used 1.10GiB path /dev/sdf devid 1 size 1.10GiB used 1.10GiB path /dev/sdb devid 2 size 1.10GiB used 1.08GiB path /dev/sdc Its fine to query devid 0 when there is no replace activity as well, because we just skip the error ENODEV btrfs fi show /btrfs Label: none uuid: f8fb9819-16c8-47b7-b62f-0ff90f8c56cd Total devices 2 FS bytes used 1.94GiB devid 1 size 1.10GiB used 1.10GiB path /dev/sdf devid 2 size 1.10GiB used 1.08GiB path /dev/sdc Signed-off-by: Anand Jain <Anand.Jain@oracle.com> --- v3: it needs to handle per devid probe v2: commit message fix utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.c b/utils.c index de513b6..e0c750d 100644 --- a/utils.c +++ b/utils.c @@ -1637,7 +1637,7 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, int fd = -1; int ret = 0; int ndevs = 0; - int i = 1; + int i = 0; struct btrfs_fs_devices *fs_devices_mnt = NULL; struct btrfs_ioctl_dev_info_args *di_args; char mp[BTRFS_PATH_NAME_MAX + 1]; -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid 2014-02-24 11:43 [PATCH 1/3 v3] btrfs-progs: there is devid 0 when replace is running Anand Jain @ 2014-02-24 11:43 ` Anand Jain 2014-02-25 17:27 ` David Sterba 2014-02-24 11:43 ` [PATCH 3/3] btrfs-progs: Fix bug when scanned for devid which was missing and deleted Anand Jain 1 sibling, 1 reply; 5+ messages in thread From: Anand Jain @ 2014-02-24 11:43 UTC (permalink / raw) To: linux-btrfs btrfs-progs picks the latest_dev based on first probed greatest trans-id. However below test case proofs that approach is wrong. $ mkfs.btrfs -d raid1 -m raid1 /dev/sde /dev/sdf $ modprobe -r btrfs && modprobe btrfs $ mount -o degraded /dev/sde /btrfs $ touch /btrfs/testfile && btrfs fi sync /btrfs The above steps will make /dev/sdf not part of the btrfs. and as below when you use /dev/sdf the btrfs dev stat and dev scrub picks up wrong disk $ btrfs dev stat /dev/sdf [/dev/sde].write_io_errs 0 [/dev/sde].read_io_errs 0 [/dev/sde].flush_io_errs 0 [/dev/sde].corruption_errs 0 [/dev/sde].generation_errs 0 $ btrfs scrub start -B /dev/sdf scrub done for 2e99c881-6abd-4f8a-8290-e2f8d0acc575 scrub started at Mon Feb 24 14:45:06 2014 and finished after 0 seconds total bytes scrubbed: 256.00KiB with 0 errors Signed-off-by: Anand Jain <Anand.Jain@oracle.com> --- utils.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/utils.c b/utils.c index e0c750d..231031e 100644 --- a/utils.c +++ b/utils.c @@ -1646,6 +1646,11 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, memset(fi_args, 0, sizeof(*fi_args)); if (is_block_device(path)) { + + struct btrfs_super_block *disk_super; + char *buf; + u64 devid; + /* Ensure it's mounted, then set path to the mountpoint */ fd = open(path, O_RDONLY); if (fd < 0) { @@ -1665,8 +1670,23 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, path = mp; /* Only fill in this one device */ fi_args->num_devices = 1; - fi_args->max_id = fs_devices_mnt->latest_devid; - i = fs_devices_mnt->latest_devid; + + buf = malloc(4096); + if (!buf) { + ret = -ENOMEM; + goto out; + } + disk_super = (struct btrfs_super_block *)buf; + ret = btrfs_read_dev_super(fd, disk_super, BTRFS_SUPER_INFO_OFFSET); + if (ret < 0) { + ret = -EIO; + goto out; + } + devid = btrfs_stack_device_id(&disk_super->dev_item); + + fi_args->max_id = devid; + i = devid; + memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE); close(fd); } -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid 2014-02-24 11:43 ` [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid Anand Jain @ 2014-02-25 17:27 ` David Sterba 2014-02-26 2:06 ` Anand Jain 0 siblings, 1 reply; 5+ messages in thread From: David Sterba @ 2014-02-25 17:27 UTC (permalink / raw) To: Anand Jain; +Cc: linux-btrfs On Mon, Feb 24, 2014 at 07:43:38PM +0800, Anand Jain wrote: > @@ -1646,6 +1646,11 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, > memset(fi_args, 0, sizeof(*fi_args)); > > if (is_block_device(path)) { > + > + struct btrfs_super_block *disk_super; > + char *buf; > + u64 devid; > + > /* Ensure it's mounted, then set path to the mountpoint */ > fd = open(path, O_RDONLY); > if (fd < 0) { > @@ -1665,8 +1670,23 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, > path = mp; > /* Only fill in this one device */ > fi_args->num_devices = 1; > - fi_args->max_id = fs_devices_mnt->latest_devid; > - i = fs_devices_mnt->latest_devid; > + > + buf = malloc(4096); > + if (!buf) { > + ret = -ENOMEM; > + goto out; > + } > + disk_super = (struct btrfs_super_block *)buf; > + ret = btrfs_read_dev_super(fd, disk_super, BTRFS_SUPER_INFO_OFFSET); > + if (ret < 0) { > + ret = -EIO; > + goto out; > + } > + devid = btrfs_stack_device_id(&disk_super->dev_item); > + > + fi_args->max_id = devid; > + i = devid; > + > memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE); > close(fd); This is leaking memory, but as this is userspace code we can use the staack for the superblock. I've committed this with the following fixup: --- a/utils.c +++ b/utils.c @@ -1680,7 +1680,7 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, if (is_block_device(path)) { struct btrfs_super_block *disk_super; - char *buf; + char buf[BTRFS_SUPER_INFO_SIZE]; u64 devid; /* Ensure it's mounted, then set path to the mountpoint */ @@ -1703,11 +1703,6 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, /* Only fill in this one device */ fi_args->num_devices = 1; - buf = malloc(4096); - if (!buf) { - ret = -ENOMEM; - goto out; - } disk_super = (struct btrfs_super_block *)buf; ret = btrfs_read_dev_super(fd, disk_super, BTRFS_SUPER_INFO_OFFSET); if (ret < 0) { ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid 2014-02-25 17:27 ` David Sterba @ 2014-02-26 2:06 ` Anand Jain 0 siblings, 0 replies; 5+ messages in thread From: Anand Jain @ 2014-02-26 2:06 UTC (permalink / raw) To: dsterba; +Cc: linux-btrfs On 26/02/2014 01:27, David Sterba wrote: > On Mon, Feb 24, 2014 at 07:43:38PM +0800, Anand Jain wrote: >> @@ -1646,6 +1646,11 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, >> memset(fi_args, 0, sizeof(*fi_args)); >> >> if (is_block_device(path)) { >> + >> + struct btrfs_super_block *disk_super; >> + char *buf; >> + u64 devid; >> + >> /* Ensure it's mounted, then set path to the mountpoint */ >> fd = open(path, O_RDONLY); >> if (fd < 0) { >> @@ -1665,8 +1670,23 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, >> path = mp; >> /* Only fill in this one device */ >> fi_args->num_devices = 1; >> - fi_args->max_id = fs_devices_mnt->latest_devid; >> - i = fs_devices_mnt->latest_devid; >> + >> + buf = malloc(4096); >> + if (!buf) { >> + ret = -ENOMEM; >> + goto out; >> + } >> + disk_super = (struct btrfs_super_block *)buf; >> + ret = btrfs_read_dev_super(fd, disk_super, BTRFS_SUPER_INFO_OFFSET); >> + if (ret < 0) { >> + ret = -EIO; >> + goto out; >> + } >> + devid = btrfs_stack_device_id(&disk_super->dev_item); >> + >> + fi_args->max_id = devid; >> + i = devid; >> + >> memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE); >> close(fd); > > This is leaking memory, but as this is userspace code we can use the > staack for the superblock. I've committed this with the following fixup: oh no my bad. thanks for the catch. > --- a/utils.c > +++ b/utils.c > @@ -1680,7 +1680,7 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, > if (is_block_device(path)) { > > struct btrfs_super_block *disk_super; > - char *buf; > + char buf[BTRFS_SUPER_INFO_SIZE]; > u64 devid; > > /* Ensure it's mounted, then set path to the mountpoint */ > @@ -1703,11 +1703,6 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, > /* Only fill in this one device */ > fi_args->num_devices = 1; > > - buf = malloc(4096); > - if (!buf) { > - ret = -ENOMEM; > - goto out; > - } > disk_super = (struct btrfs_super_block *)buf; > ret = btrfs_read_dev_super(fd, disk_super, BTRFS_SUPER_INFO_OFFSET); > if (ret < 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 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/3] btrfs-progs: Fix bug when scanned for devid which was missing and deleted 2014-02-24 11:43 [PATCH 1/3 v3] btrfs-progs: there is devid 0 when replace is running Anand Jain 2014-02-24 11:43 ` [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid Anand Jain @ 2014-02-24 11:43 ` Anand Jain 1 sibling, 0 replies; 5+ messages in thread From: Anand Jain @ 2014-02-24 11:43 UTC (permalink / raw) To: linux-btrfs get_fs_info() provides the info of the specific device/devid, however when we delete the missing disk the super-block on the disk isn't cleared, and since btrfs-progs makes its decision by reading the disk super block, so it doesn't know about the kernel previous action, And now when we tried to probe kernel for the devid it fails. reproducer: $ mkfs.btrfs -d raid1 -m raid1 /dev/sde /dev/sdf $ modprobe -r btrfs && modprobe btrfs $ mount -o degraded /dev/sde /btrfs $ btrfs dev add /dev/sdd /btrfs $ btrfs dev del missing /btrfs $ btrfs scrub start -B /dev/sdf btrfs: utils.c:1741: get_fs_info: Assertion `!(ndevs == 0)' failed. Aborted (core dumped) Signed-off-by: Anand Jain <Anand.Jain@oracle.com> --- utils.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/utils.c b/utils.c index 231031e..bce92ab 100644 --- a/utils.c +++ b/utils.c @@ -1726,8 +1726,15 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args, ndevs++; } - BUG_ON(ndevs == 0); - ret = 0; + /* + * only when the only dev we wanted to find is not there then + * let any error be returned + */ + if (fi_args->num_devices != 1) { + BUG_ON(ndevs == 0); + ret = 0; + } + out: close_file_or_dir(fd, dirstream); return ret; -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-02-26 2:07 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-02-24 11:43 [PATCH 1/3 v3] btrfs-progs: there is devid 0 when replace is running Anand Jain 2014-02-24 11:43 ` [PATCH 2/3] btrfs-progs: latest_devid is not always the probed devid Anand Jain 2014-02-25 17:27 ` David Sterba 2014-02-26 2:06 ` Anand Jain 2014-02-24 11:43 ` [PATCH 3/3] btrfs-progs: Fix bug when scanned for devid which was missing and deleted 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.