From 4cdd022ba42df17b027be7c35c7028d01b54cecc Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Tue, 27 Aug 2024 12:13:54 +0200 Subject: [PATCH 06/10] Fix detection of direct-io with suspended devices. Currently, direct-io is disabled if underlying device is suspended. This was an unfortunate change, as it is part of data corruption problem in online reenryption. Let's relax the test to assume that suspended device (suspended => must be a device-mapper device) supports direct-io. The read test is still needed as some network based devices misbehaves if opened with direct-io flag. --- lib/utils_device.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/utils_device.c b/lib/utils_device.c index eccaf048..6b7af6e1 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -127,11 +127,19 @@ static size_t device_alignment_fd(int devfd) return (size_t)alignment; } -static int device_read_test(int devfd) +static int device_read_test(struct crypt_device *cd, int devfd, struct device *device) { char buffer[512]; int r = -EIO; size_t minsize = 0, blocksize, alignment; + const char *dm_name; + + /* skip check for suspended DM devices */ + dm_name = device_dm_name(device); + if (dm_name && dm_status_suspended(cd, dm_name) > 0) { + log_dbg(cd, "Device %s is suspended, assuming direct-io is supported.", dm_name); + return 0; + } blocksize = device_block_size_fd(devfd, &minsize); alignment = device_alignment_fd(devfd); @@ -148,6 +156,8 @@ static int device_read_test(int devfd) if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize) r = 0; + log_dbg(cd, "Direct-io is supported and works."); + crypt_safe_memzero(buffer, sizeof(buffer)); return r; } @@ -165,7 +175,6 @@ static int device_ready(struct crypt_device *cd, struct device *device) int devfd = -1, r = 0; struct stat st; size_t tmp_size; - const char *dm_name; if (!device) return -EINVAL; @@ -176,12 +185,7 @@ static int device_ready(struct crypt_device *cd, struct device *device) device->o_direct = 0; devfd = open(device_path(device), O_RDONLY | O_DIRECT); if (devfd >= 0) { - /* skip check for suspended DM devices */ - dm_name = device_dm_name(device); - if (dm_name && dm_status_suspended(cd, dm_name) > 0) { - close(devfd); - devfd = -1; - } else if (device_read_test(devfd) == 0) { + if (device_read_test(cd, devfd, device) == 0) { device->o_direct = 1; } else { close(devfd); -- 2.46.0