From 6d9c7c2551ca31a800f61e36192ee12be20974b1 Mon Sep 17 00:00:00 2001
From: Goldwyn Rodrigues <rgoldwyn@suse.com>
Date: Wed, 19 Aug 2015 07:38:27 +1000
Subject: [PATCH 164/359] Increment version for clustered bitmaps
References: bsc#1081910

Add BITMAP_MAJOR_CLUSTERED as 5, in order to prevent older kernels
to assemble a clustered device.

In order to maximize compatibility, the major version is set to
BITMAP_MAJOR_CLUSTERED *only* if the bitmap is clustered.

Also, added MD_FEATURE_CLUSTERED in order to return error
for older kernels which would assemble MD in case bitmap is
corrupted.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Coly Li <colyli@suse.de>

---
 Create.c | 2 ++
 Grow.c   | 3 +++
 bitmap.c | 2 +-
 bitmap.h | 1 +
 mdadm.c  | 5 +++--
 super1.c | 5 +++++
 6 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/Create.c b/Create.c
index b62d8d4..b200d97 100644
--- a/Create.c
+++ b/Create.c
@@ -114,6 +114,8 @@ int Create(struct supertype *st, char *mddev,
 	unsigned long long newsize;
 
 	int major_num = BITMAP_MAJOR_HI;
+	if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0)
+		major_num = BITMAP_MAJOR_CLUSTERED;
 
 	memset(&info, 0, sizeof(info));
 	if (s->level == UnSet && st && st->ss->default_geometry)
diff --git a/Grow.c b/Grow.c
index a1f8e4c..80d7b22 100644
--- a/Grow.c
+++ b/Grow.c
@@ -297,6 +297,9 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
 			"  between different architectures.  Consider upgrading the Linux kernel.\n");
 	}
 
+	if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0)
+		major = BITMAP_MAJOR_CLUSTERED;
+
 	if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
 		if (errno == ENOMEM)
 			pr_err("Memory allocation failure.\n");
diff --git a/bitmap.c b/bitmap.c
index 7beb80b..803eda3 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -287,7 +287,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
 	}
 	printf("         Version : %d\n", sb->version);
 	if (sb->version < BITMAP_MAJOR_LO ||
-	    sb->version > BITMAP_MAJOR_HI) {
+	    sb->version > BITMAP_MAJOR_CLUSTERED) {
 		pr_err("unknown bitmap version %d, either the bitmap file\n",
 		       sb->version);
 		pr_err("is corrupted or you need to upgrade your tools\n");
diff --git a/bitmap.h b/bitmap.h
index adbf0b4..b8fb071 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -12,6 +12,7 @@
  */
 #define BITMAP_MAJOR_HI 4
 #define	BITMAP_MAJOR_HOSTENDIAN 3
+#define	BITMAP_MAJOR_CLUSTERED 5
 
 #define BITMAP_MINOR 39
 
diff --git a/mdadm.c b/mdadm.c
index 5d5a1b8..cf3c360 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1409,8 +1409,9 @@ int main(int argc, char *argv[])
 		}
 
 		if (s.bitmap_file) {
-			if (strcmp(s.bitmap_file, "internal")==0) {
-				pr_err("'internal' bitmaps not supported with --build\n");
+			if (strcmp(s.bitmap_file, "internal")==0 ||
+			    strcmp(s.bitmap_file, "clustered") == 0) {
+				pr_err("'internal' and 'clustered' bitmaps not supported with --build\n");
 				rv |= 1;
 				break;
 			}
diff --git a/super1.c b/super1.c
index 9b991e6..52952eb 100644
--- a/super1.c
+++ b/super1.c
@@ -125,6 +125,7 @@ struct misc_dev_info {
 					    * backwards anyway.
 					    */
 #define	MD_FEATURE_NEW_OFFSET		64 /* new_offset must be honoured */
+#define	MD_FEATURE_BITMAP_VERSIONED	256 /* bitmap version number checked properly */
 #define	MD_FEATURE_ALL			(MD_FEATURE_BITMAP_OFFSET	\
 					|MD_FEATURE_RECOVERY_OFFSET	\
 					|MD_FEATURE_RESHAPE_ACTIVE	\
@@ -132,6 +133,7 @@ struct misc_dev_info {
 					|MD_FEATURE_REPLACEMENT		\
 					|MD_FEATURE_RESHAPE_BACKWARDS	\
 					|MD_FEATURE_NEW_OFFSET		\
+					|MD_FEATURE_BITMAP_VERSIONED	\
 					)
 
 /* return how many bytes are needed for bitmap, for cluster-md each node
@@ -2163,6 +2165,9 @@ add_internal_bitmap1(struct supertype *st,
 	bms->sync_size = __cpu_to_le64(size);
 	bms->write_behind = __cpu_to_le32(write_behind);
 	bms->nodes = __cpu_to_le32(st->nodes);
+	if (st->nodes)
+		sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map)
+						| MD_FEATURE_BITMAP_VERSIONED);
 	if (st->cluster_name)
 		strncpy((char *)bms->cluster_name,
 			st->cluster_name, strlen(st->cluster_name));
-- 
2.16.1

