Skip to content

Commit bbc0536

Browse files
onikombroz
authored andcommitted
Do not read test hotzone device repeatadly.
While allocating internal data structure for a device overlaying reencryption hotzone we accidentally read tested the device in each reencryption step. This was suboptimal so now the device is read only once while initializing the reencryption device-mapper stack.
1 parent c9fd8b5 commit bbc0536

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

lib/luks2/luks2_reencrypt.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct luks2_reencrypt {
5454
uint32_t wflags1;
5555
uint32_t wflags2;
5656

57+
struct device *hotzone_device;
58+
5759
struct crypt_lock_handle *reenc_lock;
5860
};
5961
#if USE_LUKS2_REENCRYPTION
@@ -882,6 +884,8 @@ void LUKS2_reencrypt_free(struct crypt_device *cd, struct luks2_reencrypt *rh)
882884
rh->cw1 = NULL;
883885
crypt_storage_wrapper_destroy(rh->cw2);
884886
rh->cw2 = NULL;
887+
device_free(cd, rh->hotzone_device);
888+
rh->hotzone_device = NULL;
885889

886890
free(rh->device_name);
887891
free(rh->overlay_name);
@@ -2142,34 +2146,22 @@ static int reencrypt_make_targets(struct crypt_device *cd,
21422146
* 2) can't we derive hotzone device name from crypt context? (unlocked name, device uuid, etc?)
21432147
*/
21442148
static int reencrypt_load_overlay_device(struct crypt_device *cd, struct luks2_hdr *hdr,
2145-
const char *overlay, const char *hotzone, struct volume_key *vks, uint64_t size,
2149+
const char *overlay, struct device *hotzone_device, struct volume_key *vks, uint64_t size,
21462150
uint32_t flags)
21472151
{
2148-
char hz_path[PATH_MAX];
21492152
int r;
21502153

2151-
struct device *hz_dev = NULL;
21522154
struct crypt_dm_active_device dmd = {
21532155
.flags = flags,
21542156
};
21552157

21562158
log_dbg(cd, "Loading new table for overlay device %s.", overlay);
21572159

2158-
r = snprintf(hz_path, PATH_MAX, "%s/%s", dm_get_dir(), hotzone);
2159-
if (r < 0 || r >= PATH_MAX) {
2160-
r = -EINVAL;
2161-
goto out;
2162-
}
2163-
2164-
r = device_alloc(cd, &hz_dev, hz_path);
2165-
if (r)
2166-
goto out;
2167-
21682160
r = dm_targets_allocate(&dmd.segment, LUKS2_segments_count(hdr));
21692161
if (r)
21702162
goto out;
21712163

2172-
r = reencrypt_make_targets(cd, hdr, hz_dev, vks, &dmd.segment, size);
2164+
r = reencrypt_make_targets(cd, hdr, hotzone_device, vks, &dmd.segment, size);
21732165
if (r < 0)
21742166
goto out;
21752167

@@ -2178,7 +2170,6 @@ static int reencrypt_load_overlay_device(struct crypt_device *cd, struct luks2_h
21782170
/* what else on error here ? */
21792171
out:
21802172
dm_targets_free(cd, &dmd);
2181-
device_free(cd, hz_dev);
21822173

21832174
return r;
21842175
}
@@ -2305,9 +2296,13 @@ static int reencrypt_activate_hotzone_device(struct crypt_device *cd, const char
23052296
}
23062297

23072298
static int reencrypt_init_device_stack(struct crypt_device *cd,
2308-
const struct luks2_reencrypt *rh)
2299+
struct luks2_reencrypt *rh)
23092300
{
23102301
int r;
2302+
char hz_path[PATH_MAX];
2303+
2304+
assert(rh);
2305+
assert(!rh->hotzone_device);
23112306

23122307
/* Activate hotzone device 1:1 linear mapping to data_device */
23132308
r = reencrypt_activate_hotzone_device(cd, rh->hotzone_name, rh->device_size, CRYPT_ACTIVATE_PRIVATE);
@@ -2316,6 +2311,18 @@ static int reencrypt_init_device_stack(struct crypt_device *cd,
23162311
return r;
23172312
}
23182313

2314+
r = snprintf(hz_path, PATH_MAX, "%s/%s", dm_get_dir(), rh->hotzone_name);
2315+
if (r < 0 || r >= PATH_MAX) {
2316+
r = -EINVAL;
2317+
goto err;
2318+
}
2319+
2320+
r = device_alloc(cd, &rh->hotzone_device, hz_path);
2321+
if (r) {
2322+
log_err(cd, _("Failed to allocate hotzone device %s."), rh->hotzone_name);
2323+
goto err;
2324+
}
2325+
23192326
/*
23202327
* Activate overlay device with exactly same table as original 'name' mapping.
23212328
* Note that within this step the 'name' device may already include a table
@@ -2395,11 +2402,12 @@ static int reencrypt_refresh_overlay_devices(struct crypt_device *cd,
23952402
struct luks2_hdr *hdr,
23962403
const char *overlay,
23972404
const char *hotzone,
2405+
struct device *hotzone_device,
23982406
struct volume_key *vks,
23992407
uint64_t device_size,
24002408
uint32_t flags)
24012409
{
2402-
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone, vks, device_size, flags);
2410+
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone_device, vks, device_size, flags);
24032411
if (r) {
24042412
log_err(cd, _("Failed to reload device %s."), overlay);
24052413
return REENC_ERR;
@@ -4083,7 +4091,8 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
40834091
}
40844092

40854093
if (online) {
4086-
r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, rh->vks, rh->device_size, rh->flags);
4094+
r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name,
4095+
rh->hotzone_device, rh->vks, rh->device_size, rh->flags);
40874096
/* Teardown overlay devices with dm-error. None bio shall pass! */
40884097
if (r != REENC_OK)
40894098
return r;

0 commit comments

Comments
 (0)