@@ -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]);
@@ -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];
@@ -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
@@ -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;
+}
@@ -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
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.jain@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(-)