stat-util: also introduce stat_verify_block() and use it everywhere
This commit is contained in:
@@ -203,6 +203,28 @@ int fd_verify_linked(int fd) {
|
||||
return verify_stat_at(fd, NULL, false, stat_verify_linked, true);
|
||||
}
|
||||
|
||||
int stat_verify_block(const struct stat *st) {
|
||||
assert(st);
|
||||
|
||||
if (S_ISDIR(st->st_mode))
|
||||
return -EISDIR;
|
||||
|
||||
if (S_ISLNK(st->st_mode))
|
||||
return -ELOOP;
|
||||
|
||||
if (!S_ISBLK(st->st_mode))
|
||||
return -ENOTBLK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fd_verify_block(int fd) {
|
||||
if (IN_SET(fd, AT_FDCWD, XAT_FDROOT))
|
||||
return -EISDIR;
|
||||
|
||||
return verify_stat_at(fd, /* path= */ NULL, /* follow= */ false, stat_verify_block, /* verify= */ true);
|
||||
}
|
||||
|
||||
int stat_verify_device_node(const struct stat *st) {
|
||||
assert(st);
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ int is_socket(const char *path);
|
||||
int stat_verify_linked(const struct stat *st);
|
||||
int fd_verify_linked(int fd);
|
||||
|
||||
int stat_verify_block(const struct stat *st);
|
||||
int fd_verify_block(int fd);
|
||||
|
||||
int stat_verify_device_node(const struct stat *st);
|
||||
int is_device_node(const char *path);
|
||||
|
||||
|
||||
+4
-4
@@ -28,6 +28,7 @@
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "special.h"
|
||||
#include "stat-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
@@ -299,10 +300,9 @@ static int run(int argc, char *argv[]) {
|
||||
if (stat(device, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat %s: %m", device);
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s is not a block device.",
|
||||
device);
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "'%s' is not a block device.", device);
|
||||
|
||||
r = sd_device_new_from_stat_rdev(&dev, &st);
|
||||
if (r < 0)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "main-func.h"
|
||||
#include "parse-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "stat-util.h"
|
||||
#include "static-destruct.h"
|
||||
|
||||
static HibernateInfo arg_info = {};
|
||||
@@ -165,9 +166,9 @@ static int run(int argc, char *argv[]) {
|
||||
if (stat(arg_info.device, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat resume device '%s': %m", arg_info.device);
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
||||
"Resume device '%s' is not a block device.", arg_info.device);
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Resume device '%s' is not a block device.", arg_info.device);
|
||||
|
||||
/* The write shall not return if a resume takes place. */
|
||||
r = write_resume_config(st.st_rdev, arg_info.offset, arg_info.device);
|
||||
|
||||
@@ -3214,8 +3214,9 @@ static int home_get_image_path_seat(Home *h, char **ret) {
|
||||
if (stat(ip, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
||||
if (r < 0)
|
||||
|
||||
@@ -202,16 +202,14 @@ static int probe_file_system_by_path(const char *path, char **ret_fstype, sd_id1
|
||||
}
|
||||
|
||||
static int block_get_size_by_fd(int fd, uint64_t *ret) {
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret);
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = fd_verify_block(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return blockdev_get_device_size(fd, ret);
|
||||
}
|
||||
@@ -2275,8 +2273,9 @@ int home_create_luks(
|
||||
if (setup->image_fd < 0)
|
||||
return setup->image_fd;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Device is not a block device, refusing.");
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Device is not a block device, refusing.");
|
||||
|
||||
if (asprintf(&sysfs, "/sys/dev/block/" DEVNUM_FORMAT_STR "/partition", DEVNUM_FORMAT_VAL(st.st_rdev)) < 0)
|
||||
return log_oom();
|
||||
|
||||
@@ -1413,9 +1413,9 @@ static int discover_device(void) {
|
||||
if (S_ISREG(st.st_mode))
|
||||
return discover_loop_backing_file();
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Unsupported mount source type for --discover: %s", arg_mount_what);
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Unsupported mount source type for --discover: %s", arg_mount_what);
|
||||
|
||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
||||
if (r < 0)
|
||||
|
||||
@@ -149,8 +149,9 @@ int btrfs_get_block_device_at(int dir_fd, const char *path, dev_t *ret) {
|
||||
if (stat((char*) di.path, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (major(st.st_rdev) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -1895,17 +1895,15 @@ int image_read_only(Image *i, bool b, RuntimeScope scope) {
|
||||
|
||||
case IMAGE_BLOCK: {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct stat st;
|
||||
int state = b;
|
||||
|
||||
fd = open(i->path, O_CLOEXEC|O_RDONLY|O_NONBLOCK|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTTY;
|
||||
r = fd_verify_block(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ioctl(fd, BLKROSET, &state) < 0)
|
||||
return -errno;
|
||||
|
||||
@@ -2141,14 +2141,16 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
|
||||
static int is_loop_device(const char *path) {
|
||||
char s[SYS_BLOCK_PATH_MAX("/../loop/")];
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
if (stat(path, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
xsprintf_sys_block_path(s, "/loop/", st.st_dev);
|
||||
if (access(s, F_OK) < 0) {
|
||||
|
||||
@@ -209,8 +209,9 @@ static int swap_entry_get_resume_config(SwapEntry *swap) {
|
||||
return -errno;
|
||||
|
||||
if (!swap->swapfile) {
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
swap->devno = st.st_rdev;
|
||||
swap->offset = 0;
|
||||
|
||||
@@ -378,9 +378,9 @@ static int loop_configure(
|
||||
}
|
||||
|
||||
static int fd_get_max_discard(int fd, uint64_t *ret) {
|
||||
struct stat st;
|
||||
char sysfs_path[STRLEN("/sys/dev/block/" ":" "/queue/discard_max_bytes") + DECIMAL_STR_MAX(dev_t) * 2 + 1];
|
||||
_cleanup_free_ char *buffer = NULL;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
@@ -388,8 +388,9 @@ static int fd_get_max_discard(int fd, uint64_t *ret) {
|
||||
if (fstat(ASSERT_FD(fd), &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
xsprintf(sysfs_path, "/sys/dev/block/" DEVNUM_FORMAT_STR "/queue/discard_max_bytes", DEVNUM_FORMAT_VAL(st.st_rdev));
|
||||
|
||||
@@ -401,14 +402,16 @@ static int fd_get_max_discard(int fd, uint64_t *ret) {
|
||||
}
|
||||
|
||||
static int fd_set_max_discard(int fd, uint64_t max_discard) {
|
||||
struct stat st;
|
||||
char sysfs_path[STRLEN("/sys/dev/block/" ":" "/queue/discard_max_bytes") + DECIMAL_STR_MAX(dev_t) * 2 + 1];
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
if (fstat(ASSERT_FD(fd), &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
r = stat_verify_block(&st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
xsprintf(sysfs_path, "/sys/dev/block/" DEVNUM_FORMAT_STR "/queue/discard_max_bytes", DEVNUM_FORMAT_VAL(st.st_rdev));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user