diff --git a/common/device-utils.c b/common/device-utils.c index dd7fdceb..f3987244 100644 --- a/common/device-utils.c +++ b/common/device-utils.c @@ -17,17 +17,20 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include "kernel-lib/sizes.h" #include "kernel-shared/disk-io.h" #include "kernel-shared/zoned.h" #include "common/device-utils.h" +#include "common/path-utils.h" #include "common/internal.h" #include "common/messages.h" #include "common/utils.h" @@ -392,3 +395,58 @@ u64 device_get_zone_unusable(int fd, u64 flags) return unusable; } + +/* + * Read information about zone size of the given device (short @name) from a + * given filesystem fd + */ +u64 device_get_zone_size(int fd, const char *name) +{ + DIR *dir; + struct dirent *de; + int sysfs_fd; + u64 ret = 0; + + sysfs_fd = sysfs_open_fsid_dir(fd, "devices"); + if (sysfs_fd < 0) + return 0; + + dir = fdopendir(sysfs_fd); + if (!dir) { + ret = 0; + goto out; + } + while (1) { + int queue_fd; + char queue[PATH_MAX]; + char buf[128] = {0}; + + de = readdir(dir); + if (!de) { + ret = 0; + break; + } + + if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) + continue; + if (strcmp(name, de->d_name) != 0) + continue; + + path_cat3_out(queue, "devices", de->d_name, "queue/chunk_sectors"); + /* /sys/fs/btrfs/FSID/devices/NAME/queue/chunk_sectors */ + queue_fd = sysfs_open_fsid_file(fd, queue); + if (queue_fd < 0) { + ret = 0; + break; + } + sysfs_read_file(queue_fd, buf, sizeof(buf)); + ret = atoll(buf); + close(queue_fd); + break; + } + closedir(dir); + +out: + close(sysfs_fd); + return ret; +} diff --git a/common/device-utils.h b/common/device-utils.h index 22e41bd2..099520bf 100644 --- a/common/device-utils.h +++ b/common/device-utils.h @@ -40,6 +40,7 @@ u64 device_get_partition_size(const char *dev); u64 device_get_partition_size_fd(int fd); int device_get_queue_param(const char *file, const char *param, char *buf, size_t len); u64 device_get_zone_unusable(int fd, u64 flags); +u64 device_get_zone_size(int fd, const char *name); /* * Updates to devices with btrfs-specific changs */