btrfs-progs: do a separate probe for transient replacing device
authorAnand Jain <anand.jain@oracle.com>
Mon, 18 Aug 2014 08:38:19 +0000 (16:38 +0800)
committerDavid Sterba <dsterba@suse.cz>
Fri, 10 Oct 2014 16:11:32 +0000 (18:11 +0200)
As mentioned in the kernel patch

btrfs: ioctl BTRFS_IOC_FS_INFO and
 BTRFS_IOC_DEV_INFO miss-matched with slots

The count as returned by BTRFS_IOC_FS_INFO is the number of slots that
btrfs-progs would allocate for the BTRFS_IOC_DEV_INFO ioctl. Since
BTRFS_IOC_DEV_INFO would loop across the seed devices, So its better
ioctl BTRFS_IOC_FS_INFO returns the total_devices instead of num_devices.

The above mentioned patch just does that. That is, it returns
total_devices instead of num_devices.

Which means we need to probe for the replacing device separately.

This patch will probe for the replacing device separately.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
utils.c

diff --git a/utils.c b/utils.c
index e9306b0..40b8f1a 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -1819,12 +1819,29 @@ int get_fs_info(char *path, struct btrfs_ioctl_fs_info_args *fi_args,
        if (!fi_args->num_devices)
                goto out;
 
-       di_args = *di_ret = malloc(fi_args->num_devices * sizeof(*di_args));
+       /*
+        * with kernel patch
+        * btrfs: ioctl BTRFS_IOC_FS_INFO and BTRFS_IOC_DEV_INFO miss-matched with slots
+        * the kernel now returns total_devices which does not include
+        * replacing device if running.
+        * As we need to get dev info of the replace device if it is running,
+        * so just add one to fi_args->num_devices.
+        */
+
+       di_args = *di_ret = malloc((fi_args->num_devices + 1) * sizeof(*di_args));
        if (!di_args) {
                ret = -errno;
                goto out;
        }
 
+       /* get the replace target device if it is there */
+       ret = get_device_info(fd, i, &di_args[ndevs]);
+       if (!ret) {
+               ndevs++;
+               fi_args->num_devices++;
+       }
+       i++;
+
        for (; i <= fi_args->max_id; ++i) {
                BUG_ON(ndevs >= fi_args->num_devices);
                ret = get_device_info(fd, i, &di_args[ndevs]);