From 2790a782cecd2c602e0ca905d67c39a492562a30 Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Fri, 27 Dec 2024 12:52:02 +0530 Subject: [PATCH 1/7] homework: Use same sector size as fdisk context Ensure we use the same sector size as used in the created fdisk context when converting between sectors and bytes. --- src/home/homework-luks.c | 69 +++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 9147b3dfcf..7ae0f80985 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -1887,7 +1887,7 @@ static int make_partition_table( _cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL; _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; _cleanup_free_ char *disk_uuid_as_string = NULL; - uint64_t offset, size, first_lba, start, last_lba, end; + uint64_t offset, size, first_lba, start, last_lba, end, fdisk_sector_size; sd_id128_t disk_uuid; int r; @@ -1924,9 +1924,13 @@ static int make_partition_table( if (r < 0) return log_error_errno(r, "Failed to place partition at first free partition index: %m"); + /* Use same sector size as the fdisk context when converting to bytes */ + fdisk_sector_size = fdisk_get_sector_size(c); + assert(fdisk_sector_size > 0); + first_lba = fdisk_get_first_lba(c); /* Boundary where usable space starts */ - assert(first_lba <= UINT64_MAX/512); - start = DISK_SIZE_ROUND_UP(first_lba * 512); /* Round up to multiple of 4K */ + assert(first_lba <= UINT64_MAX / fdisk_sector_size); + start = DISK_SIZE_ROUND_UP(first_lba * fdisk_sector_size); log_debug("Starting partition at offset %" PRIu64, start); @@ -1934,17 +1938,17 @@ static int make_partition_table( return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Overflow while rounding up start LBA."); last_lba = fdisk_get_last_lba(c); /* One sector before boundary where usable space ends */ - assert(last_lba < UINT64_MAX/512); - end = DISK_SIZE_ROUND_DOWN((last_lba + 1) * 512); /* Round down to multiple of 4K */ + assert(last_lba < UINT64_MAX / fdisk_sector_size); + end = DISK_SIZE_ROUND_DOWN((last_lba + 1) * fdisk_sector_size); if (end <= start) return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Resulting partition size zero or negative."); - r = fdisk_partition_set_start(p, start / 512); + r = fdisk_partition_set_start(p, start / fdisk_sector_size); if (r < 0) return log_error_errno(r, "Failed to place partition at offset %" PRIu64 ": %m", start); - r = fdisk_partition_set_size(p, (end - start) / 512); + r = fdisk_partition_set_size(p, (end - start) / fdisk_sector_size); if (r < 0) return log_error_errno(r, "Failed to end partition at offset %" PRIu64 ": %m", end); @@ -1978,16 +1982,16 @@ static int make_partition_table( assert(fdisk_partition_has_start(q)); offset = fdisk_partition_get_start(q); - if (offset > UINT64_MAX / 512U) + if (offset > UINT64_MAX / fdisk_sector_size) return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Partition offset too large."); assert(fdisk_partition_has_size(q)); size = fdisk_partition_get_size(q); - if (size > UINT64_MAX / 512U) + if (size > UINT64_MAX / fdisk_sector_size) return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Partition size too large."); - *ret_offset = offset * 512U; - *ret_size = size * 512U; + *ret_offset = offset * fdisk_sector_size; + *ret_size = size * fdisk_sector_size; *ret_disk_uuid = disk_uuid; return 0; @@ -2753,6 +2757,7 @@ static int prepare_resize_partition( n_partitions = fdisk_table_get_nents(t); for (size_t i = 0; i < n_partitions; i++) { struct fdisk_partition *p; + uint64_t fdisk_sector_size; p = fdisk_table_get_partition(t, i); if (!p) @@ -2763,14 +2768,16 @@ static int prepare_resize_partition( if (fdisk_partition_has_start(p) <= 0 || fdisk_partition_has_size(p) <= 0 || fdisk_partition_has_end(p) <= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Found partition without a size."); - if (fdisk_partition_get_start(p) == partition_offset / 512U && - fdisk_partition_get_size(p) == old_partition_size / 512U) { + fdisk_sector_size = fdisk_get_sector_size(c); + assert(fdisk_sector_size > 0); + if (fdisk_partition_get_start(p) == partition_offset / fdisk_sector_size && + fdisk_partition_get_size(p) == old_partition_size / fdisk_sector_size) { if (found) return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Partition found twice, refusing."); found = p; - } else if (fdisk_partition_get_end(p) > partition_offset / 512U) + } else if (fdisk_partition_get_end(p) > partition_offset / fdisk_sector_size) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Can't extend, not last partition in image."); } @@ -2790,7 +2797,7 @@ static int get_maximum_partition_size( uint64_t *ret_maximum_partition_size) { _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; - uint64_t start_lba, start, last_lba, end; + uint64_t start_lba, start, last_lba, end, fdisk_sector_size; int r; assert(fd >= 0); @@ -2801,13 +2808,15 @@ static int get_maximum_partition_size( if (r < 0) return log_error_errno(r, "Failed to create fdisk context: %m"); + /* Get the probed sector size by fdisk */ + fdisk_sector_size = fdisk_get_sector_size(c); start_lba = fdisk_partition_get_start(p); - assert(start_lba <= UINT64_MAX/512); - start = start_lba * 512; + assert(start_lba <= UINT64_MAX / fdisk_sector_size); + start = start_lba * fdisk_sector_size; last_lba = fdisk_get_last_lba(c); /* One sector before boundary where usable space ends */ - assert(last_lba < UINT64_MAX/512); - end = DISK_SIZE_ROUND_DOWN((last_lba + 1) * 512); /* Round down to multiple of 4K */ + assert(last_lba < UINT64_MAX / fdisk_sector_size); + end = DISK_SIZE_ROUND_DOWN((last_lba + 1) * fdisk_sector_size); if (start > end) return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Last LBA is before partition start."); @@ -2860,15 +2869,6 @@ static int apply_resize_partition( assert(p); - /* Before writing our partition patch the final size in */ - r = fdisk_partition_size_explicit(p, 1); - if (r < 0) - return log_error_errno(r, "Failed to enable explicit partition size: %m"); - - r = fdisk_partition_set_size(p, new_partition_size / 512U); - if (r < 0) - return log_error_errno(r, "Failed to change partition size: %m"); - r = probe_sector_size(fd, &ssz); if (r < 0) return log_error_errno(r, "Failed to determine current sector size: %m"); @@ -2888,6 +2888,15 @@ static int apply_resize_partition( if (r < 0) return log_error_errno(r, "Failed to open device: %m"); + /* Before writing our partition patch the final size in */ + r = fdisk_partition_size_explicit(p, 1); + if (r < 0) + return log_error_errno(r, "Failed to enable explicit partition size: %m"); + + r = fdisk_partition_set_size(p, new_partition_size / ssz); + if (r < 0) + return log_error_errno(r, "Failed to change partition size: %m"); + r = fdisk_create_disklabel(c, "gpt"); if (r < 0) return log_error_errno(r, "Failed to create GPT disk label: %m"); @@ -3472,6 +3481,7 @@ int home_resize_luks( (void) reread_partition_table_fd(image_fd, /* flags= */ 0); /* Tell LUKS about the new bigger size too */ + /* libcrypsetup uses units of 512B sectors for size */ r = sym_crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512U); if (r < 0) return log_error_errno(r, "Failed to grow LUKS device: %m"); @@ -3536,7 +3546,8 @@ int home_resize_luks( if (new_fs_size < old_fs_size) { /* → Shrink */ /* Shrink the LUKS device now, matching the new file system size */ - r = sym_crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512); + /* libcrypsetup uses units of 512B sectors for size */ + r = sym_crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512U); if (r < 0) return log_error_errno(r, "Failed to shrink LUKS device: %m"); From a24f11798b13e17d4f88dd1af2b962c98800da37 Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:56:12 +0530 Subject: [PATCH 2/7] homework: Remove zeroing of PMBR Remove zeroing of PMBR before writing out the new partition table. There is no reason, to do this explicitly ? --- src/home/homework-luks.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 7ae0f80985..e559836cc4 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -2856,9 +2856,7 @@ static int apply_resize_partition( size_t new_partition_size) { _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; - _cleanup_free_ void *two_zero_lbas = NULL; uint32_t ssz; - ssize_t n; int r; assert(fd >= 0); @@ -2873,17 +2871,6 @@ static int apply_resize_partition( if (r < 0) return log_error_errno(r, "Failed to determine current sector size: %m"); - two_zero_lbas = malloc0(ssz * 2); - if (!two_zero_lbas) - return log_oom(); - - /* libfdisk appears to get confused by the existing PMBR. Let's explicitly flush it out. */ - n = pwrite(fd, two_zero_lbas, ssz * 2, 0); - if (n < 0) - return log_error_errno(errno, "Failed to wipe partition table: %m"); - if ((size_t) n != ssz * 2) - return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while wiping partition table."); - r = fdisk_new_context_at(fd, /* path= */ NULL, /* read_only= */ false, ssz, &c); if (r < 0) return log_error_errno(r, "Failed to open device: %m"); From fc280b64e8fbb4c2306ef7e3737227f518795750 Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Fri, 27 Dec 2024 17:19:34 +0530 Subject: [PATCH 3/7] homework: Auto-probe luks sector size Auto-probe the luks sector size, if not explicitly specified in the home record --- src/home/homework-luks.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index e559836cc4..44f020d8ae 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -1755,6 +1755,7 @@ static int luks_format( const PasswordCache *cache, char **effective_passwords, bool discard, + uint64_t sector_size, UserRecord *hr, struct crypt_device **ret) { @@ -1809,7 +1810,7 @@ static int luks_format( &(struct crypt_params_luks2) { .label = label, .subsystem = "systemd-home", - .sector_size = user_record_luks_sector_size(hr), + .sector_size = sector_size, /* sector-size of 0 is auto for libcryptsetup */ .pbkdf = &good_pbkdf, }); if (r < 0) @@ -2166,7 +2167,7 @@ int home_create_luks( UserRecord **ret_home) { _cleanup_free_ char *subdir = NULL, *disk_uuid_path = NULL; - uint64_t encrypted_size, + uint64_t encrypted_size, image_sector_size, luks_sector_size, host_size = 0, partition_offset = 0, partition_size = 0; /* Unnecessary initialization to appease gcc */ _cleanup_(user_record_unrefp) UserRecord *new_home = NULL; sd_id128_t partition_uuid, fs_uuid, luks_uuid, disk_uuid; @@ -2337,9 +2338,17 @@ int home_create_luks( log_info("Allocating image file completed."); } + if (h->luks_sector_size == UINT64_MAX) { + /* If sector size is not specified, select UINT32_MAX, i.e. auto-probe */ + image_sector_size = UINT32_MAX; + /* Let cryptsetup decide if the sector size is not specified in home record */ + luks_sector_size = 0; + } else + luks_sector_size = image_sector_size = user_record_luks_sector_size(h); + r = make_partition_table( setup->image_fd, - user_record_luks_sector_size(h), + image_sector_size, user_record_user_name_and_realm(h), partition_uuid, &partition_offset, @@ -2355,7 +2364,7 @@ int home_create_luks( O_RDWR, partition_offset, partition_size, - user_record_luks_sector_size(h), + image_sector_size, 0, LOCK_EX, &setup->loop); @@ -2375,6 +2384,7 @@ int home_create_luks( cache, effective_passwords, user_record_luks_discard(h) || user_record_luks_offline_discard(h), + luks_sector_size, h, &setup->crypt_device); if (r < 0) From 118cccf97fa39e46a8f84f57c8bb73bb436e74b0 Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:34:36 +0530 Subject: [PATCH 4/7] homework: Align partitions to 1MiB Align partitions to 1MiB for consistency with regular partition tools which use 1MiB alignment by default --- src/home/homework-luks.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 44f020d8ae..3ee16fe815 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -66,16 +66,16 @@ #include "user-record.h" #include "user-util.h" -/* Round down to the nearest 4K size. Given that newer hardware generally prefers 4K sectors, let's align our - * partitions to that too. In the worst case we'll waste 3.5K per partition that way, but I think I can live +/* Round down to the nearest 1 MiB size. Given that most tools generally align partitions to 1 MiB boundaries, let's align our + * partitions to that too. In the worst case we'll waste 1 MiB per partition that way, but I think I can live * with that. */ -#define DISK_SIZE_ROUND_DOWN(x) ((x) & ~UINT64_C(4095)) +#define DISK_SIZE_ROUND_DOWN(x) ((x) & ~(U64_MB - 1)) -/* Rounds up to the nearest 4K boundary. Returns UINT64_MAX on overflow */ +/* Rounds up to the nearest 1 MiB boundary. Returns UINT64_MAX on overflow */ #define DISK_SIZE_ROUND_UP(x) \ ({ \ uint64_t _x = (x); \ - _x > UINT64_MAX - 4095U ? UINT64_MAX : (_x + 4095U) & ~UINT64_C(4095); \ + _x > UINT64_MAX - (U64_MB - 1) ? UINT64_MAX : (DISK_SIZE_ROUND_DOWN(_x + U64_MB - 1)); \ }) /* How much larger will the image on disk be than the fs inside it, i.e. the space we pay for the GPT and From 292525dd20ce2b6ecb6511c470bcddcb06a3ea16 Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Sat, 28 Dec 2024 09:13:34 +0530 Subject: [PATCH 5/7] homework: Use same sector size when probing the device If there is an explicit sector size specified in the user record, use the same when probing the file using libblkid. The default is 512 bytes, which will not be able to find the signatures, if the partition table on regular file was created assuming 4k sectors --- src/home/homework-luks.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 3ee16fe815..5e6d782fdb 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -666,6 +666,7 @@ static int luks_validate( int fd, const char *label, sd_id128_t partition_uuid, + uint64_t sector_size, sd_id128_t *ret_partition_uuid, uint64_t *ret_offset, uint64_t *ret_size) { @@ -683,6 +684,7 @@ static int luks_validate( assert(label); assert(ret_offset); assert(ret_size); + assert(sector_size > 0); r = dlopen_libblkid(); if (r < 0) @@ -697,6 +699,12 @@ static int luks_validate( if (r != 0) return errno_or_else(ENOMEM); + /* Set probing sector size if explicitly specified */ + if (sector_size != UINT32_MAX) { + r = sym_blkid_probe_set_sectorsize(b, sector_size); + if (r != 0) + return errno_or_else(EINVAL); + } (void) sym_blkid_probe_enable_superblocks(b, 1); (void) sym_blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE); (void) sym_blkid_probe_enable_partitions(b, 1); @@ -778,6 +786,7 @@ static int luks_validate( if ((uint64_t) size > UINT64_MAX / 512U) return -EINVAL; + /* libblkid returns partitions sizes in count of 512-sectors. This does not necessarily need to match the device sector size */ *ret_offset = offset * 512U; *ret_size = size * 512U; *ret_partition_uuid = found_partition_uuid; @@ -1401,7 +1410,15 @@ int home_setup_luks( if (!subdir) return log_oom(); - r = luks_validate(setup->image_fd, user_record_user_name_and_realm(h), h->partition_uuid, &found_partition_uuid, &offset, &size); + r = luks_validate( + setup->image_fd, + user_record_user_name_and_realm(h), + h->partition_uuid, + /* if sector size is not specified, select UINT32_MAX, i.e. auto-probe */ + h->luks_sector_size == UINT64_MAX ? UINT32_MAX : user_record_luks_sector_size(h), + &found_partition_uuid, + &offset, + &size); if (r < 0) return log_error_errno(r, "Failed to validate disk label: %m"); From 6a389701b22af2a5d492df328cd883a3889b2c1f Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Sat, 28 Dec 2024 13:25:25 +0530 Subject: [PATCH 6/7] homework: Ensure we don't stack block devices Ensure we don't create a loop device on top of a physical block device. This leads to huge performance degradation of discard operations if the physical device does not support discard_on_zeroes. - loop device historical semantics dictates that when the device is discarded, it needs to return zero data on read. This can be implemented easily on a filesystem. since fallocate zero-range would return immediately & the holes are handled at the filesystem level to return zero data on read. - For a raw block device, the feature (discard_zeroes_data) depends on the capabilities of the physical device that is exposed to the block layer by the driver. This means that to guarantee that the loop device stacked on a block device returns zero on discarded data, it needs to convert discarded range into write_zero op on the block device. https://github.com/torvalds/linux/blob/63676eefb7a026d04b51dcb7aaf54f358517a2ec/drivers/block/loop.c#L773 For example on one of my local nvme I can see the following: cat /sys/class/block/nvme1n1/queue/write_zeroes_max_bytes 131072 cat /sys/class/block/nvme0n1/queue/discard_max_hw_bytes 2199023255040 This means maximum size of a write_zero operation can be 128KiB & maximum size of discard operation can be 2TiB on the block device. So discarding for example 1TB of data, which would be a single block device operation, gets split into 8.3 million block device operations when issued on top of stacked loop device. --- src/home/homework-luks.c | 64 ++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 5e6d782fdb..e7dc26794c 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -1433,6 +1433,11 @@ int home_setup_luks( return r; } + /* Before we make the loop device, make sure offset is zero & we are using the full partition + * If our offset is not zero, loop_device_make will create a loop device on top of the block device */ + if (S_ISBLK(st.st_mode)) + assert(offset == 0 && size == UINT64_MAX); + r = loop_device_make( setup->image_fd, O_RDWR, @@ -2191,6 +2196,7 @@ int home_create_luks( _cleanup_close_ int mount_fd = -EBADF; const char *fstype, *ip; struct statfs sfs; + struct stat st; int r; _cleanup_strv_free_ char **extra_mkfs_options = NULL; @@ -2263,7 +2269,6 @@ int home_create_luks( if (path_startswith(ip, "/dev/")) { _cleanup_free_ char *sysfs = NULL; uint64_t block_device_size; - struct stat st; /* Let's place the home directory on a real device, i.e. a USB stick or such */ @@ -2376,21 +2381,48 @@ int home_create_luks( log_info("Writing of partition table completed."); - r = loop_device_make( - setup->image_fd, - O_RDWR, - partition_offset, - partition_size, - image_sector_size, - 0, - LOCK_EX, - &setup->loop); - if (r == -ENOENT) /* this means /dev/loop-control doesn't exist, i.e. we are in a container - * or similar and loopback bock devices are not available, return a - * recognizable error in this case. */ - return log_error_errno(SYNTHETIC_ERRNO(ENOLINK), "Loopback block device support is not available on this system."); - if (r < 0) - return log_error_errno(r, "Failed to set up loopback device for %s: %m", setup->temporary_image_path); + if (fstat(setup->image_fd, &st) < 0) + return log_error_errno(errno, "Failed to fstat home image: %m"); + + /* Ensure we don't create a loop device over block device as it leads to huge overhead for discard operations + * if the device does not support discard_zeroes_data */ + if (S_ISBLK(st.st_mode)) { + _cleanup_free_ char *partition_path = NULL; + assert(!sd_id128_is_null(partition_uuid)); + if (asprintf(&partition_path, "/dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(partition_uuid)) < 0) + return log_oom(); + + /* Release the lock, so that udev can find the partition */ + setup->image_fd = safe_close(setup->image_fd); + (void) wait_for_devlink(partition_path); + setup->image_fd = open_image_file(h, ip, &st); + if (setup->image_fd < 0) + return setup->image_fd; + + r = loop_device_open_from_path( + partition_path, + O_RDWR, + LOCK_EX, + &setup->loop); + if (r < 0) + return log_error_errno(r, "Failed to open newly written partition device: %s", partition_path); + } else { + r = loop_device_make( + setup->image_fd, + O_RDWR, + partition_offset, + partition_size, + image_sector_size, + 0, + LOCK_EX, + &setup->loop); + if (r == -ENOENT) /* this means /dev/loop-control doesn't exist, i.e. we are in a container + * or similar and loopback bock devices are not available, return a + * recognizable error in this case. */ + return log_error_errno(SYNTHETIC_ERRNO(ENOLINK), "Loopback block device support is not available on this system."); + if (r < 0) + return log_error_errno(r, "Failed to set up loopback device for %s: %m", setup->temporary_image_path); + } log_info("Setting up loopback device %s completed.", setup->loop->node ?: ip); From 48b9d7e980e5ca182af0f9e06a5c67e727f606d2 Mon Sep 17 00:00:00 2001 From: scarlet-storm <12461256+scarlet-storm@users.noreply.github.com> Date: Sat, 28 Dec 2024 14:14:11 +0530 Subject: [PATCH 7/7] Use sectorsize for partition tables on block devs Fix for specific case #30393 where 4k sector luks container is created on a 512b device. In this case the partition table needs to be 512b, else the kernel will not be able to find the partition, and we will have to create a loop device to translate the partition table to 4k. --- src/home/homework-luks.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index e7dc26794c..9f7af06a4e 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -2365,9 +2365,15 @@ int home_create_luks( image_sector_size = UINT32_MAX; /* Let cryptsetup decide if the sector size is not specified in home record */ luks_sector_size = 0; - } else - luks_sector_size = image_sector_size = user_record_luks_sector_size(h); - + } else { + if (S_ISBLK(st.st_mode)) { + /* For physical block devices always use the actual device logical + * sector size. Else the partition will not be discoverable by kernel. */ + image_sector_size = UINT32_MAX; + luks_sector_size = user_record_luks_sector_size(h); + } else + image_sector_size = luks_sector_size = user_record_luks_sector_size(h); + } r = make_partition_table( setup->image_fd, image_sector_size,