summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-05-15 12:05:44 +0200
committerDavid Sterba <dsterba@suse.cz>2013-01-30 00:40:35 +0100
commit7a69dc4eecfd52841b11e0f9312f62d17e3479f5 (patch)
treebc833b0d2699568054fe6d3b352f255e6d35f069
parent46e3b8087b86ef555b13be6807c34c555171fc4a (diff)
Btrfs-progs: make two utility functions globally available
Two convenient utility functions that have so far been local to scrub are moved to utils.c. They will be used in the device stats code in a following commit. Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
-rw-r--r--cmds-scrub.c94
-rw-r--r--utils.c67
-rw-r--r--utils.h4
3 files changed, 80 insertions, 85 deletions
diff --git a/cmds-scrub.c b/cmds-scrub.c
index b188996f..efdfdb4f 100644
--- a/cmds-scrub.c
+++ b/cmds-scrub.c
@@ -969,89 +969,6 @@ static struct scrub_file_record *last_dev_scrub(
return NULL;
}
-static int scrub_device_info(int fd, u64 devid,
- struct btrfs_ioctl_dev_info_args *di_args)
-{
- int ret;
-
- di_args->devid = devid;
- memset(&di_args->uuid, '\0', sizeof(di_args->uuid));
-
- ret = ioctl(fd, BTRFS_IOC_DEV_INFO, di_args);
- return ret ? -errno : 0;
-}
-
-static int scrub_fs_info(char *path,
- struct btrfs_ioctl_fs_info_args *fi_args,
- struct btrfs_ioctl_dev_info_args **di_ret)
-{
- int ret = 0;
- int ndevs = 0;
- int i = 1;
- int fd;
- struct btrfs_fs_devices *fs_devices_mnt = NULL;
- struct btrfs_ioctl_dev_info_args *di_args;
- char mp[BTRFS_PATH_NAME_MAX + 1];
-
- memset(fi_args, 0, sizeof(*fi_args));
-
- fd = open_file_or_dir(path);
- if (fd < 0) {
- fprintf(stderr, "ERROR: can't access to '%s'\n", path);
- return -1;
- }
-
- ret = ioctl(fd, BTRFS_IOC_FS_INFO, fi_args);
- if (ret && (errno == EINVAL || errno == ENOTTY)) {
- /* path is no mounted btrfs. try if it's a device */
- ret = check_mounted_where(fd, path, mp, sizeof(mp),
- &fs_devices_mnt);
- if (!ret)
- return -EINVAL;
- if (ret < 0)
- return ret;
- fi_args->num_devices = 1;
- fi_args->max_id = fs_devices_mnt->latest_devid;
- i = fs_devices_mnt->latest_devid;
- memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE);
- close(fd);
- fd = open_file_or_dir(mp);
- if (fd < 0)
- return -errno;
- } else if (ret) {
- close(fd);
- return -errno;
- }
-
- if (!fi_args->num_devices) {
- close(fd);
- return 0;
- }
-
- di_args = *di_ret = malloc(fi_args->num_devices * sizeof(*di_args));
- if (!di_args) {
- close(fd);
- return -errno;
- }
-
- for (; i <= fi_args->max_id; ++i) {
- BUG_ON(ndevs >= fi_args->num_devices);
- ret = scrub_device_info(fd, i, &di_args[ndevs]);
- if (ret == -ENODEV)
- continue;
- if (ret) {
- close(fd);
- return ret;
- }
- ++ndevs;
- }
-
- BUG_ON(ndevs == 0);
-
- close(fd);
- return 0;
-}
-
int mkdir_p(char *path)
{
int i;
@@ -1172,7 +1089,7 @@ static int scrub_start(int argc, char **argv, int resume)
return 12;
}
- ret = scrub_fs_info(path, &fi_args, &di_args);
+ ret = get_fs_info(fdmnt, path, &fi_args, &di_args);
if (ret) {
ERR(!do_quiet, "ERROR: getting dev info for scrub failed: "
"%s\n", strerror(-ret));
@@ -1604,6 +1521,7 @@ static int cmd_scrub_status(int argc, char **argv)
};
int ret;
int i;
+ int fdmnt;
int print_raw = 0;
int do_stats_per_dev = 0;
int c;
@@ -1631,7 +1549,13 @@ static int cmd_scrub_status(int argc, char **argv)
path = argv[optind];
- ret = scrub_fs_info(path, &fi_args, &di_args);
+ fdmnt = open_file_or_dir(path);
+ if (fdmnt < 0) {
+ fprintf(stderr, "ERROR: can't access to '%s'\n", path);
+ return 12;
+ }
+
+ ret = get_fs_info(fdmnt, path, &fi_args, &di_args);
if (ret) {
fprintf(stderr, "ERROR: getting dev info for scrub failed: "
"%s\n", strerror(-ret));
diff --git a/utils.c b/utils.c
index 87051359..d92f3178 100644
--- a/utils.c
+++ b/utils.c
@@ -1302,3 +1302,70 @@ int open_file_or_dir(const char *fname)
}
return fd;
}
+
+int get_device_info(int fd, u64 devid,
+ struct btrfs_ioctl_dev_info_args *di_args)
+{
+ int ret;
+
+ di_args->devid = devid;
+ memset(&di_args->uuid, '\0', sizeof(di_args->uuid));
+
+ ret = ioctl(fd, BTRFS_IOC_DEV_INFO, di_args);
+ return ret ? -errno : 0;
+}
+
+int get_fs_info(int fd, char *path, struct btrfs_ioctl_fs_info_args *fi_args,
+ struct btrfs_ioctl_dev_info_args **di_ret)
+{
+ int ret = 0;
+ int ndevs = 0;
+ int i = 1;
+ struct btrfs_fs_devices *fs_devices_mnt = NULL;
+ struct btrfs_ioctl_dev_info_args *di_args;
+ char mp[BTRFS_PATH_NAME_MAX + 1];
+
+ memset(fi_args, 0, sizeof(*fi_args));
+
+ ret = ioctl(fd, BTRFS_IOC_FS_INFO, fi_args);
+ if (ret && (errno == EINVAL || errno == ENOTTY)) {
+ /* path is not a mounted btrfs. Try if it's a device */
+ ret = check_mounted_where(fd, path, mp, sizeof(mp),
+ &fs_devices_mnt);
+ if (!ret)
+ return -EINVAL;
+ if (ret < 0)
+ return ret;
+ fi_args->num_devices = 1;
+ fi_args->max_id = fs_devices_mnt->latest_devid;
+ i = fs_devices_mnt->latest_devid;
+ memcpy(fi_args->fsid, fs_devices_mnt->fsid, BTRFS_FSID_SIZE);
+ close(fd);
+ fd = open_file_or_dir(mp);
+ if (fd < 0)
+ return -errno;
+ } else if (ret) {
+ return -errno;
+ }
+
+ if (!fi_args->num_devices)
+ return 0;
+
+ di_args = *di_ret = malloc(fi_args->num_devices * sizeof(*di_args));
+ if (!di_args)
+ return -errno;
+
+ for (; i <= fi_args->max_id; ++i) {
+ BUG_ON(ndevs >= fi_args->num_devices);
+ ret = get_device_info(fd, i, &di_args[ndevs]);
+ if (ret == -ENODEV)
+ continue;
+ if (ret)
+ return ret;
+ ndevs++;
+ }
+
+ BUG_ON(ndevs == 0);
+
+ return 0;
+}
diff --git a/utils.h b/utils.h
index ed43e846..2d2c23d2 100644
--- a/utils.h
+++ b/utils.h
@@ -49,4 +49,8 @@ int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
u64 parse_size(char *s);
int open_file_or_dir(const char *fname);
+int get_device_info(int fd, u64 devid,
+ struct btrfs_ioctl_dev_info_args *di_args);
+int get_fs_info(int fd, char *path, struct btrfs_ioctl_fs_info_args *fi_args,
+ struct btrfs_ioctl_dev_info_args **di_ret);
#endif