Blame SOURCES/0008-lvresize-only-resize-crypt-when-fs-resize-is-enabled.patch

337b9c
From 7e0c2e1581225a916269edc8f04fb10e4ef5e952 Mon Sep 17 00:00:00 2001
337b9c
From: David Teigland <teigland@redhat.com>
337b9c
Date: Thu, 19 Jan 2023 11:36:51 -0600
337b9c
Subject: [PATCH 2/4] lvresize: only resize crypt when fs resize is enabled
337b9c
337b9c
There were a couple of cases where lvresize, without --fs resize,
337b9c
was resizing the crypt layer above the LV.  Resizing the crypt
337b9c
layer should only be done when fs resizing is enabled (even if the
337b9c
fs is already small enough due to being independently reduced.)
337b9c
337b9c
Also, check the size of the crypt device to see if it's already
337b9c
been reduced independently, and skip the cryptsetup resize if
337b9c
it's not needed.
337b9c
337b9c
(cherry picked from commit 3bb55765286dc8e4f0000957d85a6b8ee2752852)
337b9c
---
337b9c
 lib/device/filesystem.c         | 12 ++++++++++++
337b9c
 lib/device/filesystem.h         |  1 +
337b9c
 lib/metadata/lv_manip.c         | 18 +++++++++++++++++-
337b9c
 test/shell/lvresize-fs-crypt.sh |  7 ++++++-
337b9c
 4 files changed, 36 insertions(+), 2 deletions(-)
337b9c
337b9c
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
337b9c
index bdc230175..b4c43a626 100644
337b9c
--- a/lib/device/filesystem.c
337b9c
+++ b/lib/device/filesystem.c
337b9c
@@ -106,6 +106,7 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
337b9c
 	struct fs_info info;
337b9c
 	FILE *fme = NULL;
337b9c
 	struct mntent *me;
337b9c
+	int fd;
337b9c
 	int ret;
337b9c
 
337b9c
 	if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir,
337b9c
@@ -151,6 +152,17 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
337b9c
 		log_print("File system found on crypt device %s on LV %s.",
337b9c
 			  crypt_path, display_lvname(lv));
337b9c
 
337b9c
+		if ((fd = open(crypt_path, O_RDONLY)) < 0) {
337b9c
+			log_error("Failed to open crypt path %s", crypt_path);
337b9c
+			return 0;
337b9c
+		}
337b9c
+		if (ioctl(fd, BLKGETSIZE64, &info.crypt_dev_size_bytes) < 0) {
337b9c
+			log_error("Failed to get crypt device size %s", crypt_path);
337b9c
+			close(fd);
337b9c
+			return 0;
337b9c
+		}
337b9c
+		close(fd);
337b9c
+
337b9c
 		if (!fs_get_blkid(crypt_path, &info)) {
337b9c
 			log_error("No file system info from blkid for dm-crypt device %s on LV %s.",
337b9c
 				  crypt_path, display_lvname(lv));
337b9c
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
337b9c
index 7a34d2ae0..fd1af0416 100644
337b9c
--- a/lib/device/filesystem.h
337b9c
+++ b/lib/device/filesystem.h
337b9c
@@ -25,6 +25,7 @@ struct fs_info {
337b9c
 	uint64_t fs_last_byte; /* last byte on the device used by the fs */
337b9c
 	uint32_t crypt_offset_bytes; /* offset in bytes of crypt data on LV */
337b9c
 	dev_t crypt_devt; /* dm-crypt device between the LV and FS */
337b9c
+	uint64_t crypt_dev_size_bytes;
337b9c
 
337b9c
 	unsigned nofs:1;
337b9c
 	unsigned unmounted:1;
337b9c
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
337b9c
index f8eae0447..a2e9db2c9 100644
337b9c
--- a/lib/metadata/lv_manip.c
337b9c
+++ b/lib/metadata/lv_manip.c
337b9c
@@ -6397,7 +6397,23 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
337b9c
 	 * but the crypt dev over the LV should be shrunk to correspond with
337b9c
 	 * the LV size, so that the FS does not see an incorrect device size.
337b9c
 	 */
337b9c
-	if (!fsinfo.needs_reduce && fsinfo.needs_crypt && !test_mode()) {
337b9c
+	if (!fsinfo.needs_reduce && fsinfo.needs_crypt) {
337b9c
+		/* Check if the crypt device is already sufficiently reduced. */
337b9c
+		if (fsinfo.crypt_dev_size_bytes <= newsize_bytes_fs) {
337b9c
+			log_print("crypt device is already reduced to %llu bytes.",
337b9c
+				  (unsigned long long)fsinfo.crypt_dev_size_bytes);
337b9c
+			ret = 1;
337b9c
+			goto out;
337b9c
+		}
337b9c
+		if (!strcmp(lp->fsopt, "checksize")) {
337b9c
+			log_error("crypt reduce is required (see --resizefs or cryptsetup resize.)");
337b9c
+			ret = 0;
337b9c
+			goto out;
337b9c
+		}
337b9c
+		if (test_mode()) {
337b9c
+			ret = 1;
337b9c
+			goto_out;
337b9c
+		}
337b9c
 		ret = crypt_resize_script(cmd, lv, &fsinfo, newsize_bytes_fs);
337b9c
 		goto out;
337b9c
 	}
337b9c
diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh
337b9c
index 61a6de022..4bef771dc 100644
337b9c
--- a/test/shell/lvresize-fs-crypt.sh
337b9c
+++ b/test/shell/lvresize-fs-crypt.sh
337b9c
@@ -151,7 +151,12 @@ mount /dev/mapper/$cr "$mount_dir"
337b9c
 # this lvresize will not resize the fs (which is already reduced
337b9c
 # to smaller than the requested LV size), but lvresize will use
337b9c
 # the helper to resize the crypt dev before resizing the LV.
337b9c
-lvresize -L-100M $vg/$lv
337b9c
+# Using --fs resize is required to allow lvresize to look above
337b9c
+# the lv at crypt&fs layers for potential resizing.  Without
337b9c
+# --fs resize, lvresize fails because it sees that crypt resize
337b9c
+# is needed and --fs resize is needed to enable that.
337b9c
+not lvresize -L-100 $vg/$lv
337b9c
+lvresize -L-100M --fs resize $vg/$lv
337b9c
 check lv_field $vg/$lv lv_size "356.00m"
337b9c
 df --output=size "$mount_dir" |tee df2
337b9c
 not diff df1 df2
337b9c
-- 
337b9c
2.39.1
337b9c