Currently, btrsf fi show uses
/proc/partitions (by default) (with priority given
to dm-<x> over sd<y> paths) and with -d option would scan
/dev only (with /dev/mapper skipped since its a link).

However using /dev/mapper paths are in common practice
with mount, fstab, and lvm, so its better to be consistent
with them.

This patch uses the /dev/mapper on top of scanning
/proc/partitions and updates paths with /dev/mapper
paths where available (which takes care if some of
the disks is under blacklist).

Signed-off-by: Anand Jain <anand.j...@oracle.com>
---
 cmds-device.c     | 50 ++++++++++++++++++++++++++++----------------------
 cmds-filesystem.c | 24 ++++++++++++------------
 man/btrfs.8.in    |  5 +++--
 utils.c           | 33 ++++++++++++++++++++++++++++++---
 utils.h           |  1 +
 5 files changed, 74 insertions(+), 39 deletions(-)

diff --git a/cmds-device.c b/cmds-device.c
index 41e79d3..e3b80d6 100644
--- a/cmds-device.c
+++ b/cmds-device.c
@@ -178,50 +178,56 @@ static int cmd_rm_dev(int argc, char **argv)
 }
 
 static const char * const cmd_scan_dev_usage[] = {
-       "btrfs device scan [<device>...]",
+       "btrfs device scan [-d|<device>...]",
        "Scan devices for a btrfs filesystem",
+       "\t      -d use /dev to scan (skips /dev/mapper)\n"
+       "\t<device> use only this disk/dev/file to scan for btrfs",
        NULL
 };
 
 static int cmd_scan_dev(int argc, char **argv)
 {
-       int     i, fd, e;
-       int     checklist = 1;
-       int     devstart = 1;
+       int i, fd, e;
+       int checklist = 0;
+       int searchstart = 1;
+       int ret;
 
-       if( argc > 1 && !strcmp(argv[1],"--all-devices")){
-               if (check_argc_max(argc, 2))
+       optind = 1;
+       while(1) {
+               int c = getopt(argc, argv, "d");
+               if (c < 0)
+                       break;
+               switch(c) {
+               case 'd':
+                       checklist = 2;
+                       searchstart += 1;
+                       break;
+               default:
                        usage(cmd_scan_dev_usage);
-
-               checklist = 0;
-               devstart += 1;
+               }
        }
 
-       if(argc<=devstart){
-
-               int ret;
+       if (argc == searchstart) {
 
-               printf("Scanning for Btrfs filesystems\n");
-               if(checklist)
-                       ret = btrfs_scan_block_devices(1);
-               else
-                       ret = btrfs_scan_one_dir("/dev", 1);
-               if (ret){
-                       fprintf(stderr, "ERROR: error %d while scanning\n", 
ret);
+               ret = scan_devs_for_btrfs(checklist, 1);
+               if (ret) {
+                       fprintf(stderr, "ERROR: while scanning - %s\n",
+                               strerror(-ret));
                        return 18;
                }
                return 0;
        }
 
+       if (checklist != 0)
+               usage(cmd_scan_dev_usage);
+
        fd = open("/dev/btrfs-control", O_RDWR);
        if (fd < 0) {
                perror("failed to open /dev/btrfs-control");
                return 10;
        }
-
-       for( i = devstart ; i < argc ; i++ ){
+       for (i = searchstart; i < argc; i++) {
                struct btrfs_ioctl_vol_args args;
-               int ret;
 
                printf("Scanning for Btrfs filesystems in '%s'\n", argv[i]);
 
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index 470de31..43a222b 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -232,9 +232,12 @@ static void print_one_uuid(struct btrfs_fs_devices 
*fs_devices)
 }
 
 static const char * const cmd_show_usage[] = {
-       "btrfs filesystem show [-d] [<uuid>]",
+       "btrfs filesystem show [-d|<fsid>]",
        "Show the structure of a filesystem",
-       "If no argument is given, structure of all present filesystems is 
shown.",
+       "\tIf no argument is given, structure of all present filesystems is 
shown\n"
+       "\tIf no option is given, scans /proc/partitions and /dev/mapper\n"
+       "\t    -d scans /dev only (does not pick /dev/mapper though)\n"
+       "\t<fsid> shows structure of the filesystem",
        NULL
 };
 
@@ -244,8 +247,8 @@ static int cmd_show(int argc, char **argv)
        struct btrfs_fs_devices *fs_devices;
        struct list_head *cur_uuid;
        char *search = 0;
-       int ret;
-       int checklist = 1;
+       int ret = 0;
+       int checklist = 0;
        int searchstart = 1;
 
        optind = 1;
@@ -255,7 +258,7 @@ static int cmd_show(int argc, char **argv)
                        break;
                switch(c) {
                case 'd':
-                       checklist = 0;
+                       checklist = 2;
                        searchstart += 1;
                        break;
                default:
@@ -266,16 +269,13 @@ static int cmd_show(int argc, char **argv)
        if (check_argc_max(argc, searchstart + 1))
                usage(cmd_show_usage);
 
-       if(checklist)
-               ret = btrfs_scan_block_devices(0);
-       else
-               ret = btrfs_scan_one_dir("/dev", 0);
-
+       ret = scan_devs_for_btrfs(checklist, 0);
        if (ret){
-               fprintf(stderr, "ERROR: error %d while scanning\n", ret);
+               fprintf(stderr, "ERROR: while scanning - %s\n",
+                       strerror(-ret));
                return 18;
        }
-       
+
        if(searchstart < argc)
                search = argv[searchstart];
 
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 8105019..9a68246 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -282,11 +282,12 @@ NOTE: Currently there are the following limitations:
 - the filesystem should not have more than one device.
 .TP
 
-\fBfilesystem show\fR [-d] [<uuid>]\fR
+\fBfilesystem show\fR [-d|m] [<uuid>]\fR
 Show the btrfs filesystem with some additional info. If no \fIUUID\fP
 is passed, \fBbtrfs\fR show info of all the btrfs filesystem.
 If \fB-d\fP is passed, all the devices under /dev are scanned;
-otherwise the devices list is extracted from the /proc/partitions file.
+otherwise the devices list is extracted from the /proc/partitions
+and /dev/mapper.
 .TP
 
 \fBfilesystem balance\fR \fI<path>\fR
diff --git a/utils.c b/utils.c
index 7b4cd74..663670b 100644
--- a/utils.c
+++ b/utils.c
@@ -1018,6 +1018,7 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl)
        struct list_head pending_list;
        struct btrfs_fs_devices *tmp_devices;
        u64 num_devices;
+       int skip_link = 1;
 
        INIT_LIST_HEAD(&pending_list);
 
@@ -1026,6 +1027,9 @@ int btrfs_scan_one_dir(char *dirname, int run_ioctl)
                return -ENOMEM;
        strcpy(pending->name, dirname);
 
+       if (!strncmp(dirname, "/dev/mapper", strlen("/dev/mapper")))
+               skip_link = 0;
+
 again:
        dirname_len = strlen(pending->name);
        fullpath = malloc(PATH_MAX);
@@ -1057,7 +1061,7 @@ again:
                        fprintf(stderr, "failed to stat %s\n", fullpath);
                        continue;
                }
-               if (S_ISLNK(st.st_mode))
+               if (skip_link && S_ISLNK(st.st_mode))
                        continue;
                if (S_ISDIR(st.st_mode)) {
                        struct pending_dir *next = malloc(sizeof(*next));
@@ -1068,9 +1072,9 @@ again:
                        strcpy(next->name, fullpath);
                        list_add_tail(&next->list, &pending_list);
                }
-               if (!S_ISBLK(st.st_mode)) {
+               if (skip_link && !S_ISBLK(st.st_mode))
                        continue;
-               }
+
                fd = open(fullpath, O_RDONLY);
                if (fd < 0) {
                        /* ignore the following errors:
@@ -1807,3 +1811,26 @@ int test_dev_for_mkfs(char *file, int force_overwrite, 
char *estr)
        close(fd);
        return 0;
 }
+
+int scan_devs_for_btrfs(int where, int update_kernel)
+{
+       int ret = 0;
+
+       switch (where) {
+       case 0:
+               ret = btrfs_scan_block_devices(update_kernel);
+
+               /* /dev/mapper unified path is most
+                * prefered if enabled for disks,
+                * so use it  which would replace the
+                * disks found in above
+               */
+               if (!ret)
+                       btrfs_scan_one_dir("/dev/mapper", update_kernel);
+               break;
+       case 2:
+               ret = btrfs_scan_one_dir("/dev", update_kernel);
+               break;
+       }
+       return ret;
+}
diff --git a/utils.h b/utils.h
index 3c17e14..375c15a 100644
--- a/utils.h
+++ b/utils.h
@@ -65,5 +65,6 @@ u64 btrfs_device_size(int fd, struct stat *st);
 /* Helper to always get proper size of the destination string */
 #define strncpy_null(dest, src) __strncpy__null(dest, src, sizeof(dest))
 int test_dev_for_mkfs(char *file, int force_overwrite, char *estr);
+int scan_devs_for_btrfs(int where, int update_kernel);
 
 #endif
-- 
1.8.1.227.g44fe835

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to