Blob Blame History Raw
From: Hannes Reinecke <hare@suse.de>
Date: Thu, 10 Mar 2016 09:42:36 +0100
Subject: loop: Compability for older releases
References: bsc#966891, FATE#320552
Patch-Mainline: no, SUSE-specific compability patch

The value of the LO_FLAGS_BLOCKSIZE flag has moved, as the original
value has been taken by the new flag LO_FLAG_DIRECT_IO. But as
the LO_FLAGS_BLOCK_SIZE requires a value in the 'init[0]' field
we can easily distinguish between the two use-cases.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/block/loop.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 9fa1b77..c5a73fc 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1098,7 +1098,7 @@ static int loop_clr_fd(struct loop_device *lo)
 	int err;
 	struct loop_func_table *xfer;
 	kuid_t uid = current_uid();
-	int lo_flags = lo->lo_flags;
+	int lo_flags = lo->lo_flags, info_flags;
 
 	if (lo->lo_encrypt_key_size &&
 	    !uid_eq(lo->lo_key_owner, uid) &&
@@ -1131,7 +1131,19 @@ static int loop_clr_fd(struct loop_device *lo)
 	if (err)
 		goto exit;
 
-	if (info->lo_flags & LO_FLAGS_BLOCKSIZE) {
+	/*
+	 * Compability with SLES12 SP1:
+	 * LO_FLAGS_BLOCKSIZE has the same value as the
+	 * new LO_DIRECT_IO. So check if the 'lo_init' field
+	 * is set; if it is, then we have the old-style usage
+	 * and we need to adjust the flags.
+	 */
+	info_flags = info->lo_flags;
+	if (info_flags & LO_FLAGS_DIRECT_IO && info->lo_init[0] != 0) {
+		info_flags |= LO_FLAGS_BLOCKSIZE;
+		info_flags &= ~LO_FLAGS_DIRECT_IO;
+	}
+	if (info_flags & LO_FLAGS_BLOCKSIZE) {
 		if (!(lo->lo_flags & LO_FLAGS_BLOCKSIZE))
 			lo->lo_logical_blocksize = 512;
 		lo->lo_flags |= LO_FLAGS_BLOCKSIZE;
-- 
1.8.5.6