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>
master
Stefan Behrens 2012-05-15 12:05:44 +02:00 committed by David Sterba
parent 46e3b8087b
commit 7a69dc4eec
3 changed files with 80 additions and 85 deletions

View File

@ -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));

67
utils.c
View File

@ -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;
}

View File

@ -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