/* LUKS2 volume key size. */
#define VOLUME_KEY_SIZE (512ULL/8ULL)
+/* Use 4K as the default filesystem sector size because as long as the partitions are aligned to 4K, the
+ * filesystems will then also be compatible with sector sizes 512, 1024 and 2048. */
+#define DEFAULT_FILESYSTEM_SECTOR_SIZE 4096ULL
+
#define APIVFS_TMP_DIRS_NULSTR "proc\0sys\0dev\0tmp\0run\0var/tmp\0"
/* Note: When growing and placing new partitions we always align to 4K sector size. It's how newer hard disks
uint64_t start, end, total;
struct fdisk_context *fdisk_context;
- uint64_t sector_size;
- uint64_t grain_size;
+ uint64_t sector_size, grain_size, fs_sector_size;
sd_id128_t seed;
sd_id128_t disk_uuid;
size_t n_partitions;
unsigned long secsz;
- uint64_t grainsz;
+ uint64_t grainsz, fs_secsz = DEFAULT_FILESYSTEM_SECTOR_SIZE;
int r;
assert(context);
if (!c)
return log_oom();
- if (arg_sector_size > 0)
+ if (arg_sector_size > 0) {
r = fdisk_save_user_sector_size(c, /* phy= */ 0, arg_sector_size);
- else {
+ fs_secsz = arg_sector_size;
+ } else {
uint32_t ssz;
+ struct stat st;
r = context_open_and_lock_backing_fd(context->node, arg_dry_run ? LOCK_SH : LOCK_EX,
&context->backing_fd);
if (r < 0)
return r;
+ if (fstat(context->backing_fd, &st) < 0)
+ return log_error_errno(r, "Failed to stat %s: %m", context->node);
+
/* Auto-detect sector size if not specified. */
r = probe_sector_size_prefer_ioctl(context->backing_fd, &ssz);
if (r < 0)
return log_error_errno(r, "Failed to probe sector size of '%s': %m", context->node);
+ /* If we found the sector size and we're operating on a block device, use it as the file
+ * system sector size as well, as we know its the sector size of the actual block device and
+ * not just the offset at which we found the GPT header. */
+ if (r > 0 && S_ISBLK(st.st_mode))
+ fs_secsz = ssz;
+
r = fdisk_save_user_sector_size(c, /* phy= */ 0, ssz);
}
if (r < 0)
if (S_ISREG(st.st_mode) && st.st_size == 0) {
/* Use the fallback values if we have no better idea */
- context->sector_size = arg_sector_size ?: 512;
+ context->sector_size = fdisk_get_sector_size(c);
+ context->fs_sector_size = fs_secsz;
context->grain_size = 4096;
return /* from_scratch = */ true;
}
context->end = last_lba;
context->total = nsectors;
context->sector_size = secsz;
+ context->fs_sector_size = fs_secsz;
context->grain_size = grainsz;
context->fdisk_context = TAKE_PTR(c);
const char *node = partition_target_path(target);
struct crypt_params_luks2 luks_params = {
.label = strempty(ASSERT_PTR(p)->new_label),
- .sector_size = ASSERT_PTR(context)->sector_size,
+ .sector_size = ASSERT_PTR(context)->fs_sector_size,
.data_device = offline ? node : NULL,
};
struct crypt_params_reencrypt reencrypt_params = {
/* Weird cryptsetup requirement which requires the header file to be the size of at least one
* sector. */
- r = ftruncate(fileno(h), context->sector_size);
+ r = ftruncate(fileno(h), luks_params.sector_size);
if (r < 0)
return log_error_errno(r, "Failed to grow temporary LUKS header file: %m");
} else {
.flags = CRYPT_VERITY_CREATE_HASH,
.hash_name = "sha256",
.hash_type = 1,
- .data_block_size = context->sector_size,
- .hash_block_size = context->sector_size,
+ .data_block_size = context->fs_sector_size,
+ .hash_block_size = context->fs_sector_size,
.salt_size = sizeof(p->verity_salt),
.salt = (const char*)p->verity_salt,
});
p->format);
r = make_filesystem(partition_target_path(t), p->format, strempty(p->new_label), root,
- p->fs_uuid, arg_discard, /* quiet = */ false, context->sector_size,
- extra_mkfs_options);
+ p->fs_uuid, arg_discard, /* quiet = */ false,
+ context->fs_sector_size, extra_mkfs_options);
if (r < 0)
return r;
"Failed to determine mkfs command line options for '%s': %m",
p->format);
- r = make_filesystem(d ? d->node : temp, p->format, strempty(p->new_label), root, fs_uuid,
- arg_discard, /* quiet = */ false, context->sector_size, extra_mkfs_options);
+ r = make_filesystem(d ? d->node : temp,
+ p->format,
+ strempty(p->new_label),
+ root,
+ fs_uuid,
+ arg_discard, /* quiet = */ false,
+ context->fs_sector_size,
+ extra_mkfs_options);
if (r < 0)
return r;
return log_error_errno(r, "Failed to make loopback device of %s: %m", temp);
}
- r = make_filesystem(d ? d->node : temp, p->format, strempty(p->new_label), root, p->fs_uuid,
- arg_discard, /* quiet = */ false, context->sector_size, extra_mkfs_options);
+ r = make_filesystem(d ? d->node : temp,
+ p->format,
+ strempty(p->new_label),
+ root,
+ p->fs_uuid,
+ arg_discard,
+ /* quiet = */ false,
+ context->fs_sector_size,
+ extra_mkfs_options);
if (r < 0)
return r;
char * const *extra_mkfs_args) {
_cleanup_free_ char *mkfs = NULL, *mangled_label = NULL;
- _cleanup_strv_free_ char **argv = NULL;
+ _cleanup_strv_free_ char **argv = NULL, **env = NULL;
_cleanup_(rm_rf_physical_and_freep) char *protofile_tmpdir = NULL;
_cleanup_(unlink_and_freep) char *protofile = NULL;
char vol_id[CONST_MAX(SD_ID128_UUID_STRING_MAX, 8U + 1U)] = {};
if (quiet && strv_extend(&argv, "-q") < 0)
return log_oom();
+ if (sector_size > 0)
+ FOREACH_STRING(s, "MKE2FS_DEVICE_SECTSIZE", "MKE2FS_DEVICE_PHYS_SECTSIZE") {
+ if (strv_extend(&env, s) < 0)
+ return log_oom();
+
+ if (strv_extendf(&env, "%"PRIu64, sector_size) < 0)
+ return log_oom();
+ }
+
} else if (streq(fstype, "btrfs")) {
argv = strv_new(mkfs,
"-L", label,
if (quiet && strv_extend(&argv, "-q") < 0)
return log_oom();
+ if (sector_size > 0) {
+ if (strv_extend(&argv, "-w") < 0)
+ return log_oom();
+
+ if (strv_extendf(&argv, "%"PRIu64, sector_size) < 0)
+ return log_oom();
+ }
+
} else if (streq(fstype, "xfs")) {
const char *j;
if (r == 0) {
/* Child */
+ STRV_FOREACH_PAIR(k, v, env)
+ if (setenv(*k, *v, /* replace = */ true) < 0) {
+ log_error_errno(r, "Failed to set %s=%s environment variable: %m", *k, *v);
+ _exit(EXIT_FAILURE);
+ }
+
/* mkfs.btrfs refuses to operate on block devices with mounted partitions, even if operating
* on unformatted free space, so let's trick it and other mkfs tools into thinking no
* partitions are mounted. See https://github.com/kdave/btrfs-progs/issues/640 for more