Merge pull request #30467 from poettering/loop-block-tweaks

various tweaks to block device ioctls, and loop device mgmt
This commit is contained in:
Daan De Meyer
2023-12-14 09:38:17 +01:00
committed by GitHub
11 changed files with 91 additions and 37 deletions
+15
View File
@@ -777,6 +777,21 @@ int blockdev_get_sector_size(int fd, uint32_t *ret) {
return 0;
}
int blockdev_get_device_size(int fd, uint64_t *ret) {
uint64_t sz = 0;
assert(fd >= 0);
assert(ret);
/* This is just a type-safe wrapper around BLKGETSIZE64 that gets us around having to include messy linux/fs.h in various clients */
if (ioctl(fd, BLKGETSIZE64, &sz) < 0)
return -errno;
*ret = sz;
return 0;
}
int blockdev_get_root(int level, dev_t *ret) {
_cleanup_free_ char *p = NULL;
dev_t devno;
+1
View File
@@ -57,5 +57,6 @@ int block_device_has_partitions(sd_device *dev);
int blockdev_reread_partition_table(sd_device *dev);
int blockdev_get_sector_size(int fd, uint32_t *ret);
int blockdev_get_device_size(int fd, uint64_t *ret);
int blockdev_get_root(int level, dev_t *ret);
+4 -2
View File
@@ -13,6 +13,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "blockdev-util.h"
#include "btrfs-util.h"
#include "chase.h"
#include "chattr-util.h"
@@ -446,8 +447,9 @@ static int image_make(
read_only = true;
}
if (ioctl(block_fd, BLKGETSIZE64, &size) < 0)
log_debug_errno(errno, "Failed to issue BLKGETSIZE64 on device %s/%s, ignoring: %m", path ?: strnull(parent), filename);
r = blockdev_get_device_size(block_fd, &size);
if (r < 0)
log_debug_errno(r, "Failed to issue BLKGETSIZE64 on device %s/%s, ignoring: %m", path ?: strnull(parent), filename);
block_fd = safe_close(block_fd);
}
+11 -3
View File
@@ -1547,6 +1547,7 @@ int dissect_image_file(
#if HAVE_BLKID
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
_cleanup_close_ int fd = -EBADF;
struct stat st;
int r;
assert(path);
@@ -1555,7 +1556,10 @@ int dissect_image_file(
if (fd < 0)
return -errno;
r = fd_verify_regular(fd);
if (fstat(fd, &st) < 0)
return -errno;
r = stat_verify_regular(&st);
if (r < 0)
return r;
@@ -1563,6 +1567,8 @@ int dissect_image_file(
if (r < 0)
return r;
m->image_size = st.st_size;
r = probe_sector_size(fd, &m->sector_size);
if (r < 0)
return r;
@@ -1759,8 +1765,9 @@ static int fs_grow(const char *node_path, int mount_fd, const char *mount_path)
if (node_fd < 0)
return log_debug_errno(errno, "Failed to open node device %s: %m", node_path);
if (ioctl(node_fd, BLKGETSIZE64, &size) != 0)
return log_debug_errno(errno, "Failed to get block device size of %s: %m", node_path);
r = blockdev_get_device_size(node_fd, &size);
if (r < 0)
return log_debug_errno(r, "Failed to get block device size of %s: %m", node_path);
if (mount_fd < 0) {
assert(mount_path);
@@ -3698,6 +3705,7 @@ int dissect_loop_device(
return r;
m->loop = loop_device_ref(loop);
m->image_size = m->loop->device_size;
m->sector_size = m->loop->sector_size;
r = dissect_image(m, loop->fd, loop->node, verity, mount_options, image_policy, flags);
+1
View File
@@ -102,6 +102,7 @@ struct DissectedImage {
DecryptedImage *decrypted_image;
uint32_t sector_size;
uint64_t image_size;
char *image_name;
sd_id128_t image_uuid;
+20 -4
View File
@@ -149,8 +149,9 @@ static int loop_configure_verify(int fd, const struct loop_config *c) {
* effect hence. And if not use classic LOOP_SET_STATUS64. */
uint64_t z;
if (ioctl(fd, BLKGETSIZE64, &z) < 0)
return -errno;
r = blockdev_get_device_size(fd, &z);
if (r < 0)
return r;
if (z != c->info.lo_sizelimit) {
log_debug("LOOP_CONFIGURE is broken, doesn't honour .info.lo_sizelimit. Falling back to LOOP_SET_STATUS64.");
@@ -404,6 +405,11 @@ static int loop_configure(
assert_not_reached();
}
uint64_t device_size;
r = blockdev_get_device_size(loop_with_fd, &device_size);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get loopback device size: %m");
LoopDevice *d = new(LoopDevice, 1);
if (!d)
return log_oom_debug();
@@ -420,6 +426,8 @@ static int loop_configure(
.uevent_seqnum_not_before = seqnum,
.timestamp_not_before = timestamp,
.sector_size = c->block_size,
.device_size = device_size,
.created = true,
};
*ret = TAKE_PTR(d);
@@ -944,6 +952,11 @@ int loop_device_open(
if (r < 0)
return r;
uint64_t device_size;
r = blockdev_get_device_size(fd, &device_size);
if (r < 0)
return r;
r = sd_device_get_devnum(dev, &devnum);
if (r < 0)
return r;
@@ -976,6 +989,8 @@ int loop_device_open(
.uevent_seqnum_not_before = UINT64_MAX,
.timestamp_not_before = USEC_INFINITY,
.sector_size = sector_size,
.device_size = device_size,
.created = false,
};
*ret = d;
@@ -1057,8 +1072,9 @@ static int resize_partition(int partition_fd, uint64_t offset, uint64_t size) {
return -EINVAL;
current_offset *= 512U;
if (ioctl(partition_fd, BLKGETSIZE64, &current_size) < 0)
return -EINVAL;
r = blockdev_get_device_size(partition_fd, &current_size);
if (r < 0)
return r;
if (size == UINT64_MAX && offset == UINT64_MAX)
return 0;
+2
View File
@@ -22,12 +22,14 @@ struct LoopDevice {
sd_device *dev;
char *backing_file;
bool relinquished;
bool created; /* If we created the device */
dev_t backing_devno; /* The backing file's dev_t */
ino_t backing_inode; /* The backing file's ino_t */
uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach, or 0 if we don't know */
uint64_t uevent_seqnum_not_before; /* uevent sequm right before we attached the loopback device, or UINT64_MAX if we don't know */
usec_t timestamp_not_before; /* CLOCK_MONOTONIC timestamp taken immediately before attaching the loopback device, or USEC_INFINITY if we don't know */
uint32_t sector_size;
uint64_t device_size;
};
/* Returns true if LoopDevice object is not actually a loopback device but some other block device we just wrap */