From d13a6f7487eb7519bc1e4302085b21ca98afabc0 Mon Sep 17 00:00:00 2001 From: Ondrej Kozina Date: Thu, 22 Aug 2019 17:05:43 +0200 Subject: [PATCH 1/5] Take optimal io size in account with LUKS2 reencryption. If device properly exposes optimal io size, let's align reencryption hotzone to it. Otherwise device-mapper driver complaints about misaligned tables and reencryption performance is not optimal. --- lib/luks2/luks2_reencrypt.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c index 1d70aaf..1f5eb5f 100644 --- a/lib/luks2/luks2_reencrypt.c +++ b/lib/luks2/luks2_reencrypt.c @@ -817,8 +817,13 @@ static int reencrypt_offset(struct luks2_hdr *hdr, return -EINVAL; } -static uint64_t reencrypt_length(struct luks2_hdr *hdr, struct luks2_reenc_context *rh, uint64_t keyslot_area_length, uint64_t length_max) +static uint64_t reencrypt_length(struct crypt_device *cd, + struct luks2_hdr *hdr, + struct luks2_reenc_context *rh, + uint64_t keyslot_area_length, + uint64_t length_max) { + unsigned long dummy, optimal_alignment; uint64_t length; if (rh->rp.type == REENC_PROTECTION_NONE) @@ -835,6 +840,20 @@ static uint64_t reencrypt_length(struct luks2_hdr *hdr, struct luks2_reenc_conte length -= (length % rh->alignment); + /* Emits error later */ + if (!length) + return length; + + device_topology_alignment(cd, crypt_data_device(cd), &optimal_alignment, &dummy, length); + + /* we have to stick with encryption sector size alignment */ + if (optimal_alignment % rh->alignment) + return length; + + /* align to opt-io size only if remaining size allows it */ + if (length > optimal_alignment) + length -= (length % optimal_alignment); + return length; } @@ -920,7 +939,7 @@ static int reencrypt_context_init(struct crypt_device *cd, struct luks2_hdr *hdr } else rh->fixed_length = false; - rh->length = reencrypt_length(hdr, rh, area_length, params->max_hotzone_size << SECTOR_SHIFT); + rh->length = reencrypt_length(cd, hdr, rh, area_length, params->max_hotzone_size << SECTOR_SHIFT); if (reencrypt_offset(hdr, rh->direction, device_size, &rh->length, &rh->offset)) { log_dbg(cd, "Failed to get reencryption offset."); return -EINVAL; -- 1.8.3.1