* [PATCH 1/4] btrfs-progs: make filesystem show by label work
@ 2013-11-04 3:45 Anand Jain
2013-11-04 3:45 ` [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control Anand Jain
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-04 3:45 UTC (permalink / raw)
To: linux-btrfs; +Cc: jbacik, zab, dsterba
with design revamp around filesystem show the fsid filter
by label wasn't planned. but apparently that seemed to be
necessary. this patch will fix it.
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
cmds-filesystem.c | 120 ++++++++++++++++++++++++++++++++---------------------
1 files changed, 73 insertions(+), 47 deletions(-)
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index d08007e..d2cad81 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -179,6 +179,26 @@ static int cmd_df(int argc, char **argv)
return !!ret;
}
+static int match_search_item_kernel(__u8 *fsid, char *mnt, char *label,
+ char *search)
+{
+ char uuidbuf[37];
+ int search_len = strlen(search);
+
+ search_len = min(search_len, 37);
+ uuid_unparse(fsid, uuidbuf);
+ if (!strncmp(uuidbuf, search, search_len))
+ return 1;
+
+ if (strlen(label) && strcmp(label, search) == 0)
+ return 1;
+
+ if (strcmp(mnt, search) == 0)
+ return 1;
+
+ return 0;
+}
+
static int uuid_search(struct btrfs_fs_devices *fs_devices, char *search)
{
char uuidbuf[37];
@@ -275,16 +295,18 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
struct btrfs_ioctl_dev_info_args *tmp_dev_info;
uuid_unparse(fs_info->fsid, uuidbuf);
- printf("Label: %s uuid: %s\n",
- strlen(label) ? label : "none", uuidbuf);
+ if (label && strlen(label))
+ printf("Label: '%s' ", label);
+ else
+ printf("Label: none ");
- printf("\tTotal devices %llu FS bytes used %s\n",
- fs_info->num_devices,
+ printf(" uuid: %s\n\tTotal devices %llu FS bytes used %s\n", uuidbuf,
+ fs_info->num_devices,
pretty_size(calc_used_bytes(space_info)));
for (i = 0; i < fs_info->num_devices; i++) {
tmp_dev_info = (struct btrfs_ioctl_dev_info_args *)&dev_info[i];
- printf("\tdevid %llu size %s used %s path %s\n",
+ printf("\tdevid %4llu size %s used %s path %s\n",
tmp_dev_info->devid,
pretty_size(tmp_dev_info->total_bytes),
pretty_size(tmp_dev_info->bytes_used),
@@ -308,7 +330,7 @@ static int check_arg_type(char *input)
char path[PATH_MAX];
if (!input)
- return BTRFS_ARG_UNKNOWN;
+ return -EINVAL;
if (realpath(input, path)) {
if (is_block_device(input) == 1)
@@ -320,7 +342,7 @@ static int check_arg_type(char *input)
return BTRFS_ARG_UNKNOWN;
}
- if (!uuid_parse(input, out))
+ if (strlen(input) == 36 && !uuid_parse(input, out))
return BTRFS_ARG_UUID;
return BTRFS_ARG_UNKNOWN;
@@ -328,23 +350,19 @@ static int check_arg_type(char *input)
static int btrfs_scan_kernel(void *search)
{
- int ret = 0, fd, type;
+ int ret = 0, fd;
FILE *f;
struct mntent *mnt;
struct btrfs_ioctl_fs_info_args fs_info_arg;
struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
struct btrfs_ioctl_space_args *space_info_arg;
char label[BTRFS_LABEL_SIZE];
- uuid_t uuid;
f = setmntent("/proc/self/mounts", "r");
if (f == NULL)
return 1;
- type = check_arg_type(search);
- if (type == BTRFS_ARG_BLKDEV)
- return 1;
-
+ memset(label, 0, sizeof(label));
while ((mnt = getmntent(f)) != NULL) {
if (strcmp(mnt->mnt_type, "btrfs"))
continue;
@@ -353,38 +371,36 @@ static int btrfs_scan_kernel(void *search)
if (ret)
return ret;
- switch (type) {
- case BTRFS_ARG_UUID:
- ret = uuid_parse(search, uuid);
- if (ret)
- return 1;
- if (uuid_compare(fs_info_arg.fsid, uuid))
- continue;
- break;
- case BTRFS_ARG_MNTPOINT:
- if (strcmp(search, mnt->mnt_dir))
- continue;
- break;
- case BTRFS_ARG_UNKNOWN:
- break;
+ if (get_label_mounted(mnt->mnt_dir, label)) {
+ kfree(dev_info_arg);
+ return 1;
+ }
+ if (search && !match_search_item_kernel(fs_info_arg.fsid,
+ mnt->mnt_dir, label, search)) {
+ kfree(dev_info_arg);
+ continue;
}
fd = open(mnt->mnt_dir, O_RDONLY);
if (fd > 0 && !get_df(fd, &space_info_arg)) {
- get_label_mounted(mnt->mnt_dir, label);
print_one_fs(&fs_info_arg, dev_info_arg,
space_info_arg, label, mnt->mnt_dir);
- free(space_info_arg);
+ kfree(space_info_arg);
+ memset(label, 0, sizeof(label));
}
if (fd > 0)
close(fd);
- free(dev_info_arg);
+ kfree(dev_info_arg);
+ if (search)
+ return 0;
}
- return ret;
+ if (search)
+ return 1;
+ return 0;
}
static const char * const cmd_show_usage[] = {
- "btrfs filesystem show [options] [<path>|<uuid>|<device>]",
+ "btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
"Show the structure of a filesystem",
"-d|--all-devices show only disks under /dev containing btrfs filesystem",
"-m|--mounted show only mounted btrfs",
@@ -402,6 +418,7 @@ static int cmd_show(int argc, char **argv)
int where = BTRFS_SCAN_LBLKID;
int type = 0;
char mp[BTRFS_PATH_NAME_MAX + 1];
+ char path[PATH_MAX];
while (1) {
int long_index;
@@ -426,24 +443,31 @@ static int cmd_show(int argc, char **argv)
}
}
- if (where == BTRFS_SCAN_LBLKID) {
- if (check_argc_max(argc, optind + 1))
- usage(cmd_show_usage);
- } else {
- if (check_argc_max(argc, optind))
- usage(cmd_show_usage);
- }
+ if (check_argc_max(argc, optind + 1))
+ usage(cmd_show_usage);
+
if (argc > optind) {
search = argv[optind];
- type = check_arg_type(search);
- if (type == BTRFS_ARG_UNKNOWN) {
- fprintf(stderr, "ERROR: arg type unknown\n");
+ if (strlen(search) == 0)
usage(cmd_show_usage);
- }
+ type = check_arg_type(search);
if (type == BTRFS_ARG_BLKDEV) {
- ret = get_btrfs_mount(search, mp, sizeof(mp));
- if (ret == 0)
- search = mp;
+ if (where == BTRFS_SCAN_DEV) {
+ /* we need to do this because
+ * legacy BTRFS_SCAN_DEV
+ * provides /dev/dm-x paths
+ */
+ if (realpath(search, path))
+ search = path;
+ } else {
+ ret = get_btrfs_mount(search,
+ mp, sizeof(mp));
+ if (!ret)
+ /* given block dev is mounted*/
+ search = mp;
+ else
+ goto devs_only;
+ }
}
}
@@ -451,7 +475,9 @@ static int cmd_show(int argc, char **argv)
goto devs_only;
/* show mounted btrfs */
- btrfs_scan_kernel(search);
+ ret = btrfs_scan_kernel(search);
+ if (search && !ret)
+ return 0;
/* shows mounted only */
if (where == BTRFS_SCAN_MOUNTED)
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control
2013-11-04 3:45 [PATCH 1/4] btrfs-progs: make filesystem show by label work Anand Jain
@ 2013-11-04 3:45 ` Anand Jain
2013-11-06 20:13 ` Josef Bacik
2013-11-04 3:45 ` [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted Anand Jain
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Anand Jain @ 2013-11-04 3:45 UTC (permalink / raw)
To: linux-btrfs; +Cc: jbacik, zab, dsterba
need fsinfo from btrfs-control that is when mount path is
not known.
current method of going through each mount points isn't
efficient, and multiple subvol of a fsid could be mounted
means extra logic to handle that. Further this will help
to revamp check_mounted() (planned)
check_mounted is heavily used in the btrfs-progs, it
does full scan of all the disks in the system to confirm
if a multi-disk btrfs is mounted it doesn't scalable well
with few hundreds luns, check_mounted for sure needs a
revamp. using this it can be done easily. which is planned.
v2: commit reword
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
ioctl.h | 19 +++++++++++++++
utils.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
utils.h | 1 +
3 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/ioctl.h b/ioctl.h
index d21413f..29575d8 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
}
}
+/* fs flags */
+#define BTRFS_FS_MOUNTED (1LLU << 0)
+
+struct btrfs_ioctl_fslist {
+ __u64 self_sz; /* in/out */
+ __u8 fsid[BTRFS_FSID_SIZE]; /* out */
+ __u64 num_devices;
+ __u64 missing_devices;
+ __u64 total_devices;
+ __u64 flags;
+};
+
+struct btrfs_ioctl_fslist_args {
+ __u64 self_sz; /* in/out */
+ __u64 count; /* out */
+};
+
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_dev_replace_args)
#define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \
struct btrfs_ioctl_dedup_args)
+#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \
+ struct btrfs_ioctl_fslist_args)
#ifdef __cplusplus
}
#endif
diff --git a/utils.c b/utils.c
index 5bedd97..1798a7c 100644
--- a/utils.c
+++ b/utils.c
@@ -2087,3 +2087,83 @@ int lookup_ino_rootid(int fd, u64 *rootid)
return 0;
}
+
+/* scans for fsid(s) in the kernel using the btrfs-control
+ * interface.
+ */
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count)
+{
+ int ret, fd, e;
+ struct btrfs_ioctl_fslist_args *fsargs;
+ struct btrfs_ioctl_fslist *fslist;
+ struct btrfs_ioctl_fslist *fslist_tmp;
+ u64 sz;
+ int count;
+
+ fd = open("/dev/btrfs-control", O_RDWR);
+ e = errno;
+ if (fd < 0) {
+ perror("failed to open /dev/btrfs-control");
+ return -e;
+ }
+
+ /* space to hold 512 fsids, doesn't matter if small
+ * it would fail and return count so then we try again
+ */
+ count = 512;
+again:
+ sz = sizeof(*fsargs) + sizeof(*fslist) * count;
+
+ fsargs = (struct btrfs_ioctl_fslist_args *) malloc(sz);
+ memset(fsargs, 0, sz);
+
+ if (!fsargs) {
+ close(fd);
+ return -ENOMEM;
+ }
+ fsargs->count = count;
+
+ ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs);
+ e = errno;
+ if (ret == 1) {
+ /* out of size so reallocate */
+ count = fsargs->count;
+ free(fsargs);
+ goto again;
+ } else if (ret < 0) {
+ printf("ERROR: scan_fsid ioctl failed - %s\n",
+ strerror(e));
+ ret = -e;
+ goto out;
+ }
+
+ /* ioctl returns fsid count in count parameter*/
+
+ *out_count = count = fsargs->count;
+ if (count == 0) {
+ *out_fslist = NULL;
+ ret = 0;
+ goto out;
+ }
+
+ fslist = (struct btrfs_ioctl_fslist *) (fsargs +
+ sizeof(*fsargs));
+
+ fslist_tmp = *out_fslist = (struct btrfs_ioctl_fslist *)
+ malloc(sizeof(*fslist) * count);
+ if (!fslist_tmp) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ while (count--) {
+ memcpy(fslist_tmp, fslist, sizeof(*fslist));
+ fslist_tmp = fslist_tmp + sizeof(*fslist_tmp);
+ fslist = fslist + sizeof(*fslist);
+ }
+ ret = 0;
+out:
+ free(fsargs);
+ close(fd);
+ return 0;
+}
diff --git a/utils.h b/utils.h
index 6f4b10c..e20ad74 100644
--- a/utils.h
+++ b/utils.h
@@ -94,5 +94,6 @@ int ask_user(char *question);
int lookup_ino_rootid(int fd, u64 *rootid);
int btrfs_scan_lblkid(int update_kernel);
int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count);
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted
2013-11-04 3:45 [PATCH 1/4] btrfs-progs: make filesystem show by label work Anand Jain
2013-11-04 3:45 ` [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control Anand Jain
@ 2013-11-04 3:45 ` Anand Jain
2013-11-06 20:19 ` Josef Bacik
2013-11-04 3:45 ` [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input Anand Jain
2013-11-07 10:06 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
3 siblings, 1 reply; 12+ messages in thread
From: Anand Jain @ 2013-11-04 3:45 UTC (permalink / raw)
To: linux-btrfs; +Cc: jbacik, zab, dsterba
as of now with out this patch user would see
fsinfo per btrfs mount path but which mean multiple
entry if more than one subvol is mounted of the same
fsid. so this patch will handle that nicely.
v2: accepts Zach suggested
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
cmds-filesystem.c | 90 +++++++++++++++++++++++++++++++++--------------------
utils.c | 88 ++++++++++++++++++++++++++++++++++++++++++---------
utils.h | 3 +-
3 files changed, 130 insertions(+), 51 deletions(-)
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index d2cad81..f8e8475 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -317,6 +317,29 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
return 0;
}
+static void handle_print(char *mnt, char *label)
+{
+ int fd;
+ struct btrfs_ioctl_fs_info_args fs_info_arg;
+ struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
+ struct btrfs_ioctl_space_args *space_info_arg;
+
+ if (get_fs_info(mnt, &fs_info_arg, &dev_info_arg)) {
+ fprintf(stdout, "ERROR: get_fs_info failed\n");
+ return;
+ }
+
+ fd = open(mnt, O_RDONLY);
+ if (fd > 0 && !get_df(fd, &space_info_arg)) {
+ print_one_fs(&fs_info_arg, dev_info_arg,
+ space_info_arg, label, mnt);
+ kfree(space_info_arg);
+ }
+ if (fd > 0)
+ close(fd);
+ kfree(dev_info_arg);
+}
+
/* This function checks if the given input parameter is
* an uuid or a path
* return -1: some error in the given input
@@ -350,47 +373,39 @@ static int check_arg_type(char *input)
static int btrfs_scan_kernel(void *search)
{
- int ret = 0, fd;
- FILE *f;
- struct mntent *mnt;
- struct btrfs_ioctl_fs_info_args fs_info_arg;
- struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
- struct btrfs_ioctl_space_args *space_info_arg;
+ int ret = 0;
char label[BTRFS_LABEL_SIZE];
-
- f = setmntent("/proc/self/mounts", "r");
- if (f == NULL)
- return 1;
-
- memset(label, 0, sizeof(label));
- while ((mnt = getmntent(f)) != NULL) {
- if (strcmp(mnt->mnt_type, "btrfs"))
+ char mnt[BTRFS_PATH_NAME_MAX + 1];
+ struct btrfs_ioctl_fslist *fslist;
+ struct btrfs_ioctl_fslist *fslist_saved;
+ u64 cnt_fs;
+ int cnt_mnt;
+ __u8 *fsid;
+ __u64 flags;
+
+ ret = get_fslist(&fslist, &cnt_fs);
+ if (ret)
+ return ret;
+ fslist_saved = fslist;
+ while (cnt_fs--) {
+ fsid = fslist->fsid;
+ flags = fslist->flags;
+ fslist++;
+ if (!(flags & BTRFS_FS_MOUNTED))
continue;
- ret = get_fs_info(mnt->mnt_dir, &fs_info_arg,
- &dev_info_arg);
+ memset(mnt, 0, BTRFS_PATH_NAME_MAX + 1);
+ memset(label, 0, sizeof(label));
+ ret = fsid_to_mntpt(fsid, mnt, &cnt_mnt);
if (ret)
return ret;
-
- if (get_label_mounted(mnt->mnt_dir, label)) {
- kfree(dev_info_arg);
+ if (get_label_mounted(mnt, label))
return 1;
- }
- if (search && !match_search_item_kernel(fs_info_arg.fsid,
- mnt->mnt_dir, label, search)) {
- kfree(dev_info_arg);
+
+ if (search && !match_search_item_kernel(fsid,
+ mnt, label, search))
continue;
- }
- fd = open(mnt->mnt_dir, O_RDONLY);
- if (fd > 0 && !get_df(fd, &space_info_arg)) {
- print_one_fs(&fs_info_arg, dev_info_arg,
- space_info_arg, label, mnt->mnt_dir);
- kfree(space_info_arg);
- memset(label, 0, sizeof(label));
- }
- if (fd > 0)
- close(fd);
- kfree(dev_info_arg);
+ handle_print(mnt, label);
if (search)
return 0;
}
@@ -469,6 +484,13 @@ static int cmd_show(int argc, char **argv)
goto devs_only;
}
}
+ if (type == BTRFS_ARG_MNTPOINT) {
+ char label[BTRFS_LABEL_SIZE];
+ if (get_label_mounted(search, label))
+ return 1;
+ handle_print(search, label);
+ return 0;
+ }
}
if (where == BTRFS_SCAN_DEV)
diff --git a/utils.c b/utils.c
index 1798a7c..d466ffa 100644
--- a/utils.c
+++ b/utils.c
@@ -47,6 +47,7 @@
#include "utils.h"
#include "volumes.h"
#include "ioctl.h"
+#include "btrfs-list.h"
#ifndef BLKDISCARD
#define BLKDISCARD _IO(0x12,119)
@@ -2091,12 +2092,12 @@ int lookup_ino_rootid(int fd, u64 *rootid)
/* scans for fsid(s) in the kernel using the btrfs-control
* interface.
*/
-int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count)
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count)
{
int ret, fd, e;
struct btrfs_ioctl_fslist_args *fsargs;
+ struct btrfs_ioctl_fslist_args *fsargs_saved = NULL;
struct btrfs_ioctl_fslist *fslist;
- struct btrfs_ioctl_fslist *fslist_tmp;
u64 sz;
int count;
@@ -2139,31 +2140,86 @@ again:
/* ioctl returns fsid count in count parameter*/
- *out_count = count = fsargs->count;
- if (count == 0) {
+ *out_count = fsargs->count;
+ if (*out_count == 0) {
*out_fslist = NULL;
ret = 0;
goto out;
}
- fslist = (struct btrfs_ioctl_fslist *) (fsargs +
- sizeof(*fsargs));
+ fsargs_saved = fsargs;
+ fslist = (struct btrfs_ioctl_fslist *) (++fsargs);
- fslist_tmp = *out_fslist = (struct btrfs_ioctl_fslist *)
- malloc(sizeof(*fslist) * count);
- if (!fslist_tmp) {
+ sz = sizeof(*fslist) * *out_count;
+ *out_fslist = (struct btrfs_ioctl_fslist *) malloc(sz);
+ if (*out_fslist == NULL) {
ret = -ENOMEM;
goto out;
}
-
- while (count--) {
- memcpy(fslist_tmp, fslist, sizeof(*fslist));
- fslist_tmp = fslist_tmp + sizeof(*fslist_tmp);
- fslist = fslist + sizeof(*fslist);
- }
+ memcpy(*out_fslist, fslist, sz);
ret = 0;
out:
- free(fsargs);
+ free(fsargs_saved);
close(fd);
return 0;
}
+
+/* This finds the mount point for a given fsid,
+ * subvols of the same fs/fsid can be mounted
+ * so here this picks and lowest subvol id
+ * and returns the mount point
+*/
+int fsid_to_mntpt(__u8 *fsid, char *mntpt, int *mnt_cnt)
+{
+ int fd = -1, ret = 0;
+ DIR *dirstream = NULL;
+ FILE *f;
+ struct btrfs_ioctl_fs_info_args fi_args;
+ u64 svid, saved_svid = (u64)-1;
+ struct mntent *mnt;
+ int mcnt = 0;
+
+ *mnt_cnt = 0;
+ f = setmntent("/proc/self/mounts", "r");
+ if (f == NULL)
+ return 1;
+
+ while ((mnt = getmntent(f)) != NULL) {
+ if (strcmp(mnt->mnt_type, "btrfs"))
+ continue;
+ fd = open_file_or_dir(mnt->mnt_dir, &dirstream);
+ if (fd < 0) {
+ ret = -errno;
+ return ret;
+ }
+ ret = ioctl(fd, BTRFS_IOC_FS_INFO, &fi_args);
+ if (ret < 0) {
+ ret = -errno;
+ close_file_or_dir(fd, dirstream);
+ break;
+ }
+ if (uuid_compare(fsid, fi_args.fsid)) {
+ close_file_or_dir(fd, dirstream);
+ continue;
+ }
+
+ /* found */
+ mcnt++;
+ ret = btrfs_list_get_path_rootid(fd, &svid);
+ if (ret) {
+ /* error so just copy and return*/
+ strcpy(mntpt, mnt->mnt_dir);
+ close_file_or_dir(fd, dirstream);
+ break;
+ }
+ if (svid < saved_svid) {
+ strcpy(mntpt, mnt->mnt_dir);
+ saved_svid = svid;
+ }
+ }
+ endmntent(f);
+ if (mcnt)
+ *mnt_cnt = mcnt;
+
+ return ret;
+}
diff --git a/utils.h b/utils.h
index e20ad74..8c64575 100644
--- a/utils.h
+++ b/utils.h
@@ -94,6 +94,7 @@ int ask_user(char *question);
int lookup_ino_rootid(int fd, u64 *rootid);
int btrfs_scan_lblkid(int update_kernel);
int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
-int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count);
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count);
+int fsid_to_mntpt(__u8 *fsid, char *mnt, int *mnt_cnt);
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input
2013-11-04 3:45 [PATCH 1/4] btrfs-progs: make filesystem show by label work Anand Jain
2013-11-04 3:45 ` [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control Anand Jain
2013-11-04 3:45 ` [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted Anand Jain
@ 2013-11-04 3:45 ` Anand Jain
2013-11-04 4:36 ` [PATCH 4/4 v2] " Anand Jain
2013-11-06 20:20 ` [PATCH 4/4] " Josef Bacik
2013-11-07 10:06 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
3 siblings, 2 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-04 3:45 UTC (permalink / raw)
To: linux-btrfs; +Cc: jbacik, zab, dsterba
A new test case when disk is unmounted and if the non mapper
disk path is given as the argument to the btrfs filesystem show <arg>
we still need this to work but lblkid will pull only mapper disks,
it won't match. So this will normalize the input to find btrfs
by fsid and pass it to the search.
v2: accepts Josef suggested
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
cmds-filesystem.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index f8e8475..f40178a 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -37,6 +37,7 @@
#include "version.h"
#include "commands.h"
#include "list_sort.h"
+#include "disk-io.h"
static const char * const filesystem_cmd_group_usage[] = {
"btrfs filesystem [<group>] <command> [<args>]",
@@ -414,6 +415,39 @@ static int btrfs_scan_kernel(void *search)
return 0;
}
+static int dev_to_fsid(char *dev, __u8 *fsid)
+{
+ struct btrfs_super_block *disk_super;
+ char *buf;
+ int ret;
+ int fd;
+
+ buf = malloc(4096);
+ if (!buf)
+ return -ENOMEM;
+
+ fd = open(dev, O_RDONLY);
+ if (fd < 0) {
+ ret = -errno;
+ free(buf);
+ return ret;
+ }
+
+ disk_super = (struct btrfs_super_block *)buf;
+ ret = btrfs_read_dev_super(fd, disk_super,
+ BTRFS_SUPER_INFO_OFFSET);
+ if (ret)
+ goto out;
+
+ memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
+ ret = 0;
+
+out:
+ close(fd);
+ free(buf);
+ return ret;
+}
+
static const char * const cmd_show_usage[] = {
"btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
"Show the structure of a filesystem",
@@ -434,6 +468,8 @@ static int cmd_show(int argc, char **argv)
int type = 0;
char mp[BTRFS_PATH_NAME_MAX + 1];
char path[PATH_MAX];
+ __u8 fsid[BTRFS_FSID_SIZE];
+ char uuid_buf[37];
while (1) {
int long_index;
@@ -466,6 +502,10 @@ static int cmd_show(int argc, char **argv)
if (strlen(search) == 0)
usage(cmd_show_usage);
type = check_arg_type(search);
+ /*needs spl handling if input arg is block dev
+ *And if input arg is mount-point just print it
+ *right away
+ */
if (type == BTRFS_ARG_BLKDEV) {
if (where == BTRFS_SCAN_DEV) {
/* we need to do this because
@@ -477,14 +517,25 @@ static int cmd_show(int argc, char **argv)
} else {
ret = get_btrfs_mount(search,
mp, sizeof(mp));
- if (!ret)
+ if (!ret) {
/* given block dev is mounted*/
search = mp;
- else
+ type = BTRFS_ARG_MNTPOINT;
+ } else {
+ ret = dev_to_fsid(search, fsid);
+ if (ret) {
+ fprintf(stderr,
+ "ERROR: No btrfs on %s\n",
+ search);
+ return 1;
+ }
+ uuid_unparse(fsid, uuid_buf);
+ search = uuid_buf;
+ type = BTRFS_ARG_UUID;
goto devs_only;
+ }
}
- }
- if (type == BTRFS_ARG_MNTPOINT) {
+ } else if (type == BTRFS_ARG_MNTPOINT) {
char label[BTRFS_LABEL_SIZE];
if (get_label_mounted(search, label))
return 1;
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/4 v2] btrfs-progs: lblkid wouldn't find non mapper path input
2013-11-04 3:45 ` [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input Anand Jain
@ 2013-11-04 4:36 ` Anand Jain
2013-11-06 20:20 ` [PATCH 4/4] " Josef Bacik
1 sibling, 0 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-04 4:36 UTC (permalink / raw)
To: linux-btrfs
A new test case when disk is unmounted and if the non mapper
disk path is given as the argument to the btrfs filesystem show <arg>
we still need this to work but lblkid will pull only mapper disks,
it won't match. So this will normalize the input to find btrfs
by fsid and pass it to the search.
v2: accepts Josef suggested
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
cmds-filesystem.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/cmds-filesystem.c b/cmds-filesystem.c
index f8e8475..f40178a 100644
--- a/cmds-filesystem.c
+++ b/cmds-filesystem.c
@@ -37,6 +37,7 @@
#include "version.h"
#include "commands.h"
#include "list_sort.h"
+#include "disk-io.h"
static const char * const filesystem_cmd_group_usage[] = {
"btrfs filesystem [<group>] <command> [<args>]",
@@ -414,6 +415,39 @@ static int btrfs_scan_kernel(void *search)
return 0;
}
+static int dev_to_fsid(char *dev, __u8 *fsid)
+{
+ struct btrfs_super_block *disk_super;
+ char *buf;
+ int ret;
+ int fd;
+
+ buf = malloc(4096);
+ if (!buf)
+ return -ENOMEM;
+
+ fd = open(dev, O_RDONLY);
+ if (fd < 0) {
+ ret = -errno;
+ free(buf);
+ return ret;
+ }
+
+ disk_super = (struct btrfs_super_block *)buf;
+ ret = btrfs_read_dev_super(fd, disk_super,
+ BTRFS_SUPER_INFO_OFFSET);
+ if (ret)
+ goto out;
+
+ memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
+ ret = 0;
+
+out:
+ close(fd);
+ free(buf);
+ return ret;
+}
+
static const char * const cmd_show_usage[] = {
"btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
"Show the structure of a filesystem",
@@ -434,6 +468,8 @@ static int cmd_show(int argc, char **argv)
int type = 0;
char mp[BTRFS_PATH_NAME_MAX + 1];
char path[PATH_MAX];
+ __u8 fsid[BTRFS_FSID_SIZE];
+ char uuid_buf[37];
while (1) {
int long_index;
@@ -466,6 +502,10 @@ static int cmd_show(int argc, char **argv)
if (strlen(search) == 0)
usage(cmd_show_usage);
type = check_arg_type(search);
+ /*needs spl handling if input arg is block dev
+ *And if input arg is mount-point just print it
+ *right away
+ */
if (type == BTRFS_ARG_BLKDEV) {
if (where == BTRFS_SCAN_DEV) {
/* we need to do this because
@@ -477,14 +517,25 @@ static int cmd_show(int argc, char **argv)
} else {
ret = get_btrfs_mount(search,
mp, sizeof(mp));
- if (!ret)
+ if (!ret) {
/* given block dev is mounted*/
search = mp;
- else
+ type = BTRFS_ARG_MNTPOINT;
+ } else {
+ ret = dev_to_fsid(search, fsid);
+ if (ret) {
+ fprintf(stderr,
+ "ERROR: No btrfs on %s\n",
+ search);
+ return 1;
+ }
+ uuid_unparse(fsid, uuid_buf);
+ search = uuid_buf;
+ type = BTRFS_ARG_UUID;
goto devs_only;
+ }
}
- }
- if (type == BTRFS_ARG_MNTPOINT) {
+ } else if (type == BTRFS_ARG_MNTPOINT) {
char label[BTRFS_LABEL_SIZE];
if (get_label_mounted(search, label))
return 1;
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control
2013-11-04 3:45 ` [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control Anand Jain
@ 2013-11-06 20:13 ` Josef Bacik
2013-11-07 9:53 ` Anand Jain
0 siblings, 1 reply; 12+ messages in thread
From: Josef Bacik @ 2013-11-06 20:13 UTC (permalink / raw)
To: Anand Jain; +Cc: linux-btrfs, jbacik, zab, dsterba
On Mon, Nov 04, 2013 at 11:45:43AM +0800, Anand Jain wrote:
> need fsinfo from btrfs-control that is when mount path is
> not known.
> current method of going through each mount points isn't
> efficient, and multiple subvol of a fsid could be mounted
> means extra logic to handle that. Further this will help
> to revamp check_mounted() (planned)
>
> check_mounted is heavily used in the btrfs-progs, it
> does full scan of all the disks in the system to confirm
> if a multi-disk btrfs is mounted it doesn't scalable well
> with few hundreds luns, check_mounted for sure needs a
> revamp. using this it can be done easily. which is planned.
>
> v2: commit reword
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> ioctl.h | 19 +++++++++++++++
> utils.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> utils.h | 1 +
> 3 files changed, 100 insertions(+), 0 deletions(-)
>
> diff --git a/ioctl.h b/ioctl.h
> index d21413f..29575d8 100644
> --- a/ioctl.h
> +++ b/ioctl.h
> @@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
> }
> }
>
> +/* fs flags */
> +#define BTRFS_FS_MOUNTED (1LLU << 0)
> +
> +struct btrfs_ioctl_fslist {
> + __u64 self_sz; /* in/out */
> + __u8 fsid[BTRFS_FSID_SIZE]; /* out */
> + __u64 num_devices;
> + __u64 missing_devices;
> + __u64 total_devices;
> + __u64 flags;
> +};
> +
> +struct btrfs_ioctl_fslist_args {
> + __u64 self_sz; /* in/out */
> + __u64 count; /* out */
> +};
> +
> #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
> struct btrfs_ioctl_vol_args)
> #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
> @@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args {
> struct btrfs_ioctl_dev_replace_args)
> #define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \
> struct btrfs_ioctl_dedup_args)
> +#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \
> + struct btrfs_ioctl_fslist_args)
> #ifdef __cplusplus
> }
> #endif
> diff --git a/utils.c b/utils.c
> index 5bedd97..1798a7c 100644
> --- a/utils.c
> +++ b/utils.c
> @@ -2087,3 +2087,83 @@ int lookup_ino_rootid(int fd, u64 *rootid)
>
> return 0;
> }
> +
> +/* scans for fsid(s) in the kernel using the btrfs-control
> + * interface.
> + */
> +int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count)
> +{
> + int ret, fd, e;
> + struct btrfs_ioctl_fslist_args *fsargs;
> + struct btrfs_ioctl_fslist *fslist;
> + struct btrfs_ioctl_fslist *fslist_tmp;
> + u64 sz;
> + int count;
> +
> + fd = open("/dev/btrfs-control", O_RDWR);
> + e = errno;
> + if (fd < 0) {
> + perror("failed to open /dev/btrfs-control");
> + return -e;
> + }
> +
> + /* space to hold 512 fsids, doesn't matter if small
> + * it would fail and return count so then we try again
> + */
> + count = 512;
> +again:
> + sz = sizeof(*fsargs) + sizeof(*fslist) * count;
> +
> + fsargs = (struct btrfs_ioctl_fslist_args *) malloc(sz);
No need to cast the return value of malloc.
> + memset(fsargs, 0, sz);
> +
> + if (!fsargs) {
> + close(fd);
> + return -ENOMEM;
> + }
Should check !fsargs before memsetting it.
> + fsargs->count = count;
> +
> + ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs);
> + e = errno;
> + if (ret == 1) {
> + /* out of size so reallocate */
> + count = fsargs->count;
> + free(fsargs);
> + goto again;
> + } else if (ret < 0) {
> + printf("ERROR: scan_fsid ioctl failed - %s\n",
> + strerror(e));
> + ret = -e;
> + goto out;
> + }
> +
> + /* ioctl returns fsid count in count parameter*/
> +
> + *out_count = count = fsargs->count;
> + if (count == 0) {
> + *out_fslist = NULL;
> + ret = 0;
> + goto out;
> + }
> +
> + fslist = (struct btrfs_ioctl_fslist *) (fsargs +
> + sizeof(*fsargs));
> +
> + fslist_tmp = *out_fslist = (struct btrfs_ioctl_fslist *)
> + malloc(sizeof(*fslist) * count);
No need to cast. Thanks,
Josef
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted
2013-11-04 3:45 ` [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted Anand Jain
@ 2013-11-06 20:19 ` Josef Bacik
2013-11-07 9:54 ` Anand Jain
0 siblings, 1 reply; 12+ messages in thread
From: Josef Bacik @ 2013-11-06 20:19 UTC (permalink / raw)
To: Anand Jain; +Cc: linux-btrfs, jbacik, zab, dsterba
On Mon, Nov 04, 2013 at 11:45:44AM +0800, Anand Jain wrote:
> as of now with out this patch user would see
> fsinfo per btrfs mount path but which mean multiple
> entry if more than one subvol is mounted of the same
> fsid. so this patch will handle that nicely.
>
> v2: accepts Zach suggested
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> cmds-filesystem.c | 90 +++++++++++++++++++++++++++++++++--------------------
> utils.c | 88 ++++++++++++++++++++++++++++++++++++++++++---------
> utils.h | 3 +-
> 3 files changed, 130 insertions(+), 51 deletions(-)
>
> diff --git a/cmds-filesystem.c b/cmds-filesystem.c
> index d2cad81..f8e8475 100644
> --- a/cmds-filesystem.c
> +++ b/cmds-filesystem.c
> @@ -317,6 +317,29 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
> return 0;
> }
>
> +static void handle_print(char *mnt, char *label)
> +{
> + int fd;
> + struct btrfs_ioctl_fs_info_args fs_info_arg;
> + struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
> + struct btrfs_ioctl_space_args *space_info_arg;
> +
> + if (get_fs_info(mnt, &fs_info_arg, &dev_info_arg)) {
> + fprintf(stdout, "ERROR: get_fs_info failed\n");
> + return;
> + }
> +
> + fd = open(mnt, O_RDONLY);
> + if (fd > 0 && !get_df(fd, &space_info_arg)) {
0 is a valid fd. Thanks,
Josef
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input
2013-11-04 3:45 ` [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input Anand Jain
2013-11-04 4:36 ` [PATCH 4/4 v2] " Anand Jain
@ 2013-11-06 20:20 ` Josef Bacik
2013-11-07 9:54 ` Anand Jain
1 sibling, 1 reply; 12+ messages in thread
From: Josef Bacik @ 2013-11-06 20:20 UTC (permalink / raw)
To: Anand Jain; +Cc: linux-btrfs, jbacik, zab, dsterba
On Mon, Nov 04, 2013 at 11:45:45AM +0800, Anand Jain wrote:
> A new test case when disk is unmounted and if the non mapper
> disk path is given as the argument to the btrfs filesystem show <arg>
> we still need this to work but lblkid will pull only mapper disks,
> it won't match. So this will normalize the input to find btrfs
> by fsid and pass it to the search.
>
> v2: accepts Josef suggested
>
> Signed-off-by: Anand Jain <anand.jain@oracle.com>
> ---
> cmds-filesystem.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 55 insertions(+), 4 deletions(-)
>
> diff --git a/cmds-filesystem.c b/cmds-filesystem.c
> index f8e8475..f40178a 100644
> --- a/cmds-filesystem.c
> +++ b/cmds-filesystem.c
> @@ -37,6 +37,7 @@
> #include "version.h"
> #include "commands.h"
> #include "list_sort.h"
> +#include "disk-io.h"
>
> static const char * const filesystem_cmd_group_usage[] = {
> "btrfs filesystem [<group>] <command> [<args>]",
> @@ -414,6 +415,39 @@ static int btrfs_scan_kernel(void *search)
> return 0;
> }
>
> +static int dev_to_fsid(char *dev, __u8 *fsid)
> +{
> + struct btrfs_super_block *disk_super;
> + char *buf;
> + int ret;
> + int fd;
> +
> + buf = malloc(4096);
> + if (!buf)
> + return -ENOMEM;
> +
> + fd = open(dev, O_RDONLY);
> + if (fd < 0) {
> + ret = -errno;
> + free(buf);
> + return ret;
> + }
> +
> + disk_super = (struct btrfs_super_block *)buf;
> + ret = btrfs_read_dev_super(fd, disk_super,
> + BTRFS_SUPER_INFO_OFFSET);
> + if (ret)
> + goto out;
> +
> + memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
> + ret = 0;
> +
> +out:
> + close(fd);
> + free(buf);
> + return ret;
> +}
> +
> static const char * const cmd_show_usage[] = {
> "btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
> "Show the structure of a filesystem",
> @@ -434,6 +468,8 @@ static int cmd_show(int argc, char **argv)
> int type = 0;
> char mp[BTRFS_PATH_NAME_MAX + 1];
> char path[PATH_MAX];
> + __u8 fsid[BTRFS_FSID_SIZE];
> + char uuid_buf[37];
>
> while (1) {
> int long_index;
> @@ -466,6 +502,10 @@ static int cmd_show(int argc, char **argv)
> if (strlen(search) == 0)
> usage(cmd_show_usage);
> type = check_arg_type(search);
> + /*needs spl handling if input arg is block dev
> + *And if input arg is mount-point just print it
> + *right away
> + */
Format screwup. Thanks,
Josef
--
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-
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control
2013-11-06 20:13 ` Josef Bacik
@ 2013-11-07 9:53 ` Anand Jain
0 siblings, 0 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-07 9:53 UTC (permalink / raw)
To: Josef Bacik; +Cc: linux-btrfs, zab, dsterba
Thanks sent out v3.
On 11/07/13 04:13 AM, Josef Bacik wrote:
> On Mon, Nov 04, 2013 at 11:45:43AM +0800, Anand Jain wrote:
>> need fsinfo from btrfs-control that is when mount path is
>> not known.
>> current method of going through each mount points isn't
>> efficient, and multiple subvol of a fsid could be mounted
>> means extra logic to handle that. Further this will help
>> to revamp check_mounted() (planned)
>>
>> check_mounted is heavily used in the btrfs-progs, it
>> does full scan of all the disks in the system to confirm
>> if a multi-disk btrfs is mounted it doesn't scalable well
>> with few hundreds luns, check_mounted for sure needs a
>> revamp. using this it can be done easily. which is planned.
>>
>> v2: commit reword
>>
>> Signed-off-by: Anand Jain<anand.jain@oracle.com>
>> ---
>> ioctl.h | 19 +++++++++++++++
>> utils.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> utils.h | 1 +
>> 3 files changed, 100 insertions(+), 0 deletions(-)
>>
>> diff --git a/ioctl.h b/ioctl.h
>> index d21413f..29575d8 100644
>> --- a/ioctl.h
>> +++ b/ioctl.h
>> @@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
>> }
>> }
>>
>> +/* fs flags */
>> +#define BTRFS_FS_MOUNTED (1LLU<< 0)
>> +
>> +struct btrfs_ioctl_fslist {
>> + __u64 self_sz; /* in/out */
>> + __u8 fsid[BTRFS_FSID_SIZE]; /* out */
>> + __u64 num_devices;
>> + __u64 missing_devices;
>> + __u64 total_devices;
>> + __u64 flags;
>> +};
>> +
>> +struct btrfs_ioctl_fslist_args {
>> + __u64 self_sz; /* in/out */
>> + __u64 count; /* out */
>> +};
>> +
>> #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
>> struct btrfs_ioctl_vol_args)
>> #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
>> @@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args {
>> struct btrfs_ioctl_dev_replace_args)
>> #define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \
>> struct btrfs_ioctl_dedup_args)
>> +#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \
>> + struct btrfs_ioctl_fslist_args)
>> #ifdef __cplusplus
>> }
>> #endif
>> diff --git a/utils.c b/utils.c
>> index 5bedd97..1798a7c 100644
>> --- a/utils.c
>> +++ b/utils.c
>> @@ -2087,3 +2087,83 @@ int lookup_ino_rootid(int fd, u64 *rootid)
>>
>> return 0;
>> }
>> +
>> +/* scans for fsid(s) in the kernel using the btrfs-control
>> + * interface.
>> + */
>> +int get_fslist(struct btrfs_ioctl_fslist **out_fslist, int *out_count)
>> +{
>> + int ret, fd, e;
>> + struct btrfs_ioctl_fslist_args *fsargs;
>> + struct btrfs_ioctl_fslist *fslist;
>> + struct btrfs_ioctl_fslist *fslist_tmp;
>> + u64 sz;
>> + int count;
>> +
>> + fd = open("/dev/btrfs-control", O_RDWR);
>> + e = errno;
>> + if (fd< 0) {
>> + perror("failed to open /dev/btrfs-control");
>> + return -e;
>> + }
>> +
>> + /* space to hold 512 fsids, doesn't matter if small
>> + * it would fail and return count so then we try again
>> + */
>> + count = 512;
>> +again:
>> + sz = sizeof(*fsargs) + sizeof(*fslist) * count;
>> +
>> + fsargs = (struct btrfs_ioctl_fslist_args *) malloc(sz);
>
> No need to cast the return value of malloc.
>
>> + memset(fsargs, 0, sz);
>> +
>> + if (!fsargs) {
>> + close(fd);
>> + return -ENOMEM;
>> + }
>
> Should check !fsargs before memsetting it.
>
>> + fsargs->count = count;
>> +
>> + ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs);
>> + e = errno;
>> + if (ret == 1) {
>> + /* out of size so reallocate */
>> + count = fsargs->count;
>> + free(fsargs);
>> + goto again;
>> + } else if (ret< 0) {
>> + printf("ERROR: scan_fsid ioctl failed - %s\n",
>> + strerror(e));
>> + ret = -e;
>> + goto out;
>> + }
>> +
>> + /* ioctl returns fsid count in count parameter*/
>> +
>> + *out_count = count = fsargs->count;
>> + if (count == 0) {
>> + *out_fslist = NULL;
>> + ret = 0;
>> + goto out;
>> + }
>> +
>> + fslist = (struct btrfs_ioctl_fslist *) (fsargs +
>> + sizeof(*fsargs));
>> +
>> + fslist_tmp = *out_fslist = (struct btrfs_ioctl_fslist *)
>> + malloc(sizeof(*fslist) * count);
>
> No need to cast. Thanks,
>
> Josef
> --
> 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] 12+ messages in thread
* Re: [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted
2013-11-06 20:19 ` Josef Bacik
@ 2013-11-07 9:54 ` Anand Jain
0 siblings, 0 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-07 9:54 UTC (permalink / raw)
To: Josef Bacik; +Cc: linux-btrfs, zab, dsterba
Thanks sent out v3
On 11/07/13 04:19 AM, Josef Bacik wrote:
> On Mon, Nov 04, 2013 at 11:45:44AM +0800, Anand Jain wrote:
>> as of now with out this patch user would see
>> fsinfo per btrfs mount path but which mean multiple
>> entry if more than one subvol is mounted of the same
>> fsid. so this patch will handle that nicely.
>>
>> v2: accepts Zach suggested
>>
>> Signed-off-by: Anand Jain<anand.jain@oracle.com>
>> ---
>> cmds-filesystem.c | 90 +++++++++++++++++++++++++++++++++--------------------
>> utils.c | 88 ++++++++++++++++++++++++++++++++++++++++++---------
>> utils.h | 3 +-
>> 3 files changed, 130 insertions(+), 51 deletions(-)
>>
>> diff --git a/cmds-filesystem.c b/cmds-filesystem.c
>> index d2cad81..f8e8475 100644
>> --- a/cmds-filesystem.c
>> +++ b/cmds-filesystem.c
>> @@ -317,6 +317,29 @@ static int print_one_fs(struct btrfs_ioctl_fs_info_args *fs_info,
>> return 0;
>> }
>>
>> +static void handle_print(char *mnt, char *label)
>> +{
>> + int fd;
>> + struct btrfs_ioctl_fs_info_args fs_info_arg;
>> + struct btrfs_ioctl_dev_info_args *dev_info_arg = NULL;
>> + struct btrfs_ioctl_space_args *space_info_arg;
>> +
>> + if (get_fs_info(mnt,&fs_info_arg,&dev_info_arg)) {
>> + fprintf(stdout, "ERROR: get_fs_info failed\n");
>> + return;
>> + }
>> +
>> + fd = open(mnt, O_RDONLY);
>> + if (fd> 0&& !get_df(fd,&space_info_arg)) {
>
> 0 is a valid fd. Thanks,
>
> Josef
> --
> 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] 12+ messages in thread
* Re: [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input
2013-11-06 20:20 ` [PATCH 4/4] " Josef Bacik
@ 2013-11-07 9:54 ` Anand Jain
0 siblings, 0 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-07 9:54 UTC (permalink / raw)
To: Josef Bacik; +Cc: linux-btrfs, zab, dsterba
Done.
On 11/07/13 04:20 AM, Josef Bacik wrote:
> On Mon, Nov 04, 2013 at 11:45:45AM +0800, Anand Jain wrote:
>> A new test case when disk is unmounted and if the non mapper
>> disk path is given as the argument to the btrfs filesystem show<arg>
>> we still need this to work but lblkid will pull only mapper disks,
>> it won't match. So this will normalize the input to find btrfs
>> by fsid and pass it to the search.
>>
>> v2: accepts Josef suggested
>>
>> Signed-off-by: Anand Jain<anand.jain@oracle.com>
>> ---
>> cmds-filesystem.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++---
>> 1 files changed, 55 insertions(+), 4 deletions(-)
>>
>> diff --git a/cmds-filesystem.c b/cmds-filesystem.c
>> index f8e8475..f40178a 100644
>> --- a/cmds-filesystem.c
>> +++ b/cmds-filesystem.c
>> @@ -37,6 +37,7 @@
>> #include "version.h"
>> #include "commands.h"
>> #include "list_sort.h"
>> +#include "disk-io.h"
>>
>> static const char * const filesystem_cmd_group_usage[] = {
>> "btrfs filesystem [<group>]<command> [<args>]",
>> @@ -414,6 +415,39 @@ static int btrfs_scan_kernel(void *search)
>> return 0;
>> }
>>
>> +static int dev_to_fsid(char *dev, __u8 *fsid)
>> +{
>> + struct btrfs_super_block *disk_super;
>> + char *buf;
>> + int ret;
>> + int fd;
>> +
>> + buf = malloc(4096);
>> + if (!buf)
>> + return -ENOMEM;
>> +
>> + fd = open(dev, O_RDONLY);
>> + if (fd< 0) {
>> + ret = -errno;
>> + free(buf);
>> + return ret;
>> + }
>> +
>> + disk_super = (struct btrfs_super_block *)buf;
>> + ret = btrfs_read_dev_super(fd, disk_super,
>> + BTRFS_SUPER_INFO_OFFSET);
>> + if (ret)
>> + goto out;
>> +
>> + memcpy(fsid, disk_super->fsid, BTRFS_FSID_SIZE);
>> + ret = 0;
>> +
>> +out:
>> + close(fd);
>> + free(buf);
>> + return ret;
>> +}
>> +
>> static const char * const cmd_show_usage[] = {
>> "btrfs filesystem show [options] [<path>|<uuid>|<device>|label]",
>> "Show the structure of a filesystem",
>> @@ -434,6 +468,8 @@ static int cmd_show(int argc, char **argv)
>> int type = 0;
>> char mp[BTRFS_PATH_NAME_MAX + 1];
>> char path[PATH_MAX];
>> + __u8 fsid[BTRFS_FSID_SIZE];
>> + char uuid_buf[37];
>>
>> while (1) {
>> int long_index;
>> @@ -466,6 +502,10 @@ static int cmd_show(int argc, char **argv)
>> if (strlen(search) == 0)
>> usage(cmd_show_usage);
>> type = check_arg_type(search);
>> + /*needs spl handling if input arg is block dev
>> + *And if input arg is mount-point just print it
>> + *right away
>> + */
>
> Format screwup. Thanks,
>
> Josef
> --
> 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] 12+ messages in thread
* [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3
2013-11-04 3:45 [PATCH 1/4] btrfs-progs: make filesystem show by label work Anand Jain
` (2 preceding siblings ...)
2013-11-04 3:45 ` [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input Anand Jain
@ 2013-11-07 10:06 ` Anand Jain
3 siblings, 0 replies; 12+ messages in thread
From: Anand Jain @ 2013-11-07 10:06 UTC (permalink / raw)
To: linux-btrfs; +Cc: jbacik, zab, dsterba
need fsinfo from btrfs-control that is when mount path is
not known.
current method of going through each mount points isn't
efficient, and multiple subvol of a fsid could be mounted
means extra logic to handle that. Further this will help
to revamp check_mounted() (planned)
check_mounted is heavily used in the btrfs-progs, it
does full scan of all the disks in the system to confirm
if a multi-disk btrfs is mounted it doesn't scalable well
with few hundreds luns, check_mounted for sure needs a
revamp. using this it can be done easily. which is planned.
v3: accepts Josef suggested and fix git screwup
v2: commit reword
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
ioctl.h | 19 +++++++++++++++
utils.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
utils.h | 1 +
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/ioctl.h b/ioctl.h
index d21413f..29575d8 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -506,6 +506,23 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
}
}
+/* fs flags */
+#define BTRFS_FS_MOUNTED (1LLU << 0)
+
+struct btrfs_ioctl_fslist {
+ __u64 self_sz; /* in/out */
+ __u8 fsid[BTRFS_FSID_SIZE]; /* out */
+ __u64 num_devices;
+ __u64 missing_devices;
+ __u64 total_devices;
+ __u64 flags;
+};
+
+struct btrfs_ioctl_fslist_args {
+ __u64 self_sz; /* in/out */
+ __u64 count; /* out */
+};
+
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
@@ -604,6 +621,8 @@ struct btrfs_ioctl_clone_range_args {
struct btrfs_ioctl_dev_replace_args)
#define BTRFS_IOC_DEDUP_CTL _IOWR(BTRFS_IOCTL_MAGIC, 55, \
struct btrfs_ioctl_dedup_args)
+#define BTRFS_IOC_GET_FSLIST _IOWR(BTRFS_IOCTL_MAGIC, 56, \
+ struct btrfs_ioctl_fslist_args)
#ifdef __cplusplus
}
#endif
diff --git a/utils.c b/utils.c
index 60d2c3a..4b90026 100644
--- a/utils.c
+++ b/utils.c
@@ -47,6 +47,7 @@
#include "utils.h"
#include "volumes.h"
#include "ioctl.h"
+#include "btrfs-list.h"
#ifndef BLKDISCARD
#define BLKDISCARD _IO(0x12,119)
@@ -2087,3 +2088,78 @@ int lookup_ino_rootid(int fd, u64 *rootid)
return 0;
}
+
+/* scans for fsid(s) in the kernel using the btrfs-control
+ * interface.
+ */
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count)
+{
+ int ret, fd, e;
+ struct btrfs_ioctl_fslist_args *fsargs;
+ struct btrfs_ioctl_fslist_args *fsargs_saved = NULL;
+ struct btrfs_ioctl_fslist *fslist;
+ u64 sz;
+ int count;
+
+ fd = open("/dev/btrfs-control", O_RDWR);
+ e = errno;
+ if (fd < 0) {
+ perror("failed to open /dev/btrfs-control");
+ return -e;
+ }
+
+ /* space to hold 512 fsids, doesn't matter if small
+ * it would fail and return count so then we try again
+ */
+ count = 512;
+again:
+ sz = sizeof(*fsargs) + sizeof(*fslist) * count;
+
+ fsargs = malloc(sz);
+ if (!fsargs) {
+ close(fd);
+ return -ENOMEM;
+ }
+
+ memset(fsargs, 0, sz);
+ fsargs->count = count;
+
+ ret = ioctl(fd, BTRFS_IOC_GET_FSLIST, fsargs);
+ e = errno;
+ if (ret == 1) {
+ /* out of size so reallocate */
+ count = fsargs->count;
+ free(fsargs);
+ goto again;
+ } else if (ret < 0) {
+ printf("ERROR: scan_fsid ioctl failed - %s\n",
+ strerror(e));
+ ret = -e;
+ goto out;
+ }
+
+ /* ioctl returns fsid count in count parameter*/
+
+ *out_count = fsargs->count;
+ if (*out_count == 0) {
+ *out_fslist = NULL;
+ ret = 0;
+ goto out;
+ }
+
+ fsargs_saved = fsargs;
+ fslist = (struct btrfs_ioctl_fslist *) (++fsargs);
+
+ sz = sizeof(*fslist) * *out_count;
+ *out_fslist = malloc(sz);
+ if (*out_fslist == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ memcpy(*out_fslist, fslist, sz);
+ ret = 0;
+out:
+ free(fsargs_saved);
+ close(fd);
+ return 0;
+}
diff --git a/utils.h b/utils.h
index 6f4b10c..a14a887 100644
--- a/utils.h
+++ b/utils.h
@@ -94,5 +94,6 @@ int ask_user(char *question);
int lookup_ino_rootid(int fd, u64 *rootid);
int btrfs_scan_lblkid(int update_kernel);
int get_btrfs_mount(const char *dev, char *mp, size_t mp_size);
+int get_fslist(struct btrfs_ioctl_fslist **out_fslist, u64 *out_count);
#endif
--
1.7.1
--
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
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-11-07 9:59 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-04 3:45 [PATCH 1/4] btrfs-progs: make filesystem show by label work Anand Jain
2013-11-04 3:45 ` [PATCH 2/4 v2] btrfs-progs: mechanism to fetch fsinfo from btrfs-control Anand Jain
2013-11-06 20:13 ` Josef Bacik
2013-11-07 9:53 ` Anand Jain
2013-11-04 3:45 ` [PATCH 3/4 v2] btrfs-progs: fs show should handle if subvol(s) mounted Anand Jain
2013-11-06 20:19 ` Josef Bacik
2013-11-07 9:54 ` Anand Jain
2013-11-04 3:45 ` [PATCH 4/4] btrfs-progs: lblkid wouldn't find non mapper path input Anand Jain
2013-11-04 4:36 ` [PATCH 4/4 v2] " Anand Jain
2013-11-06 20:20 ` [PATCH 4/4] " Josef Bacik
2013-11-07 9:54 ` Anand Jain
2013-11-07 10:06 ` [PATCH 1/3] btrfs-progs: mechanism to fetch fsinfo from btrfs-control v3 Anand Jain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).