You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cryptsetup/SOURCES/cryptsetup-2.7.5-Fix-detect...

79 lines
2.5 KiB

From 4cdd022ba42df17b027be7c35c7028d01b54cecc Mon Sep 17 00:00:00 2001
From: Milan Broz <gmazyland@gmail.com>
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