* [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
* [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
* 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
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.