diff --git a/SOURCES/0078-Makefile-add-EXTRAVERSION-support.patch b/SOURCES/0078-Makefile-add-EXTRAVERSION-support.patch
new file mode 100644
index 0000000..c653eaf
--- /dev/null
+++ b/SOURCES/0078-Makefile-add-EXTRAVERSION-support.patch
@@ -0,0 +1,49 @@
+From 03ab9763f51ddf2030f60f83e76cf9c1b50b726c Mon Sep 17 00:00:00 2001
+From: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
+Date: Fri, 15 May 2020 11:23:14 +0200
+Subject: [PATCH 078/108] Makefile: add EXTRAVERSION support
+
+Add optional EXTRAVERSION parameter to Makefile and allow to mark version
+by user friendly label. It might be useful when creating custom
+spins of mdadm, or labeling some instance in between major releases.
+
+Signed-off-by: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile | 3 ++-
+ ReadMe.c | 5 ++++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index a33319a..0a20b75 100644
+--- a/Makefile
++++ b/Makefile
+@@ -105,7 +105,8 @@ VERSION = $(shell [ -d .git ] && git describe HEAD | sed 's/mdadm-//')
+ VERS_DATE = $(shell [ -d .git ] && date --iso-8601 --date="`git log -n1 --format=format:%cd --date=iso --date=short`")
+ DVERS = $(if $(VERSION),-DVERSION=\"$(VERSION)\",)
+ DDATE = $(if $(VERS_DATE),-DVERS_DATE="\"$(VERS_DATE)\"",)
+-CFLAGS += $(DVERS) $(DDATE)
++DEXTRAVERSION = $(if $(EXTRAVERSION),-DEXTRAVERSION="\" - $(EXTRAVERSION)\"",)
++CFLAGS += $(DVERS) $(DDATE) $(DEXTRAVERSION)
+ 
+ # The glibc TLS ABI requires applications that call clone(2) to set up
+ # TLS data structures, use pthreads until mdmon implements this support
+diff --git a/ReadMe.c b/ReadMe.c
+index eaf1042..06b8f7e 100644
+--- a/ReadMe.c
++++ b/ReadMe.c
+@@ -33,7 +33,10 @@
+ #ifndef VERS_DATE
+ #define VERS_DATE "2018-10-01"
+ #endif
+-char Version[] = "mdadm - v" VERSION " - " VERS_DATE "\n";
++#ifndef EXTRAVERSION
++#define EXTRAVERSION ""
++#endif
++char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n";
+ 
+ /*
+  * File: ReadMe.c
+-- 
+2.7.5
+
diff --git a/SOURCES/0079-uuid.c-split-uuid-stuffs-from-util.c.patch b/SOURCES/0079-uuid.c-split-uuid-stuffs-from-util.c.patch
new file mode 100644
index 0000000..dfa9e4d
--- /dev/null
+++ b/SOURCES/0079-uuid.c-split-uuid-stuffs-from-util.c.patch
@@ -0,0 +1,284 @@
+From f4c8a605d2467c0ed25fcba5d27dd56540660e55 Mon Sep 17 00:00:00 2001
+From: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
+Date: Mon, 18 May 2020 23:53:35 +0200
+Subject: [PATCH 079/108] uuid.c: split uuid stuffs from util.c
+
+Currently, 'make raid6check' is build broken since commit b06815989
+("mdadm: load default sysfs attributes after assemblation").
+
+/usr/bin/ld: sysfs.o: in function `sysfsline':
+sysfs.c:(.text+0x2707): undefined reference to `parse_uuid'
+/usr/bin/ld: sysfs.c:(.text+0x271a): undefined reference to `uuid_zero'
+/usr/bin/ld: sysfs.c:(.text+0x2721): undefined reference to `uuid_zero'
+
+Apparently, the compile of mdadm or raid6check are coupled with uuid
+functions inside util.c. However, we can't just add util.o to CHECK_OBJS
+which raid6check is needed, because it caused other worse problems.
+
+So, let's introduce a uuid.c file which is indenpended file to fix the
+problem, all the contents are splitted from util.c.
+
+Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile |   6 ++--
+ util.c   |  87 -------------------------------------------------
+ uuid.c   | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 115 insertions(+), 90 deletions(-)
+ create mode 100644 uuid.c
+
+diff --git a/Makefile b/Makefile
+index 0a20b75..15d05d1 100644
+--- a/Makefile
++++ b/Makefile
+@@ -140,7 +140,7 @@ else
+ 	ECHO=:
+ endif
+ 
+-OBJS =  mdadm.o config.o policy.o mdstat.o  ReadMe.o util.o maps.o lib.o \
++OBJS =  mdadm.o config.o policy.o mdstat.o  ReadMe.o uuid.o util.o maps.o lib.o \
+ 	Manage.o Assemble.o Build.o \
+ 	Create.o Detail.o Examine.o Grow.o Monitor.o dlink.o Kill.o Query.o \
+ 	Incremental.o Dump.o \
+@@ -149,13 +149,13 @@ OBJS =  mdadm.o config.o policy.o mdstat.o  ReadMe.o util.o maps.o lib.o \
+ 	restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \
+ 	platform-intel.o probe_roms.o crc32c.o
+ 
+-CHECK_OBJS = restripe.o sysfs.o maps.o lib.o xmalloc.o dlink.o
++CHECK_OBJS = restripe.o uuid.o sysfs.o maps.o lib.o xmalloc.o dlink.o
+ 
+ SRCS =  $(patsubst %.o,%.c,$(OBJS))
+ 
+ INCL = mdadm.h part.h bitmap.h
+ 
+-MON_OBJS = mdmon.o monitor.o managemon.o util.o maps.o mdstat.o sysfs.o \
++MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o \
+ 	policy.o lib.o \
+ 	Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \
+ 	super-mbr.o super-gpt.o \
+diff --git a/util.c b/util.c
+index 07f9dc3..579dd42 100644
+--- a/util.c
++++ b/util.c
+@@ -306,43 +306,6 @@ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk)
+ 	return ioctl(fd, GET_DISK_INFO, disk);
+ }
+ 
+-/*
+- * Parse a 128 bit uuid in 4 integers
+- * format is 32 hexx nibbles with options :.<space> separator
+- * If not exactly 32 hex digits are found, return 0
+- * else return 1
+- */
+-int parse_uuid(char *str, int uuid[4])
+-{
+-	int hit = 0; /* number of Hex digIT */
+-	int i;
+-	char c;
+-	for (i = 0; i < 4; i++)
+-		uuid[i] = 0;
+-
+-	while ((c = *str++) != 0) {
+-		int n;
+-		if (c >= '0' && c <= '9')
+-			n = c-'0';
+-		else if (c >= 'a' && c <= 'f')
+-			n = 10 + c - 'a';
+-		else if (c >= 'A' && c <= 'F')
+-			n = 10 + c - 'A';
+-		else if (strchr(":. -", c))
+-			continue;
+-		else return 0;
+-
+-		if (hit<32) {
+-			uuid[hit/8] <<= 4;
+-			uuid[hit/8] += n;
+-		}
+-		hit++;
+-	}
+-	if (hit == 32)
+-		return 1;
+-	return 0;
+-}
+-
+ int get_linux_version()
+ {
+ 	struct utsname name;
+@@ -611,56 +574,6 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
+ 	}
+ }
+ 
+-const int uuid_zero[4] = { 0, 0, 0, 0 };
+-
+-int same_uuid(int a[4], int b[4], int swapuuid)
+-{
+-	if (swapuuid) {
+-		/* parse uuids are hostendian.
+-		 * uuid's from some superblocks are big-ending
+-		 * if there is a difference, we need to swap..
+-		 */
+-		unsigned char *ac = (unsigned char *)a;
+-		unsigned char *bc = (unsigned char *)b;
+-		int i;
+-		for (i = 0; i < 16; i += 4) {
+-			if (ac[i+0] != bc[i+3] ||
+-			    ac[i+1] != bc[i+2] ||
+-			    ac[i+2] != bc[i+1] ||
+-			    ac[i+3] != bc[i+0])
+-				return 0;
+-		}
+-		return 1;
+-	} else {
+-		if (a[0]==b[0] &&
+-		    a[1]==b[1] &&
+-		    a[2]==b[2] &&
+-		    a[3]==b[3])
+-			return 1;
+-		return 0;
+-	}
+-}
+-
+-void copy_uuid(void *a, int b[4], int swapuuid)
+-{
+-	if (swapuuid) {
+-		/* parse uuids are hostendian.
+-		 * uuid's from some superblocks are big-ending
+-		 * if there is a difference, we need to swap..
+-		 */
+-		unsigned char *ac = (unsigned char *)a;
+-		unsigned char *bc = (unsigned char *)b;
+-		int i;
+-		for (i = 0; i < 16; i += 4) {
+-			ac[i+0] = bc[i+3];
+-			ac[i+1] = bc[i+2];
+-			ac[i+2] = bc[i+1];
+-			ac[i+3] = bc[i+0];
+-		}
+-	} else
+-		memcpy(a, b, 16);
+-}
+-
+ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep)
+ {
+ 	int i, j;
+diff --git a/uuid.c b/uuid.c
+new file mode 100644
+index 0000000..94b5abd
+--- /dev/null
++++ b/uuid.c
+@@ -0,0 +1,112 @@
++/*
++ * mdadm - manage Linux "md" devices aka RAID arrays.
++ *
++ * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
++ *
++ *
++ *    This program is free software; you can redistribute it and/or modify
++ *    it under the terms of the GNU General Public License as published by
++ *    the Free Software Foundation; either version 2 of the License, or
++ *    (at your option) any later version.
++ *
++ *    This program is distributed in the hope that it will be useful,
++ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *    GNU General Public License for more details.
++ *
++ *    You should have received a copy of the GNU General Public License
++ *    along with this program; if not, write to the Free Software
++ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ *    Author: Neil Brown
++ *    Email: <neilb@suse.de>
++ */
++
++#include	<string.h>
++
++const int uuid_zero[4] = { 0, 0, 0, 0 };
++
++int same_uuid(int a[4], int b[4], int swapuuid)
++{
++	if (swapuuid) {
++		/* parse uuids are hostendian.
++		 * uuid's from some superblocks are big-ending
++		 * if there is a difference, we need to swap..
++		 */
++		unsigned char *ac = (unsigned char *)a;
++		unsigned char *bc = (unsigned char *)b;
++		int i;
++		for (i = 0; i < 16; i += 4) {
++			if (ac[i+0] != bc[i+3] ||
++			    ac[i+1] != bc[i+2] ||
++			    ac[i+2] != bc[i+1] ||
++			    ac[i+3] != bc[i+0])
++				return 0;
++		}
++		return 1;
++	} else {
++		if (a[0]==b[0] &&
++		    a[1]==b[1] &&
++		    a[2]==b[2] &&
++		    a[3]==b[3])
++			return 1;
++		return 0;
++	}
++}
++
++void copy_uuid(void *a, int b[4], int swapuuid)
++{
++	if (swapuuid) {
++		/* parse uuids are hostendian.
++		 * uuid's from some superblocks are big-ending
++		 * if there is a difference, we need to swap..
++		 */
++		unsigned char *ac = (unsigned char *)a;
++		unsigned char *bc = (unsigned char *)b;
++		int i;
++		for (i = 0; i < 16; i += 4) {
++			ac[i+0] = bc[i+3];
++			ac[i+1] = bc[i+2];
++			ac[i+2] = bc[i+1];
++			ac[i+3] = bc[i+0];
++		}
++	} else
++		memcpy(a, b, 16);
++}
++
++/*
++ * Parse a 128 bit uuid in 4 integers
++ * format is 32 hexx nibbles with options :.<space> separator
++ * If not exactly 32 hex digits are found, return 0
++ * else return 1
++ */
++int parse_uuid(char *str, int uuid[4])
++{
++	int hit = 0; /* number of Hex digIT */
++	int i;
++	char c;
++	for (i = 0; i < 4; i++)
++		uuid[i] = 0;
++
++	while ((c = *str++) != 0) {
++		int n;
++		if (c >= '0' && c <= '9')
++			n = c-'0';
++		else if (c >= 'a' && c <= 'f')
++			n = 10 + c - 'a';
++		else if (c >= 'A' && c <= 'F')
++			n = 10 + c - 'A';
++		else if (strchr(":. -", c))
++			continue;
++		else return 0;
++
++		if (hit<32) {
++			uuid[hit/8] <<= 4;
++			uuid[hit/8] += n;
++		}
++		hit++;
++	}
++	if (hit == 32)
++		return 1;
++	return 0;
++}
+-- 
+2.7.5
+
diff --git a/SOURCES/0080-Include-count-for-0-character-when-using-strncpy-to-.patch b/SOURCES/0080-Include-count-for-0-character-when-using-strncpy-to-.patch
new file mode 100644
index 0000000..f53c559
--- /dev/null
+++ b/SOURCES/0080-Include-count-for-0-character-when-using-strncpy-to-.patch
@@ -0,0 +1,34 @@
+From 7d90f7603af6b59e7144cef6617a1e9dd42161bd Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Mon, 18 May 2020 20:19:53 -0400
+Subject: [PATCH 080/108] Include count for \0 character when using strncpy to
+ implement strdup.
+
+We have to include the \0 character in the length when copying a
+string with strncpy() for which length was found with strlen().
+Otherwise the destination will not get null terminated - except that
+we explicitly zeroed it out earlier.
+
+This quiets down the compiler's warnings.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ dlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dlink.c b/dlink.c
+index 3efa94b..69aa7aa 100644
+--- a/dlink.c
++++ b/dlink.c
+@@ -63,7 +63,7 @@ char *dl_strndup(char *s, int l)
+     if (s == NULL)
+ 	return NULL;
+     n = dl_newv(char, l+1);
+-    strncpy(n, s, l);
++    strncpy(n, s, l+1);
+     n[l] = 0;
+     return n;
+ }
+-- 
+2.7.5
+
diff --git a/SOURCES/0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch b/SOURCES/0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch
new file mode 100644
index 0000000..318239d
--- /dev/null
+++ b/SOURCES/0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch
@@ -0,0 +1,53 @@
+From d92cee7b374db9944b63bdd6c1784a2dd90ee9ca Mon Sep 17 00:00:00 2001
+From: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
+Date: Mon, 18 May 2020 23:53:36 +0200
+Subject: [PATCH 081/108] =?UTF-8?q?restripe:=20fix=20ignoring=20return=20v?=
+ =?UTF-8?q?alue=20of=20=E2=80=98read=E2=80=99=20and=20lseek?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Got below error when run "make everything".
+
+restripe.c: In function ‘test_stripes’:
+restripe.c:870:4: error: ignoring return value of ‘read’, declared with attribute warn_unused_result [-Werror=unused-result]
+    read(source[i], stripes[i], chunk_size);
+    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fix it by check the return value of ‘read’, and free memory
+in the failure case.
+
+And check the return value of lseek as well per Jes's comment.
+
+Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ restripe.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/restripe.c b/restripe.c
+index 31b07e8..86e1d00 100644
+--- a/restripe.c
++++ b/restripe.c
+@@ -866,8 +866,16 @@ int test_stripes(int *source, unsigned long long *offsets,
+ 		int disk;
+ 
+ 		for (i = 0 ; i < raid_disks ; i++) {
+-			lseek64(source[i], offsets[i]+start, 0);
+-			read(source[i], stripes[i], chunk_size);
++			if ((lseek64(source[i], offsets[i]+start, 0) < 0) ||
++			    (read(source[i], stripes[i], chunk_size) !=
++			     chunk_size)) {
++				free(q);
++				free(p);
++				free(blocks);
++				free(stripes);
++				free(stripe_buf);
++				return -1;
++			}
+ 		}
+ 		for (i = 0 ; i < data_disks ; i++) {
+ 			int disk = geo_map(i, start/chunk_size, raid_disks,
+-- 
+2.7.5
+
diff --git a/SOURCES/0082-Block-overwriting-existing-links-while-manual-assemb.patch b/SOURCES/0082-Block-overwriting-existing-links-while-manual-assemb.patch
new file mode 100644
index 0000000..ea7fc5e
--- /dev/null
+++ b/SOURCES/0082-Block-overwriting-existing-links-while-manual-assemb.patch
@@ -0,0 +1,33 @@
+From 7758ada9f3872cc9cb4c76c733dbc553562b3d7d Mon Sep 17 00:00:00 2001
+From: Kinga Tanska <kinga.tanska@intel.com>
+Date: Fri, 29 May 2020 08:31:36 +0200
+Subject: [PATCH 082/108] Block overwriting existing links while manual
+ assembly
+
+Manual assembly with existing link caused overwriting
+this link. Add checking link and block this situation.
+
+Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Assemble.c b/Assemble.c
+index 3e5d4e6..ed0ddfb 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1482,6 +1482,10 @@ try_again:
+ 				name = content->name;
+ 			break;
+ 		}
++		if (mddev && map_by_name(&map, mddev) != NULL) {
++			pr_err("Cannot create device with %s because is in use\n", mddev);
++			goto out;
++		}
+ 		if (!auto_assem)
+ 			/* If the array is listed in mdadm.conf or on
+ 			 * command line, then we trust the name
+-- 
+2.7.5
+
diff --git a/SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch b/SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch
new file mode 100644
index 0000000..d3d7bd8
--- /dev/null
+++ b/SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch
@@ -0,0 +1,76 @@
+From 2cf0433063203fca10d26629c9e090b51fb1d806 Mon Sep 17 00:00:00 2001
+From: David Favro <dfavro@meta-dynamic.com>
+Date: Sat, 23 May 2020 08:24:59 -0400
+Subject: [PATCH 083/108] Detect too-small device: error rather than
+ underflow/crash
+
+For 1.x metadata, when the user requested creation of an array on
+component devices that were too small even to hold the superblock,
+an undetected integer wraparound (underflow) resulted in an enormous
+computed size which resulted in various follow-on errors such as
+floating-point exception.
+
+This patch detects this condition, prints a reasonable diagnostic
+message, and refuses to continue.
+
+Signed-off-by: David Favro <dfavro@meta-dynamic.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index e0d80be..7664883 100644
+--- a/super1.c
++++ b/super1.c
+@@ -2753,6 +2753,7 @@ static int validate_geometry1(struct supertype *st, int level,
+ 	unsigned long long ldsize, devsize;
+ 	int bmspace;
+ 	unsigned long long headroom;
++	unsigned long long overhead;
+ 	int fd;
+ 
+ 	if (level == LEVEL_CONTAINER) {
+@@ -2785,10 +2786,6 @@ static int validate_geometry1(struct supertype *st, int level,
+ 	close(fd);
+ 
+ 	devsize = ldsize >> 9;
+-	if (devsize < 24) {
+-		*freesize = 0;
+-		return 0;
+-	}
+ 
+ 	/* creating:  allow suitable space for bitmap or PPL */
+ 	if (consistency_policy == CONSISTENCY_POLICY_PPL)
+@@ -2829,15 +2826,27 @@ static int validate_geometry1(struct supertype *st, int level,
+ 	case 0: /* metadata at end.  Round down and subtract space to reserve */
+ 		devsize = (devsize & ~(4ULL*2-1));
+ 		/* space for metadata, bblog, bitmap/ppl */
+-		devsize -= 8*2 + 8 + bmspace;
++		overhead = 8*2 + 8 + bmspace;
++		if (devsize < overhead) /* detect underflow */
++			goto dev_too_small_err;
++		devsize -= overhead;
+ 		break;
+ 	case 1:
+ 	case 2:
++		if (devsize < data_offset) /* detect underflow */
++			goto dev_too_small_err;
+ 		devsize -= data_offset;
+ 		break;
+ 	}
+ 	*freesize = devsize;
+ 	return 1;
++
++/* Error condition, device cannot even hold the overhead. */
++dev_too_small_err:
++	fprintf(stderr, "device %s is too small (%lluK) for "
++			"required metadata!\n", subdev, devsize>>1);
++	*freesize = 0;
++	return 0;
+ }
+ 
+ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0)
+-- 
+2.7.5
+
diff --git a/SOURCES/0084-Use-more-secure-HTTPS-URLs.patch b/SOURCES/0084-Use-more-secure-HTTPS-URLs.patch
new file mode 100644
index 0000000..6acb14c
--- /dev/null
+++ b/SOURCES/0084-Use-more-secure-HTTPS-URLs.patch
@@ -0,0 +1,123 @@
+From 8e41153c91cdce696618c527906648625217470c Mon Sep 17 00:00:00 2001
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+Date: Thu, 28 May 2020 16:52:24 +0200
+Subject: [PATCH 084/108] Use more secure HTTPS URLs
+
+All URLs in the source are available over HTTPS, so convert all URLs to
+HTTPS with the command below.
+
+    git grep -l 'http://' | xargs sed -i 's,http://,https://,g'
+
+Revert the changes to announcement files `ANNOUNCE-*` as requested by
+the maintainer.
+
+Cc: linux-raid@vger.kernel.org
+Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ external-reshape-design.txt      | 2 +-
+ mdadm.8.in                       | 6 +++---
+ mdadm.spec                       | 4 ++--
+ raid6check.8                     | 2 +-
+ restripe.c                       | 2 +-
+ udev-md-raid-safe-timeouts.rules | 2 +-
+ 6 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/external-reshape-design.txt b/external-reshape-design.txt
+index 10c57cc..e4cf4e1 100644
+--- a/external-reshape-design.txt
++++ b/external-reshape-design.txt
+@@ -277,4 +277,4 @@ sync_action
+ 
+ ...
+ 
+-[1]: Linux kernel design patterns - part 3, Neil Brown http://lwn.net/Articles/336262/
++[1]: Linux kernel design patterns - part 3, Neil Brown https://lwn.net/Articles/336262/
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 9e7cb96..7f32762 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -367,7 +367,7 @@ Use the Intel(R) Matrix Storage Manager metadata format.  This creates a
+ which is managed in a similar manner to DDF, and is supported by an
+ option-rom on some platforms:
+ .IP
+-.B http://www.intel.com/design/chipsets/matrixstorage_sb.htm
++.B https://www.intel.com/design/chipsets/matrixstorage_sb.htm
+ .PP
+ .RE
+ 
+@@ -3407,7 +3407,7 @@ was previously known as
+ For further information on mdadm usage, MD and the various levels of
+ RAID, see:
+ .IP
+-.B http://raid.wiki.kernel.org/
++.B https://raid.wiki.kernel.org/
+ .PP
+ (based upon Jakob \(/Ostergaard's Software\-RAID.HOWTO)
+ .PP
+@@ -3415,7 +3415,7 @@ The latest version of
+ .I mdadm
+ should always be available from
+ .IP
+-.B http://www.kernel.org/pub/linux/utils/raid/mdadm/
++.B https://www.kernel.org/pub/linux/utils/raid/mdadm/
+ .PP
+ Related man pages:
+ .PP
+diff --git a/mdadm.spec b/mdadm.spec
+index 1c66894..506ea33 100644
+--- a/mdadm.spec
++++ b/mdadm.spec
+@@ -2,8 +2,8 @@ Summary:     mdadm is used for controlling Linux md devices (aka RAID arrays)
+ Name:        mdadm
+ Version:     4.1
+ Release:     1
+-Source:      http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz
+-URL:         http://neil.brown.name/blog/mdadm
++Source:      https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz
++URL:         https://neil.brown.name/blog/mdadm
+ License:     GPL
+ Group:       Utilities/System
+ BuildRoot:   %{_tmppath}/%{name}-root
+diff --git a/raid6check.8 b/raid6check.8
+index 5003343..8999ca8 100644
+--- a/raid6check.8
++++ b/raid6check.8
+@@ -86,7 +86,7 @@ The latest version of
+ .I raid6check
+ should always be available from
+ .IP
+-.B http://www.kernel.org/pub/linux/utils/raid/mdadm/
++.B https://www.kernel.org/pub/linux/utils/raid/mdadm/
+ .PP
+ Related man pages:
+ .PP
+diff --git a/restripe.c b/restripe.c
+index 86e1d00..a7a7229 100644
+--- a/restripe.c
++++ b/restripe.c
+@@ -333,7 +333,7 @@ void make_tables(void)
+ 
+ 	/* Compute log and inverse log */
+ 	/* Modified code from:
+-	 *    http://web.eecs.utk.edu/~plank/plank/papers/CS-96-332.html
++	 *    https://web.eecs.utk.edu/~plank/plank/papers/CS-96-332.html
+ 	 */
+ 	b = 1;
+ 	raid6_gflog[0] = 0;
+diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules
+index 13c23d8..12bdcaa 100644
+--- a/udev-md-raid-safe-timeouts.rules
++++ b/udev-md-raid-safe-timeouts.rules
+@@ -13,7 +13,7 @@
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with mdraid-safe-timeouts.  If not, see
+-# <http://www.gnu.org/licenses/>.
++# <https://www.gnu.org/licenses/>.
+ 
+ # This file causes block devices with Linux RAID (mdadm) signatures to
+ # attempt to set safe timeouts for the drives involved
+-- 
+2.7.5
+
diff --git a/SOURCES/0085-Update-link-to-Intel-page-for-IMSM.patch b/SOURCES/0085-Update-link-to-Intel-page-for-IMSM.patch
new file mode 100644
index 0000000..9e9443f
--- /dev/null
+++ b/SOURCES/0085-Update-link-to-Intel-page-for-IMSM.patch
@@ -0,0 +1,28 @@
+From bcf40dbb5bf7db9d55a877b805ebb95c2008a132 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 12 Jun 2020 10:49:11 -0400
+Subject: [PATCH 085/108] Update link to Intel page for IMSM
+
+The old design page is gone, so update to the current overview page.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 7f32762..1474602 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -367,7 +367,7 @@ Use the Intel(R) Matrix Storage Manager metadata format.  This creates a
+ which is managed in a similar manner to DDF, and is supported by an
+ option-rom on some platforms:
+ .IP
+-.B https://www.intel.com/design/chipsets/matrixstorage_sb.htm
++.B https://www.intel.com/content/www/us/en/support/products/122484/memory-and-storage/ssd-software/intel-virtual-raid-on-cpu-intel-vroc.html
+ .PP
+ .RE
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch b/SOURCES/0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch
new file mode 100644
index 0000000..348682d
--- /dev/null
+++ b/SOURCES/0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch
@@ -0,0 +1,64 @@
+From 77b72fa828132a35c8b2e08d3fb07eea80b11895 Mon Sep 17 00:00:00 2001
+From: allenpeng <allenpeng@synology.com>
+Date: Fri, 12 Jun 2020 17:00:39 +0800
+Subject: [PATCH 086/108] mdadm/Grow: prevent md's fd from being occupied
+ during delayed time
+
+If we start reshaping on md which shares sub-devices with another
+resyncing md, it may be forced to wait for others to complete. mdadm
+occupies the md's fd during this time, which causes the md can not be
+stopped and the filesystem can not be mounted on the md. We can close
+md's fd earlier to solve this problem.
+
+Reproducible Steps:
+
+1. create two partitions on sda, sdb, sdc, sdd
+2. create raid1 with sda1, sdb1
+mdadm -C /dev/md1 --assume-clean -l1 -n2 /dev/sda1 /dev/sdb1
+3. create raid5 with sda2, sdb2, sdc2
+mdadm -C /dev/md2 --assume-clean -l5 -n3 /dev/sda2 /dev/sdb2 /dev/sdc2
+4. start resync at md1
+echo repair > /sys/block/md1/md/sync_action
+5. reshape raid5 to raid6
+mdadm -a /dev/md2 /dev/sdd2
+mdadm --grow /dev/md2 -n4 -l6 --backup-file=/root/md2-backup
+
+Now mdadm is occupying the fd of md2, causing md2 unable to be stopped
+
+6.Try to stop md2, an error message shows
+mdadm -S /dev/md2
+mdadm: Cannot get exclusive access to /dev/md3:Perhaps a running process,
+mounted filesystem or active volume group?
+
+Reviewed-by: Alex Wu <alexwu@synology.com>
+Reviewed-by: BingJing Chang <bingjingc@synology.com>
+Reviewed-by: Danny Shih <dannyshih@synology.com>
+Signed-off-by: ChangSyun Peng <allenpeng@synology.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Grow.c b/Grow.c
+index 764374f..57db7d4 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -3517,6 +3517,7 @@ started:
+ 			return 0;
+ 		}
+ 
++	close(fd);
+ 	/* Now we just need to kick off the reshape and watch, while
+ 	 * handling backups of the data...
+ 	 * This is all done by a forked background process.
+@@ -3569,7 +3570,6 @@ started:
+ 			mdstat_wait(30 - (delayed-1) * 25);
+ 	} while (delayed);
+ 	mdstat_close();
+-	close(fd);
+ 	if (check_env("MDADM_GROW_VERIFY"))
+ 		fd = open(devname, O_RDONLY | O_DIRECT);
+ 	else
+-- 
+2.7.5
+
diff --git a/SOURCES/0087-Specify-nodes-number-when-updating-cluster-nodes.patch b/SOURCES/0087-Specify-nodes-number-when-updating-cluster-nodes.patch
new file mode 100644
index 0000000..a0e5a37
--- /dev/null
+++ b/SOURCES/0087-Specify-nodes-number-when-updating-cluster-nodes.patch
@@ -0,0 +1,36 @@
+From 138a9e9bbe2622eafc90c976b82f3d84895dbebd Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Mon, 27 Jul 2020 09:14:20 +0800
+Subject: [PATCH 087/108] Specify nodes number when updating cluster nodes
+
+Now it allows updating cluster nodes without specify --nodes. It can write superblock
+with zero nodes. It can break the current cluster. Add this check to avoid this problem.
+
+v2: It needs check c.update first to avoid NULL pointer reference
+v3: Wol points the typo error
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/mdadm.c b/mdadm.c
+index 13dc24e..1b3467f 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1433,6 +1433,11 @@ int main(int argc, char *argv[])
+ 		}
+ 	}
+ 
++	if (c.update && strcmp(c.update, "nodes") == 0 && c.nodes == 0) {
++		pr_err("Please specify nodes number with --nodes\n");
++		exit(1);
++	}
++
+ 	if (c.backup_file && data_offset != INVALID_SECTORS) {
+ 		pr_err("--backup-file and --data-offset are incompatible\n");
+ 		exit(2);
+-- 
+2.7.5
+
diff --git a/SOURCES/0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch b/SOURCES/0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch
new file mode 100644
index 0000000..f037b90
--- /dev/null
+++ b/SOURCES/0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch
@@ -0,0 +1,32 @@
+From 5e592e1ed809b94670872b7a4629317fc1c8a5c1 Mon Sep 17 00:00:00 2001
+From: Winston Weinert <winston@ml1.net>
+Date: Wed, 22 Jul 2020 08:33:22 -0500
+Subject: [PATCH 088/108] mdadm/md.4: update path to in-kernel-tree
+ documentation
+
+Documentation/md.txt was renamed to Documentation/admin-guide/md.rst
+in linux commit 9d85025b0418163fae079c9ba8f8445212de8568 (Oct 26,
+2016).
+
+Signed-off-by: Winston Weinert <winston@ml1.net>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ md.4 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/md.4 b/md.4
+index 0712af2..aecff38 100644
+--- a/md.4
++++ b/md.4
+@@ -1061,7 +1061,7 @@ which contains various files for providing access to information about
+ the array.
+ 
+ This interface is documented more fully in the file
+-.B Documentation/md.txt
++.B Documentation/admin-guide/md.rst
+ which is distributed with the kernel sources.  That file should be
+ consulted for full documentation.  The following are just a selection
+ of attribute files that are available.
+-- 
+2.7.5
+
diff --git a/SOURCES/0089-manual-update-examine-badblocks.patch b/SOURCES/0089-manual-update-examine-badblocks.patch
new file mode 100644
index 0000000..2150671
--- /dev/null
+++ b/SOURCES/0089-manual-update-examine-badblocks.patch
@@ -0,0 +1,34 @@
+From 5f4184557a98bb641a7889e280265109c73e2f43 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Thu, 6 Aug 2020 13:57:50 +0200
+Subject: [PATCH 089/108] manual: update --examine-badblocks
+
+IMSM also supports it.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 1474602..ab832e8 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -1695,9 +1695,11 @@ does not report the bitmap for that array.
+ .TP
+ .B \-\-examine\-badblocks
+ List the bad-blocks recorded for the device, if a bad-blocks list has
+-been configured.  Currently only
++been configured. Currently only
+ .B 1.x
+-metadata supports bad-blocks lists.
++and
++.B IMSM
++metadata support bad-blocks lists.
+ 
+ .TP
+ .BI \-\-dump= directory
+-- 
+2.7.5
+
diff --git a/SOURCES/0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch b/SOURCES/0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch
new file mode 100644
index 0000000..2f771a3
--- /dev/null
+++ b/SOURCES/0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch
@@ -0,0 +1,68 @@
+From 64bf4dff34301a4b44883a8bc03f7835faef121e Mon Sep 17 00:00:00 2001
+From: Lidong Zhong <lidong.zhong@suse.com>
+Date: Mon, 14 Sep 2020 10:52:18 +0800
+Subject: [PATCH 090/108] Detail: show correct raid level when the array is
+ inactive
+
+Sometimes the raid level in the output of `mdadm -D /dev/mdX` is
+misleading when the array is in inactive state. Here is a testcase for
+introduction.
+1\ creating a raid1 device with two disks. Specify a different hostname
+rather than the real one for later verfication.
+
+node1:~ # mdadm --create /dev/md0 --homehost TESTARRAY -o -l 1 -n 2 /dev/sdb
+/dev/sdc
+2\ remove one of the devices and reboot
+3\ show the detail of raid1 device
+
+node1:~ # mdadm -D /dev/md127
+/dev/md127:
+        Version : 1.2
+     Raid Level : raid0
+  Total Devices : 1
+    Persistence : Superblock is persistent
+          State : inactive
+Working Devices : 1
+
+You can see that the "Raid Level" in /dev/md127 is raid0 now.
+After step 2\ is done, the degraded raid1 device is recognized
+as a "foreign" array in 64-md-raid-assembly.rules. And thus the
+timer to activate the raid1 device is not triggered. The array
+level returned from GET_ARRAY_INFO ioctl is 0. And the string
+shown for "Raid Level" is
+str = map_num(pers, array.level);
+And the definition of pers is
+mapping_t pers[] = {
+{ "linear", LEVEL_LINEAR},
+{ "raid0", 0},
+{ "0", 0}
+...
+So the misleading "raid0" is shown in this testcase.
+
+Changelog:
+v1: don't show "Raid Level" when array is inactive
+Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/Detail.c b/Detail.c
+index 24eeba0..b6587c8 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -224,7 +224,10 @@ int Detail(char *dev, struct context *c)
+ 	}
+ 
+ 	/* Ok, we have some info to print... */
+-	str = map_num(pers, array.level);
++	if (inactive)
++		str = map_num(pers, info->array.level);
++	else
++		str = map_num(pers, array.level);
+ 
+ 	if (c->export) {
+ 		if (array.raid_disks) {
+-- 
+2.7.5
+
diff --git a/SOURCES/0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch b/SOURCES/0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch
new file mode 100644
index 0000000..a1d7450
--- /dev/null
+++ b/SOURCES/0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch
@@ -0,0 +1,29 @@
+From 2ce091724031e18f522994ffd1e5eb0dc404bcba Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Tue, 15 Sep 2020 15:44:42 +0800
+Subject: [PATCH 091/108] Don't create bitmap for raid5 with journal disk
+
+Journal disk and bitmap can't exist at the same time. It needs to check if the raid
+has a journal disk when creating bitmap.
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Create.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Create.c b/Create.c
+index 6f84e5b..0efa19c 100644
+--- a/Create.c
++++ b/Create.c
+@@ -542,6 +542,7 @@ int Create(struct supertype *st, char *mddev,
+ 	if (!s->bitmap_file &&
+ 	    s->level >= 1 &&
+ 	    st->ss->add_internal_bitmap &&
++	    s->journaldisks == 0 &&
+ 	    (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
+ 	     s->consistency_policy != CONSISTENCY_POLICY_PPL) &&
+ 	    (s->write_behind || s->size > 100*1024*1024ULL)) {
+-- 
+2.7.5
+
diff --git a/SOURCES/0092-Monitor-refresh-mdstat-fd-after-select.patch b/SOURCES/0092-Monitor-refresh-mdstat-fd-after-select.patch
new file mode 100644
index 0000000..da94683
--- /dev/null
+++ b/SOURCES/0092-Monitor-refresh-mdstat-fd-after-select.patch
@@ -0,0 +1,70 @@
+From e2308733910a157b0a4d4e78721f239d44b91a24 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 9 Sep 2020 10:31:17 +0200
+Subject: [PATCH 092/108] Monitor: refresh mdstat fd after select
+
+After 52209d6ee118 ("Monitor: release /proc/mdstat fd when no arrays
+present") mdstat fd is closed if mdstat is empty or cannot be opened.
+It causes that monitor is not able to select on mdstat. Select
+doesn't fail because it gets valid descriptor to a different resource.
+As a result any new event will be unnoticed until timeout (delay).
+
+Refresh mdstat after wake up, don't poll on wrong resource.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 6 +++---
+ mdstat.c  | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 2d6b3b9..80a3200 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -216,8 +216,6 @@ int Monitor(struct mddev_dev *devlist,
+ 		if (mdstat)
+ 			free_mdstat(mdstat);
+ 		mdstat = mdstat_read(oneshot ? 0 : 1, 0);
+-		if (!mdstat)
+-			mdstat_close();
+ 
+ 		for (st = statelist; st; st = st->next)
+ 			if (check_array(st, mdstat, c->test, &info,
+@@ -238,8 +236,10 @@ int Monitor(struct mddev_dev *devlist,
+ 		if (!new_found) {
+ 			if (oneshot)
+ 				break;
+-			else
++			else {
+ 				mdstat_wait(c->delay);
++				mdstat_close();
++			}
+ 		}
+ 		c->test = 0;
+ 
+diff --git a/mdstat.c b/mdstat.c
+index 20577a3..48559e6 100644
+--- a/mdstat.c
++++ b/mdstat.c
+@@ -135,7 +135,6 @@ struct mdstat_ent *mdstat_read(int hold, int start)
+ 	if (hold && mdstat_fd != -1) {
+ 		off_t offset = lseek(mdstat_fd, 0L, 0);
+ 		if (offset == (off_t)-1) {
+-			mdstat_close();
+ 			return NULL;
+ 		}
+ 		fd = dup(mdstat_fd);
+@@ -312,7 +311,8 @@ void mdstat_wait(int seconds)
+ 	if (mdstat_fd >= 0) {
+ 		FD_SET(mdstat_fd, &fds);
+ 		maxfd = mdstat_fd;
+-	}
++	} else
++		return;
+ 	tm.tv_sec = seconds;
+ 	tm.tv_usec = 0;
+ 	select(maxfd + 1, NULL, NULL, &fds, &tm);
+-- 
+2.7.5
+
diff --git a/SOURCES/0093-Monitor-stop-notifing-about-containers.patch b/SOURCES/0093-Monitor-stop-notifing-about-containers.patch
new file mode 100644
index 0000000..7c968ce
--- /dev/null
+++ b/SOURCES/0093-Monitor-stop-notifing-about-containers.patch
@@ -0,0 +1,78 @@
+From 007087d0898a045901e4e120296e6d9b845b20a6 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 9 Sep 2020 10:31:18 +0200
+Subject: [PATCH 093/108] Monitor: stop notifing about containers.
+
+Stop reporting any events from container but still track them,
+it is important for spare migration.
+Stop mdmonitor if no redundant array is presented in mdstat.
+There is nothing to follow.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 80a3200..aed7a69 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -212,15 +212,24 @@ int Monitor(struct mddev_dev *devlist,
+ 		int new_found = 0;
+ 		struct state *st, **stp;
+ 		int anydegraded = 0;
++		int anyredundant = 0;
+ 
+ 		if (mdstat)
+ 			free_mdstat(mdstat);
+ 		mdstat = mdstat_read(oneshot ? 0 : 1, 0);
+ 
+-		for (st = statelist; st; st = st->next)
++		for (st = statelist; st; st = st->next) {
+ 			if (check_array(st, mdstat, c->test, &info,
+ 					increments, c->prefer))
+ 				anydegraded = 1;
++			/* for external arrays, metadata is filled for
++			 * containers only
++			 */
++			if (st->metadata && st->metadata->ss->external)
++				continue;
++			if (st->err == 0 && !anyredundant)
++				anyredundant = 1;
++		}
+ 
+ 		/* now check if there are any new devices found in mdstat */
+ 		if (c->scan)
+@@ -236,6 +245,9 @@ int Monitor(struct mddev_dev *devlist,
+ 		if (!new_found) {
+ 			if (oneshot)
+ 				break;
++			else if (!anyredundant) {
++				break;
++			}
+ 			else {
+ 				mdstat_wait(c->delay);
+ 				mdstat_close();
+@@ -542,7 +554,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		st->err = 0;
+ 		st->percent = RESYNC_NONE;
+ 		new_array = 1;
+-		alert("NewArray", st->devname, NULL, ainfo);
++		if (!is_container)
++			alert("NewArray", st->devname, NULL, ainfo);
+ 	}
+ 
+ 	if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
+@@ -676,7 +689,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	return retval;
+ 
+  disappeared:
+-	if (!st->err)
++	if (!st->err && !is_container)
+ 		alert("DeviceDisappeared", dev, NULL, ainfo);
+ 	st->err++;
+ 	goto out;
+-- 
+2.7.5
+
diff --git a/SOURCES/0094-mdmonitor-set-small-delay-once.patch b/SOURCES/0094-mdmonitor-set-small-delay-once.patch
new file mode 100644
index 0000000..2645654
--- /dev/null
+++ b/SOURCES/0094-mdmonitor-set-small-delay-once.patch
@@ -0,0 +1,103 @@
+From cab9c67d461c65a1138359f9f6d39636466b90e4 Mon Sep 17 00:00:00 2001
+From: Blazej Kucman <blazej.kucman@intel.com>
+Date: Wed, 9 Sep 2020 10:31:19 +0200
+Subject: [PATCH 094/108] mdmonitor: set small delay once
+
+If mdmonitor is awakened by event, set small delay once
+to deal with udev and mdadm.
+
+Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 14 +++++++++++++-
+ mdadm.h   |  2 +-
+ mdstat.c  | 18 +++++++++++++++---
+ 3 files changed, 29 insertions(+), 5 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index aed7a69..0fb4f77 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -128,6 +128,7 @@ int Monitor(struct mddev_dev *devlist,
+ 	char *mailfrom;
+ 	struct alert_info info;
+ 	struct mddev_ident *mdlist;
++	int delay_for_event = c->delay;
+ 
+ 	if (!mailaddr) {
+ 		mailaddr = conf_get_mailaddr();
+@@ -249,7 +250,18 @@ int Monitor(struct mddev_dev *devlist,
+ 				break;
+ 			}
+ 			else {
+-				mdstat_wait(c->delay);
++				int wait_result = mdstat_wait(delay_for_event);
++
++				/*
++				 * If mdmonitor is awaken by event, set small delay once
++				 * to deal with udev and mdadm.
++				 */
++				if (wait_result != 0) {
++					if (c->delay > 5)
++						delay_for_event = 5;
++				} else
++					delay_for_event = c->delay;
++
+ 				mdstat_close();
+ 			}
+ 		}
+diff --git a/mdadm.h b/mdadm.h
+index 399478b..4961c0f 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -628,7 +628,7 @@ struct mdstat_ent {
+ extern struct mdstat_ent *mdstat_read(int hold, int start);
+ extern void mdstat_close(void);
+ extern void free_mdstat(struct mdstat_ent *ms);
+-extern void mdstat_wait(int seconds);
++extern int mdstat_wait(int seconds);
+ extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
+ extern int mddev_busy(char *devnm);
+ extern struct mdstat_ent *mdstat_by_component(char *name);
+diff --git a/mdstat.c b/mdstat.c
+index 48559e6..dd96cca 100644
+--- a/mdstat.c
++++ b/mdstat.c
+@@ -302,7 +302,17 @@ void mdstat_close(void)
+ 	mdstat_fd = -1;
+ }
+ 
+-void mdstat_wait(int seconds)
++/*
++ * function: mdstat_wait
++ * Description: Function waits for event on mdstat.
++ * Parameters:
++ *		seconds - timeout for waiting
++ * Returns:
++ *		> 0 - detected event
++ *		0 - timeout
++ *		< 0 - detected error
++ */
++int mdstat_wait(int seconds)
+ {
+ 	fd_set fds;
+ 	struct timeval tm;
+@@ -312,10 +322,12 @@ void mdstat_wait(int seconds)
+ 		FD_SET(mdstat_fd, &fds);
+ 		maxfd = mdstat_fd;
+ 	} else
+-		return;
++		return -1;
++
+ 	tm.tv_sec = seconds;
+ 	tm.tv_usec = 0;
+-	select(maxfd + 1, NULL, NULL, &fds, &tm);
++
++	return select(maxfd + 1, NULL, NULL, &fds, &tm);
+ }
+ 
+ void mdstat_wait_fd(int fd, const sigset_t *sigmask)
+-- 
+2.7.5
+
diff --git a/SOURCES/0095-Check-if-other-Monitor-instance-running-before-fork.patch b/SOURCES/0095-Check-if-other-Monitor-instance-running-before-fork.patch
new file mode 100644
index 0000000..28b0637
--- /dev/null
+++ b/SOURCES/0095-Check-if-other-Monitor-instance-running-before-fork.patch
@@ -0,0 +1,103 @@
+From 7f3b2d1d1621cbdc60b5af4a41445391010fe9e1 Mon Sep 17 00:00:00 2001
+From: Blazej Kucman <blazej.kucman@intel.com>
+Date: Wed, 9 Sep 2020 10:31:20 +0200
+Subject: [PATCH 095/108] Check if other Monitor instance running before fork.
+
+Make error message visible to the user.
+
+Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 44 ++++++++++++++++++++++++++++----------------
+ 1 file changed, 28 insertions(+), 16 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 0fb4f77..7fd4808 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -63,6 +63,7 @@ struct alert_info {
+ };
+ static int make_daemon(char *pidfile);
+ static int check_one_sharer(int scan);
++static void write_autorebuild_pid(void);
+ static void alert(char *event, char *dev, char *disc, struct alert_info *info);
+ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		       int test, struct alert_info *info,
+@@ -153,6 +154,11 @@ int Monitor(struct mddev_dev *devlist,
+ 	info.mailfrom = mailfrom;
+ 	info.dosyslog = dosyslog;
+ 
++	if (share){
++		if (check_one_sharer(c->scan))
++			return 1;
++	}
++
+ 	if (daemonise) {
+ 		int rv = make_daemon(pidfile);
+ 		if (rv >= 0)
+@@ -160,8 +166,7 @@ int Monitor(struct mddev_dev *devlist,
+ 	}
+ 
+ 	if (share)
+-		if (check_one_sharer(c->scan))
+-			return 1;
++		write_autorebuild_pid();
+ 
+ 	if (devlist == NULL) {
+ 		mdlist = conf_get_ident(NULL);
+@@ -328,8 +333,8 @@ static int check_one_sharer(int scan)
+ 	int pid;
+ 	FILE *comm_fp;
+ 	FILE *fp;
+-	char comm_path[100];
+-	char path[100];
++	char comm_path[PATH_MAX];
++	char path[PATH_MAX];
+ 	char comm[20];
+ 
+ 	sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
+@@ -356,21 +361,28 @@ static int check_one_sharer(int scan)
+ 		}
+ 		fclose(fp);
+ 	}
+-	if (scan) {
+-		if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
++	return 0;
++}
++
++static void write_autorebuild_pid()
++{
++	char path[PATH_MAX];
++	int pid;
++	FILE *fp;
++	sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
++
++	if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
++		pr_err("Can't create autorebuild.pid file\n");
++	} else {
++		fp = fopen(path, "w");
++		if (!fp)
+ 			pr_err("Can't create autorebuild.pid file\n");
+-		} else {
+-			fp = fopen(path, "w");
+-			if (!fp)
+-				pr_err("Cannot create autorebuild.pidfile\n");
+-			else {
+-				pid = getpid();
+-				fprintf(fp, "%d\n", pid);
+-				fclose(fp);
+-			}
++		else {
++			pid = getpid();
++			fprintf(fp, "%d\n", pid);
++			fclose(fp);
+ 		}
+ 	}
+-	return 0;
+ }
+ 
+ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
+-- 
+2.7.5
+
diff --git a/SOURCES/0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch b/SOURCES/0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch
new file mode 100644
index 0000000..5512709
--- /dev/null
+++ b/SOURCES/0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch
@@ -0,0 +1,136 @@
+From 97b51a2c2d00b79a59f2a8e37134031b0c9e0223 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 14 Oct 2020 13:12:48 +1100
+Subject: [PATCH 096/108] Super1: allow RAID0 layout setting to be removed.
+
+Once the RAID0 layout has been set, the RAID0 array cannot be assembled
+on an older kernel which doesn't understand layouts.
+This is an intentional safety feature, but sometimes people need the
+ability to roll-back to a previously working configuration.
+
+So add "--update=layout-unspecified" to remove RAID0 layout information
+from the superblock.
+Running "--assemble --update=layout-unspecified" will cause the assembly
+the fail when run on a newer kernel, but will allow it to work on
+an older kernel.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ md.4       | 13 +++++++++++++
+ mdadm.8.in | 15 +++++++++++++--
+ mdadm.c    |  5 +++--
+ super1.c   |  6 +++++-
+ 4 files changed, 34 insertions(+), 5 deletions(-)
+
+diff --git a/md.4 b/md.4
+index aecff38..60fdd27 100644
+--- a/md.4
++++ b/md.4
+@@ -215,6 +215,19 @@ option or the
+ .B "--update=layout-alternate"
+ option.
+ 
++Once you have updated the layout you will not be able to mount the array
++on an older kernel.  If you need to revert to an older kernel, the
++layout information can be erased with the
++.B "--update=layout-unspecificed"
++option.  If you use this option to 
++.B --assemble
++while running a newer kernel, the array will NOT assemble, but the
++metadata will be update so that it can be assembled on an older kernel.
++
++No that setting the layout to "unspecified" removes protections against
++this bug, and you must be sure that the kernel you use matches the
++layout of the array.
++
+ .SS RAID1
+ 
+ A RAID1 array is also known as a mirrored set (though mirrors tend to
+diff --git a/mdadm.8.in b/mdadm.8.in
+index ab832e8..34a93a8 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -1213,6 +1213,7 @@ argument given to this flag can be one of
+ .BR no\-ppl ,
+ .BR layout\-original ,
+ .BR layout\-alternate ,
++.BR layout\-unspecified ,
+ .BR metadata ,
+ or
+ .BR super\-minor .
+@@ -1368,8 +1369,9 @@ The
+ .B layout\-original
+ and
+ .B layout\-alternate
+-options are for RAID0 arrays in use before Linux 5.4.  If the array was being
+-used with Linux 3.13 or earlier, then to assemble the array on a new kernel,
++options are for RAID0 arrays with non-uniform devices size that were in
++use before Linux 5.4.  If the array was being used with Linux 3.13 or
++earlier, then to assemble the array on a new kernel, 
+ .B \-\-update=layout\-original
+ must be given.  If the array was created and used with a kernel from Linux 3.14 to
+ Linux 5.3, then
+@@ -1379,6 +1381,15 @@ will happen normally.
+ For more information, see
+ .IR md (4).
+ 
++The
++.B layout\-unspecified
++option reverts the effect of
++.B layout\-orignal
++or
++.B layout\-alternate
++and allows the array to be again used on a kernel prior to Linux 5.3.
++This option should be used with great caution.
++
+ .TP
+ .BR \-\-freeze\-reshape
+ Option is intended to be used in start-up scripts during initrd boot phase.
+diff --git a/mdadm.c b/mdadm.c
+index 1b3467f..493d70e 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -796,7 +796,8 @@ int main(int argc, char *argv[])
+ 			if (strcmp(c.update, "revert-reshape") == 0)
+ 				continue;
+ 			if (strcmp(c.update, "layout-original") == 0 ||
+-			    strcmp(c.update, "layout-alternate") == 0)
++			    strcmp(c.update, "layout-alternate") == 0 ||
++			    strcmp(c.update, "layout-unspecified") == 0)
+ 				continue;
+ 			if (strcmp(c.update, "byteorder") == 0) {
+ 				if (ss) {
+@@ -828,7 +829,7 @@ int main(int argc, char *argv[])
+ 		"     'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
+ 		"     'no-bitmap', 'metadata', 'revert-reshape'\n"
+ 		"     'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n"
+-		"     'layout-original', 'layout-alternate'\n"
++		"     'layout-original', 'layout-alternate', 'layout-unspecified'\n"
+ 				);
+ 			exit(outf == stdout ? 0 : 2);
+ 
+diff --git a/super1.c b/super1.c
+index 7664883..8b0d6ff 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1551,11 +1551,15 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 	else if (strcmp(update, "nofailfast") == 0)
+ 		sb->devflags &= ~FailFast1;
+ 	else if (strcmp(update, "layout-original") == 0 ||
+-		 strcmp(update, "layout-alternate") == 0) {
++		 strcmp(update, "layout-alternate") == 0 ||
++		 strcmp(update, "layout-unspecified") == 0) {
+ 		if (__le32_to_cpu(sb->level) != 0) {
+ 			pr_err("%s: %s only supported for RAID0\n",
+ 			       devname?:"", update);
+ 			rv = -1;
++		} else if (strcmp(update, "layout-unspecified") == 0) {
++			sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
++			sb->layout = 0;
+ 		} else {
+ 			sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
+ 			sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2);
+-- 
+2.7.5
+
diff --git a/SOURCES/0097-Detail-fix-segfault-during-IMSM-raid-creation.patch b/SOURCES/0097-Detail-fix-segfault-during-IMSM-raid-creation.patch
new file mode 100644
index 0000000..f2c2e2b
--- /dev/null
+++ b/SOURCES/0097-Detail-fix-segfault-during-IMSM-raid-creation.patch
@@ -0,0 +1,33 @@
+From c3129b39a7d467eec063681529f46f84a2a85308 Mon Sep 17 00:00:00 2001
+From: Lidong Zhong <lidong.zhong@suse.com>
+Date: Sun, 22 Nov 2020 23:12:29 +0800
+Subject: [PATCH 097/108] Detail: fix segfault during IMSM raid creation
+
+It can be reproduced with non IMSM hardware and IMSM_NO_PLATFORM
+environmental variable set. The array state is inactive when creating
+an IMSM container. And the structure info is NULL because load_super()
+always fails since no intel HBA information could be obtained.
+
+Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
+Reported-by: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
+Fixes: 64bf4dff3430 (Detail: show correct raid level when the array is inactive)
+---
+ Detail.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Detail.c b/Detail.c
+index b6587c8..ea86884 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -224,7 +224,7 @@ int Detail(char *dev, struct context *c)
+ 	}
+ 
+ 	/* Ok, we have some info to print... */
+-	if (inactive)
++	if (inactive && info)
+ 		str = map_num(pers, info->array.level);
+ 	else
+ 		str = map_num(pers, array.level);
+-- 
+2.7.5
+
diff --git a/SOURCES/0098-Create.c-close-mdfd-and-generate-uevent.patch b/SOURCES/0098-Create.c-close-mdfd-and-generate-uevent.patch
new file mode 100644
index 0000000..7edc593
--- /dev/null
+++ b/SOURCES/0098-Create.c-close-mdfd-and-generate-uevent.patch
@@ -0,0 +1,37 @@
+From ce559078a5650afb9f635204b31a89a1fa0061e3 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+Date: Tue, 24 Nov 2020 13:39:49 +0100
+Subject: [PATCH 098/108] Create.c: close mdfd and generate uevent
+
+During mdfd closing change event is not generated because open() is
+called before start watching mddevice by udev.
+Device is ready at this stage. Unblock device, close fd and
+generate event to give a chance next layers to work.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+---
+ Create.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 0efa19c..51f8826 100644
+--- a/Create.c
++++ b/Create.c
+@@ -1083,12 +1083,9 @@ int Create(struct supertype *st, char *mddev,
+ 	} else {
+ 		pr_err("not starting array - not enough devices.\n");
+ 	}
+-	close(mdfd);
+-	/* Give udev a moment to process the Change event caused
+-	 * by the close.
+-	 */
+-	usleep(100*1000);
+ 	udev_unblock();
++	close(mdfd);
++	sysfs_uevent(&info, "change");
+ 	return 0;
+ 
+  abort:
+-- 
+2.7.5
+
diff --git a/SOURCES/0099-imsm-update-num_data_stripes-according-to-dev_size.patch b/SOURCES/0099-imsm-update-num_data_stripes-according-to-dev_size.patch
new file mode 100644
index 0000000..484208a
--- /dev/null
+++ b/SOURCES/0099-imsm-update-num_data_stripes-according-to-dev_size.patch
@@ -0,0 +1,166 @@
+From 895ffd992954069e4ea67efb8a85bb0fd72c3707 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+Date: Tue, 24 Nov 2020 14:15:15 +0100
+Subject: [PATCH 099/108] imsm: update num_data_stripes according to dev_size
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If array was created in UEFI there is possibility that
+member size is not rounded to 1MB. After any size reconfiguration
+it will be rounded down to 1MB per each member but the old
+component size will remain in metadata.
+During reshape old array size is calculated from component size because
+dev_size is not a part of map and is bumped to new value quickly.
+It may result in size mismatch if array is assembled during reshape.
+
+If difference in calculated size and dev_size is observed try to fix it.
+num_data_stripes value can be safety updated to smaller value if array
+doesn't occuppy whole reserved component space.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+---
+ super-intel.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 78 insertions(+), 6 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 3a73d2b..9562064 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -3453,7 +3453,6 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ 			__u64 blocks_per_unit = blocks_per_migr_unit(super,
+ 								     dev);
+ 			__u64 units = current_migr_unit(migr_rec);
+-			unsigned long long array_blocks;
+ 			int used_disks;
+ 
+ 			if (__le32_to_cpu(migr_rec->ascending_migr) &&
+@@ -3472,12 +3471,8 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ 
+ 			used_disks = imsm_num_data_members(prev_map);
+ 			if (used_disks > 0) {
+-				array_blocks = per_dev_array_size(map) *
++				info->custom_array_size = per_dev_array_size(map) *
+ 					used_disks;
+-				info->custom_array_size =
+-					round_size_to_mb(array_blocks,
+-							 used_disks);
+-
+ 			}
+ 		}
+ 		case MIGR_VERIFY:
+@@ -11682,6 +11677,68 @@ int imsm_takeover(struct supertype *st, struct geo_params *geo)
+ 	return 0;
+ }
+ 
++/* Flush size update if size calculated by num_data_stripes is higher than
++ * imsm_dev_size to eliminate differences during reshape.
++ * Mdmon will recalculate them correctly.
++ * If subarray index is not set then check whole container.
++ * Returns:
++ *	0 - no error occurred
++ *	1 - error detected
++ */
++static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
++{
++	struct intel_super *super = st->sb;
++	int tmp = super->current_vol;
++	int ret_val = 1;
++	int i;
++
++	for (i = 0; i < super->anchor->num_raid_devs; i++) {
++		if (subarray_index >= 0 && i != subarray_index)
++			continue;
++		super->current_vol = i;
++		struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
++		struct imsm_map *map = get_imsm_map(dev, MAP_0);
++		unsigned int disc_count = imsm_num_data_members(map);
++		struct geo_params geo;
++		struct imsm_update_size_change *update;
++		unsigned long long calc_size = per_dev_array_size(map) * disc_count;
++		unsigned long long d_size = imsm_dev_size(dev);
++		int u_size;
++
++		if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR)
++			continue;
++
++		/* There is a difference, verify that imsm_dev_size is
++		 * rounded correctly and push update.
++		 */
++		if (d_size != round_size_to_mb(d_size, disc_count)) {
++			dprintf("imsm: Size of volume %d is not rounded correctly\n",
++				 i);
++			goto exit;
++		}
++		memset(&geo, 0, sizeof(struct geo_params));
++		geo.size = d_size;
++		u_size = imsm_create_metadata_update_for_size_change(st, &geo,
++								     &update);
++		if (u_size < 1) {
++			dprintf("imsm: Cannot prepare size change update\n");
++			goto exit;
++		}
++		imsm_update_metadata_locally(st, update, u_size);
++		if (st->update_tail) {
++			append_metadata_update(st, update, u_size);
++			flush_metadata_updates(st);
++			st->update_tail = &st->updates;
++		} else {
++			imsm_sync_metadata(st);
++		}
++	}
++	ret_val = 0;
++exit:
++	super->current_vol = tmp;
++	return ret_val;
++}
++
+ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
+ 			      int level,
+ 			      int layout, int chunksize, int raid_disks,
+@@ -11718,6 +11775,11 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
+ 			struct imsm_update_reshape *u = NULL;
+ 			int len;
+ 
++			if (imsm_fix_size_mismatch(st, -1)) {
++				dprintf("imsm: Cannot fix size mismatch\n");
++				goto exit_imsm_reshape_super;
++			}
++
+ 			len = imsm_create_metadata_update_for_reshape(
+ 				st, &geo, old_raid_disks, &u);
+ 
+@@ -12020,6 +12082,7 @@ static int imsm_manage_reshape(
+ 	unsigned long long start_buf_shift; /* [bytes] */
+ 	int degraded = 0;
+ 	int source_layout = 0;
++	int subarray_index = -1;
+ 
+ 	if (!sra)
+ 		return ret_val;
+@@ -12033,6 +12096,7 @@ static int imsm_manage_reshape(
+ 		    dv->dev->vol.migr_state == 1) {
+ 			dev = dv->dev;
+ 			migr_vol_qan++;
++			subarray_index = dv->index;
+ 		}
+ 	}
+ 	/* Only one volume can migrate at the same time */
+@@ -12217,6 +12281,14 @@ static int imsm_manage_reshape(
+ 
+ 	/* return '1' if done */
+ 	ret_val = 1;
++
++	/* After the reshape eliminate size mismatch in metadata.
++	 * Don't update md/component_size here, volume hasn't
++	 * to take whole space. It is allowed by kernel.
++	 * md/component_size will be set propoperly after next assembly.
++	 */
++	imsm_fix_size_mismatch(st, subarray_index);
++
+ abort:
+ 	free(buf);
+ 	/* See Grow.c: abort_reshape() for further explanation */
+-- 
+2.7.5
+
diff --git a/SOURCES/0100-imsm-remove-redundant-calls-to-imsm_get_map.patch b/SOURCES/0100-imsm-remove-redundant-calls-to-imsm_get_map.patch
new file mode 100644
index 0000000..49f718d
--- /dev/null
+++ b/SOURCES/0100-imsm-remove-redundant-calls-to-imsm_get_map.patch
@@ -0,0 +1,35 @@
+From b65c1f4a2340e24ae00babc4399fb4030ff99517 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+Date: Tue, 24 Nov 2020 15:58:53 +0100
+Subject: [PATCH 100/108] imsm: remove redundant calls to imsm_get_map
+
+MAP_0 is gotten and the beginning, there is no need to get it again.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+---
+ super-intel.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 9562064..95f4eaf 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -8598,7 +8598,6 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 				break;
+ 			}
+ 			end_migration(dev, super, map_state);
+-			map = get_imsm_map(dev, MAP_0);
+ 			map->failed_disk_num = ~0;
+ 			super->updates_pending++;
+ 			a->last_checkpoint = 0;
+@@ -8610,7 +8609,6 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 				end_migration(dev, super, map_state);
+ 			else
+ 				map->map_state = map_state;
+-			map = get_imsm_map(dev, MAP_0);
+ 			map->failed_disk_num = ~0;
+ 			super->updates_pending++;
+ 			break;
+-- 
+2.7.5
+
diff --git a/SOURCES/0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch b/SOURCES/0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch
new file mode 100644
index 0000000..fac4298
--- /dev/null
+++ b/SOURCES/0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch
@@ -0,0 +1,55 @@
+From ca4b156b2059ee00a9143313267ee4a098967d76 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+Date: Tue, 24 Nov 2020 16:41:01 +0100
+Subject: [PATCH 101/108] Monitor: don't use default modes when creating a file
+
+Replace fopen() calls by open() with creation mode directly specified.
+This fixes the potential security issue. Use octal values instead masks.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+---
+ Monitor.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 7fd4808..a82e99d 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -305,8 +305,11 @@ static int make_daemon(char *pidfile)
+ 		if (!pidfile)
+ 			printf("%d\n", pid);
+ 		else {
+-			FILE *pid_file;
+-			pid_file=fopen(pidfile, "w");
++			FILE *pid_file = NULL;
++			int fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC,
++				      0644);
++			if (fd >= 0)
++				pid_file = fdopen(fd, "w");
+ 			if (!pid_file)
+ 				perror("cannot create pid file");
+ 			else {
+@@ -368,13 +371,17 @@ static void write_autorebuild_pid()
+ {
+ 	char path[PATH_MAX];
+ 	int pid;
+-	FILE *fp;
++	FILE *fp = NULL;
+ 	sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
+ 
+-	if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
++	if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) {
+ 		pr_err("Can't create autorebuild.pid file\n");
+ 	} else {
+-		fp = fopen(path, "w");
++		int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700);
++
++		if (fd >= 0)
++			fp = fdopen(fd, "w");
++
+ 		if (!fp)
+ 			pr_err("Can't create autorebuild.pid file\n");
+ 		else {
+-- 
+2.7.5
+
diff --git a/SOURCES/0102-imsm-limit-support-to-first-NVMe-namespace.patch b/SOURCES/0102-imsm-limit-support-to-first-NVMe-namespace.patch
new file mode 100644
index 0000000..849612b
--- /dev/null
+++ b/SOURCES/0102-imsm-limit-support-to-first-NVMe-namespace.patch
@@ -0,0 +1,95 @@
+From a8f3cfd54e45c8aabc4a99cdc92b6b9080b26607 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 4 Nov 2020 10:01:28 +0100
+Subject: [PATCH 102/108] imsm: limit support to first NVMe namespace
+
+Due to metadata limitations NVMe multinamespace support has to be removed.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+---
+ platform-intel.c | 31 +++++++++++++++++++++++++++++++
+ platform-intel.h |  1 +
+ super-intel.c    | 11 ++++++++++-
+ 3 files changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/platform-intel.c b/platform-intel.c
+index 04bffc5..f1f6d4c 100644
+--- a/platform-intel.c
++++ b/platform-intel.c
+@@ -766,3 +766,34 @@ char *vmd_domain_to_controller(struct sys_dev *hba, char *buf)
+ 	closedir(dir);
+ 	return NULL;
+ }
++/* Verify that NVMe drive is supported by IMSM
++ * Returns:
++ *	0 - not supported
++ *	1 - supported
++ */
++int imsm_is_nvme_supported(int disk_fd, int verbose)
++{
++	char nsid_path[PATH_MAX];
++	char buf[PATH_MAX];
++	struct stat stb;
++
++	if (disk_fd < 0)
++		return 0;
++
++	if (fstat(disk_fd, &stb))
++		return 0;
++
++	snprintf(nsid_path, PATH_MAX-1, "/sys/dev/block/%d:%d/nsid",
++		 major(stb.st_rdev), minor(stb.st_rdev));
++
++	if (load_sys(nsid_path, buf, sizeof(buf))) {
++		pr_err("Cannot read %s, rejecting drive\n", nsid_path);
++		return 0;
++	}
++	if (strtoll(buf, NULL, 10) != 1) {
++		if (verbose)
++			pr_err("Only first namespace is supported by IMSM, aborting\n");
++		return 0;
++	}
++	return 1;
++}
+diff --git a/platform-intel.h b/platform-intel.h
+index 7cb370e..7371478 100644
+--- a/platform-intel.h
++++ b/platform-intel.h
+@@ -251,4 +251,5 @@ const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id);
+ const struct imsm_orom *get_orom_by_device_id(__u16 device_id);
+ struct sys_dev *device_by_id(__u16 device_id);
+ struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path);
++int imsm_is_nvme_supported(int disk_fd, int verbose);
+ char *vmd_domain_to_controller(struct sys_dev *hba, char *buf);
+diff --git a/super-intel.c b/super-intel.c
+index 95f4eaf..715febf 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -2364,7 +2364,9 @@ static int print_nvme_info(struct sys_dev *hba)
+ 				continue;
+ 			if (path_attached_to_hba(rp, hba->path)) {
+ 				fd = open_dev(ent->d_name);
+-				if (fd < 0) {
++				if (!imsm_is_nvme_supported(fd, 0)) {
++					if (fd >= 0)
++						close(fd);
+ 					free(rp);
+ 					continue;
+ 				}
+@@ -5868,6 +5870,13 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
+ 		snprintf(controller_path, PATH_MAX-1, "%s/device", devpath);
+ 		free(devpath);
+ 
++		if (!imsm_is_nvme_supported(dd->fd, 1)) {
++			if (dd->devname)
++				free(dd->devname);
++			free(dd);
++			return 1;
++		}
++
+ 		if (devpath_to_vendor(controller_path) == 0x8086) {
+ 			/*
+ 			 * If Intel's NVMe drive has serial ended with
+-- 
+2.7.5
+
diff --git a/SOURCES/0103-mdadm-Unify-forks-behaviour.patch b/SOURCES/0103-mdadm-Unify-forks-behaviour.patch
new file mode 100644
index 0000000..1ff25e8
--- /dev/null
+++ b/SOURCES/0103-mdadm-Unify-forks-behaviour.patch
@@ -0,0 +1,354 @@
+From ff6bb131a46e1bac84a26e5b2c4bf408c0e56926 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 4 Nov 2020 10:02:36 +0100
+Subject: [PATCH 103/108] mdadm: Unify forks behaviour
+
+If mdadm is run by udev or systemd, it gets a pipe as each stream.
+Forks in the background may run after an event or service has been
+processed when udev is detached from pipe. As a result process
+fails quietly if any message is written.
+To prevent from it, each fork has to close all parent streams. Leave
+stderr and stdout opened only for debug purposes.
+Unify it across all forks. Introduce other descriptors detection by
+scanning /proc/self/fd directory. Add generic method for
+managing systemd services.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+---
+ Grow.c        |  52 ++++--------------------
+ Incremental.c |   1 +
+ Monitor.c     |   5 +--
+ mdadm.h       |  10 +++++
+ mdmon.c       |   9 +----
+ util.c        | 124 +++++++++++++++++++++++++++++++++++++---------------------
+ 6 files changed, 100 insertions(+), 101 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index 57db7d4..6b8321c 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -2982,47 +2982,6 @@ static void catch_term(int sig)
+ 	sigterm = 1;
+ }
+ 
+-static int continue_via_systemd(char *devnm)
+-{
+-	int skipped, i, pid, status;
+-	char pathbuf[1024];
+-	/* In a systemd/udev world, it is best to get systemd to
+-	 * run "mdadm --grow --continue" rather than running in the
+-	 * background.
+-	 */
+-	switch(fork()) {
+-	case  0:
+-		/* FIXME yuk. CLOSE_EXEC?? */
+-		skipped = 0;
+-		for (i = 3; skipped < 20; i++)
+-			if (close(i) < 0)
+-				skipped++;
+-			else
+-				skipped = 0;
+-
+-		/* Don't want to see error messages from
+-		 * systemctl.  If the service doesn't exist,
+-		 * we fork ourselves.
+-		 */
+-		close(2);
+-		open("/dev/null", O_WRONLY);
+-		snprintf(pathbuf, sizeof(pathbuf),
+-			 "mdadm-grow-continue@%s.service", devnm);
+-		status = execl("/usr/bin/systemctl", "systemctl", "restart",
+-			       pathbuf, NULL);
+-		status = execl("/bin/systemctl", "systemctl", "restart",
+-			       pathbuf, NULL);
+-		exit(1);
+-	case -1: /* Just do it ourselves. */
+-		break;
+-	default: /* parent - good */
+-		pid = wait(&status);
+-		if (pid >= 0 && status == 0)
+-			return 1;
+-	}
+-	return 0;
+-}
+-
+ static int reshape_array(char *container, int fd, char *devname,
+ 			 struct supertype *st, struct mdinfo *info,
+ 			 int force, struct mddev_dev *devlist,
+@@ -3401,6 +3360,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 		default: /* parent */
+ 			return 0;
+ 		case 0:
++			manage_fork_fds(0);
+ 			map_fork();
+ 			break;
+ 		}
+@@ -3509,8 +3469,9 @@ started:
+ 		return 1;
+ 	}
+ 
+-	if (!forked && !check_env("MDADM_NO_SYSTEMCTL"))
+-		if (continue_via_systemd(container ?: sra->sys_name)) {
++	if (!forked)
++		if (continue_via_systemd(container ?: sra->sys_name,
++					 GROW_SERVICE)) {
+ 			free(fdlist);
+ 			free(offsets);
+ 			sysfs_free(sra);
+@@ -3704,8 +3665,8 @@ int reshape_container(char *container, char *devname,
+ 	 */
+ 	ping_monitor(container);
+ 
+-	if (!forked && !freeze_reshape && !check_env("MDADM_NO_SYSTEMCTL"))
+-		if (continue_via_systemd(container))
++	if (!forked && !freeze_reshape)
++		if (continue_via_systemd(container, GROW_SERVICE))
+ 			return 0;
+ 
+ 	switch (forked ? 0 : fork()) {
+@@ -3718,6 +3679,7 @@ int reshape_container(char *container, char *devname,
+ 			printf("%s: multi-array reshape continues in background\n", Name);
+ 		return 0;
+ 	case 0: /* child */
++		manage_fork_fds(0);
+ 		map_fork();
+ 		break;
+ 	}
+diff --git a/Incremental.c b/Incremental.c
+index 98dbcd9..ad9ec1c 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -1679,6 +1679,7 @@ static void run_udisks(char *arg1, char *arg2)
+ 	int pid = fork();
+ 	int status;
+ 	if (pid == 0) {
++		manage_fork_fds(1);
+ 		execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL);
+ 		execl("/bin/udisks", "udisks", arg1, arg2, NULL);
+ 		exit(1);
+diff --git a/Monitor.c b/Monitor.c
+index a82e99d..3f3005b 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -323,10 +323,7 @@ static int make_daemon(char *pidfile)
+ 		perror("daemonise");
+ 		return 1;
+ 	}
+-	close(0);
+-	open("/dev/null", O_RDWR);
+-	dup2(0, 1);
+-	dup2(0, 2);
++	manage_fork_fds(0);
+ 	setsid();
+ 	return -1;
+ }
+diff --git a/mdadm.h b/mdadm.h
+index 4961c0f..56b1b19 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -129,6 +129,14 @@ struct dlm_lksb {
+ #define FAILED_SLOTS_DIR "/run/mdadm/failed-slots"
+ #endif /* FAILED_SLOTS */
+ 
++#ifndef MDMON_SERVICE
++#define MDMON_SERVICE "mdmon"
++#endif /* MDMON_SERVICE */
++
++#ifndef GROW_SERVICE
++#define GROW_SERVICE "mdadm-grow-continue"
++#endif /* GROW_SERVICE */
++
+ #include	"md_u.h"
+ #include	"md_p.h"
+ #include	"bitmap.h"
+@@ -1497,6 +1505,8 @@ extern int is_standard(char *dev, int *nump);
+ extern int same_dev(char *one, char *two);
+ extern int compare_paths (char* path1,char* path2);
+ extern void enable_fds(int devices);
++extern void manage_fork_fds(int close_all);
++extern int continue_via_systemd(char *devnm, char *service_name);
+ 
+ extern int parse_auto(char *str, char *msg, int config);
+ extern struct mddev_ident *conf_get_ident(char *dev);
+diff --git a/mdmon.c b/mdmon.c
+index ff985d2..c71e62c 100644
+--- a/mdmon.c
++++ b/mdmon.c
+@@ -546,14 +546,7 @@ static int mdmon(char *devnm, int must_fork, int takeover)
+ 	}
+ 
+ 	setsid();
+-	close(0);
+-	open("/dev/null", O_RDWR);
+-	close(1);
+-	ignore = dup(0);
+-#ifndef DEBUG
+-	close(2);
+-	ignore = dup(0);
+-#endif
++	manage_fork_fds(0);
+ 
+ 	/* This silliness is to stop the compiler complaining
+ 	 * that we ignore 'ignore'
+diff --git a/util.c b/util.c
+index 579dd42..5879694 100644
+--- a/util.c
++++ b/util.c
+@@ -1915,7 +1915,7 @@ int mdmon_running(char *devnm)
+ 
+ int start_mdmon(char *devnm)
+ {
+-	int i, skipped;
++	int i;
+ 	int len;
+ 	pid_t pid;
+ 	int status;
+@@ -1929,7 +1929,10 @@ int start_mdmon(char *devnm)
+ 
+ 	if (check_env("MDADM_NO_MDMON"))
+ 		return 0;
++	if (continue_via_systemd(devnm, MDMON_SERVICE))
++		return 0;
+ 
++	/* That failed, try running mdmon directly */
+ 	len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf)-1);
+ 	if (len > 0) {
+ 		char *sl;
+@@ -1943,51 +1946,9 @@ int start_mdmon(char *devnm)
+ 	} else
+ 		pathbuf[0] = '\0';
+ 
+-	/* First try to run systemctl */
+-	if (!check_env("MDADM_NO_SYSTEMCTL"))
+-		switch(fork()) {
+-		case 0:
+-			/* FIXME yuk. CLOSE_EXEC?? */
+-			skipped = 0;
+-			for (i = 3; skipped < 20; i++)
+-				if (close(i) < 0)
+-					skipped++;
+-				else
+-					skipped = 0;
+-
+-			/* Don't want to see error messages from
+-			 * systemctl.  If the service doesn't exist,
+-			 * we start mdmon ourselves.
+-			 */
+-			close(2);
+-			open("/dev/null", O_WRONLY);
+-			snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service",
+-				 devnm);
+-			status = execl("/usr/bin/systemctl", "systemctl",
+-				       "start",
+-				       pathbuf, NULL);
+-			status = execl("/bin/systemctl", "systemctl", "start",
+-				       pathbuf, NULL);
+-			exit(1);
+-		case -1: pr_err("cannot run mdmon. Array remains readonly\n");
+-			return -1;
+-		default: /* parent - good */
+-			pid = wait(&status);
+-			if (pid >= 0 && status == 0)
+-				return 0;
+-		}
+-
+-	/* That failed, try running mdmon directly */
+ 	switch(fork()) {
+ 	case 0:
+-		/* FIXME yuk. CLOSE_EXEC?? */
+-		skipped = 0;
+-		for (i = 3; skipped < 20; i++)
+-			if (close(i) < 0)
+-				skipped++;
+-			else
+-				skipped = 0;
+-
++		manage_fork_fds(1);
+ 		for (i = 0; paths[i]; i++)
+ 			if (paths[i][0]) {
+ 				execl(paths[i], paths[i],
+@@ -2192,6 +2153,81 @@ void enable_fds(int devices)
+ 	setrlimit(RLIMIT_NOFILE, &lim);
+ }
+ 
++/* Close all opened descriptors if needed and redirect
++ * streams to /dev/null.
++ * For debug purposed, leave STDOUT and STDERR untouched
++ * Returns:
++ *	1- if any error occurred
++ *	0- otherwise
++ */
++void manage_fork_fds(int close_all)
++{
++	DIR *dir;
++	struct dirent *dirent;
++
++	close(0);
++	open("/dev/null", O_RDWR);
++
++#ifndef DEBUG
++	dup2(0, 1);
++	dup2(0, 2);
++#endif
++
++	if (close_all == 0)
++		return;
++
++	dir = opendir("/proc/self/fd");
++	if (!dir) {
++		pr_err("Cannot open /proc/self/fd directory.\n");
++		return;
++	}
++	for (dirent = readdir(dir); dirent; dirent = readdir(dir)) {
++		int fd = -1;
++
++		if ((strcmp(dirent->d_name, ".") == 0) ||
++		    (strcmp(dirent->d_name, "..")) == 0)
++			continue;
++
++		fd = strtol(dirent->d_name, NULL, 10);
++		if (fd > 2)
++			close(fd);
++	}
++}
++
++/* In a systemd/udev world, it is best to get systemd to
++ * run daemon rather than running in the background.
++ * Returns:
++ *	1- if systemd service has been started
++ *	0- otherwise
++ */
++int continue_via_systemd(char *devnm, char *service_name)
++{
++	int pid, status;
++	char pathbuf[1024];
++
++	/* Simply return that service cannot be started */
++	if (check_env("MDADM_NO_SYSTEMCTL"))
++		return 0;
++	switch (fork()) {
++	case  0:
++		manage_fork_fds(1);
++		snprintf(pathbuf, sizeof(pathbuf),
++			 "%s@%s.service", service_name, devnm);
++		status = execl("/usr/bin/systemctl", "systemctl", "restart",
++			       pathbuf, NULL);
++		status = execl("/bin/systemctl", "systemctl", "restart",
++			       pathbuf, NULL);
++		exit(1);
++	case -1: /* Just do it ourselves. */
++		break;
++	default: /* parent - good */
++		pid = wait(&status);
++		if (pid >= 0 && status == 0)
++			return 1;
++	}
++	return 0;
++}
++
+ int in_initrd(void)
+ {
+ 	/* This is based on similar function in systemd. */
+-- 
+2.7.5
+
diff --git a/SOURCES/0104-mdadm-Detail-show-correct-state-for-clustered-array.patch b/SOURCES/0104-mdadm-Detail-show-correct-state-for-clustered-array.patch
new file mode 100644
index 0000000..0c30bd9
--- /dev/null
+++ b/SOURCES/0104-mdadm-Detail-show-correct-state-for-clustered-array.patch
@@ -0,0 +1,197 @@
+From 9c030dadba89b90a4e52b6afe0290076c809684c Mon Sep 17 00:00:00 2001
+From: Zhao Heming <heming.zhao@suse.com>
+Date: Sat, 24 Oct 2020 17:43:12 +0800
+Subject: [PATCH 104/108] mdadm/Detail: show correct state for clustered array
+
+After kernel md module commit 480523feae581, in clustered env,
+mddev->in_sync always zero, it will make array.state never set
+up MD_SB_CLEAN. it causes "mdadm -D /dev/mdX" show state 'active'
+all the time.
+
+bitmap.c: add a new API IsBitmapDirty() to support inquiry bitmap
+dirty or clean.
+
+Signed-off-by: Zhao Heming <heming.zhao@suse.com>
+---
+ Detail.c | 20 ++++++++++++++++-
+ bitmap.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
+ mdadm.h  |  1 +
+ 3 files changed, 86 insertions(+), 10 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index ea86884..f8dea6f 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -498,8 +498,26 @@ int Detail(char *dev, struct context *c)
+ 							  sra->array_state);
+ 				else
+ 					arrayst = "clean";
+-			} else
++			} else {
+ 				arrayst = "active";
++				if (array.state & (1<<MD_SB_CLUSTERED)) {
++					for (d = 0; d < max_disks * 2; d++) {
++						char *dv;
++						mdu_disk_info_t disk = disks[d];
++
++						/* only check first valid disk in cluster env */
++						if ((disk.state & (MD_DISK_SYNC | MD_DISK_ACTIVE))
++							&& (disk.major | disk.minor)) {
++							dv = map_dev_preferred(disk.major, disk.minor, 0,
++									c->prefer);
++							if (!dv)
++								continue;
++							arrayst = IsBitmapDirty(dv) ? "active" : "clean";
++							break;
++						}
++					}
++				}
++			}
+ 
+ 			printf("             State : %s%s%s%s%s%s%s \n",
+ 			       arrayst, st,
+diff --git a/bitmap.c b/bitmap.c
+index e38cb96..9a7ffe3 100644
+--- a/bitmap.c
++++ b/bitmap.c
+@@ -180,13 +180,14 @@ out:
+ }
+ 
+ static int
+-bitmap_file_open(char *filename, struct supertype **stp, int node_num)
++bitmap_file_open(char *filename, struct supertype **stp, int node_num, int fd)
+ {
+-	int fd;
+ 	struct stat stb;
+ 	struct supertype *st = *stp;
+ 
+-	fd = open(filename, O_RDONLY|O_DIRECT);
++	/* won't re-open filename when (fd >= 0) */
++	if (fd < 0)
++		fd = open(filename, O_RDONLY|O_DIRECT);
+ 	if (fd < 0) {
+ 		pr_err("failed to open bitmap file %s: %s\n",
+ 		       filename, strerror(errno));
+@@ -249,7 +250,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
+ 	int fd, i;
+ 	__u32 uuid32[4];
+ 
+-	fd = bitmap_file_open(filename, &st, 0);
++	fd = bitmap_file_open(filename, &st, 0, -1);
+ 	if (fd < 0)
+ 		return rv;
+ 
+@@ -263,7 +264,6 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
+ 		pr_err("Reporting bitmap that would be used if this array were used\n");
+ 		pr_err("as a member of some other array\n");
+ 	}
+-	close(fd);
+ 	printf("        Filename : %s\n", filename);
+ 	printf("           Magic : %08x\n", sb->magic);
+ 	if (sb->magic != BITMAP_MAGIC) {
+@@ -332,15 +332,13 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
+ 		for (i = 0; i < (int)sb->nodes; i++) {
+ 			st = NULL;
+ 			free(info);
+-			fd = bitmap_file_open(filename, &st, i);
++			fd = bitmap_file_open(filename, &st, i, fd);
+ 			if (fd < 0) {
+ 				printf("   Unable to open bitmap file on node: %i\n", i);
+-
+ 				continue;
+ 			}
+ 			info = bitmap_fd_read(fd, brief);
+ 			if (!info) {
+-				close(fd);
+ 				printf("   Unable to read bitmap on node: %i\n", i);
+ 				continue;
+ 			}
+@@ -359,13 +357,72 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
+ 			printf("          Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n",
+ 			       info->total_bits, info->dirty_bits,
+ 			       100.0 * info->dirty_bits / (info->total_bits?:1));
+-			 close(fd);
+ 		}
+ 	}
+ 
+ free_info:
++	close(fd);
++	free(info);
++	return rv;
++}
++
++int IsBitmapDirty(char *filename)
++{
++	/*
++	 * Read the bitmap file
++	 * It will break reading bitmap action immediately when meeting any error.
++	 *
++	 * Return: 1(dirty), 0 (clean), -1(error)
++	 */
++
++	int fd = -1, rv = 0, i;
++	struct supertype *st = NULL;
++	bitmap_info_t *info = NULL;
++	bitmap_super_t *sb = NULL;
++
++	fd = bitmap_file_open(filename, &st, 0, fd);
++	free(st);
++	if (fd < 0)
++		goto out;
++
++	info = bitmap_fd_read(fd, 0);
++	if (!info) {
++		close(fd);
++		goto out;
++	}
++
++	sb = &info->sb;
++	for (i = 0; i < (int)sb->nodes; i++) {
++		st = NULL;
++		free(info);
++		info = NULL;
++
++		fd = bitmap_file_open(filename, &st, i, fd);
++		free(st);
++		if (fd < 0)
++			goto out;
++
++		info = bitmap_fd_read(fd, 0);
++		if (!info) {
++			close(fd);
++			goto out;
++		}
++
++		sb = &info->sb;
++		if (sb->magic != BITMAP_MAGIC) { /* invalid bitmap magic */
++			free(info);
++			close(fd);
++			goto out;
++		}
++
++		if (info->dirty_bits)
++			rv = 1;
++	}
++	close(fd);
+ 	free(info);
+ 	return rv;
++out:
++	return -1;
+ }
+ 
+ int CreateBitmap(char *filename, int force, char uuid[16],
+diff --git a/mdadm.h b/mdadm.h
+index 56b1b19..1ee6c92 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1455,6 +1455,7 @@ extern int CreateBitmap(char *filename, int force, char uuid[16],
+ 			unsigned long long array_size,
+ 			int major);
+ extern int ExamineBitmap(char *filename, int brief, struct supertype *st);
++extern int IsBitmapDirty(char *filename);
+ extern int Write_rules(char *rule_name);
+ extern int bitmap_update_uuid(int fd, int *uuid, int swap);
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0105-Make-target-to-install-binaries-only.patch b/SOURCES/0105-Make-target-to-install-binaries-only.patch
new file mode 100644
index 0000000..efbafd0
--- /dev/null
+++ b/SOURCES/0105-Make-target-to-install-binaries-only.patch
@@ -0,0 +1,43 @@
+From b4a5ad4958cb3ad87c3c5fa993e7572c38596d09 Mon Sep 17 00:00:00 2001
+From: Kinga Tanska <kinga.tanska@intel.com>
+Date: Thu, 22 Oct 2020 14:22:29 +0200
+Subject: [PATCH 105/108] Make target to install binaries only
+
+Make install causes installation of binaries, udev and man.
+This commit contains new target make install-bin, which
+results in installation of binaries only.
+
+Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
+---
+ Makefile | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 15d05d1..4cd4c9d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -245,9 +245,7 @@ $(MON_OBJS) : $(INCL) mdmon.h
+ sha1.o : sha1.c sha1.h md5.h
+ 	$(CC) $(CFLAGS) -DHAVE_STDINT_H -o sha1.o -c sha1.c
+ 
+-install : mdadm mdmon install-man install-udev
+-	$(INSTALL) -D $(STRIP) -m 755 mdadm $(DESTDIR)$(BINDIR)/mdadm
+-	$(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon
++install : install-bin install-man install-udev
+ 
+ install-static : mdadm.static install-man
+ 	$(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm
+@@ -297,6 +295,10 @@ install-systemd: systemd/mdmon@.service
+ 	done
+ 	if [ -f /etc/SuSE-release -o -n "$(SUSE)" ] ;then $(INSTALL) -D -m 755 systemd/SUSE-mdadm_env.sh $(DESTDIR)$(LIB_DIR)/mdadm_env.sh ;fi
+ 
++install-bin: mdadm mdmon
++	$(INSTALL) -D $(STRIP) -m 755 mdadm $(DESTDIR)$(BINDIR)/mdadm
++	$(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon
++
+ uninstall:
+ 	rm -f $(DESTDIR)$(MAN8DIR)/mdadm.8 $(DESTDIR)$(MAN8DIR)/mdmon.8 $(DESTDIR)$(MAN4DIR)/md.4 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 $(DESTDIR)$(BINDIR)/mdadm
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0106-udev-start-grow-service-automatically.patch b/SOURCES/0106-udev-start-grow-service-automatically.patch
new file mode 100644
index 0000000..a899c39
--- /dev/null
+++ b/SOURCES/0106-udev-start-grow-service-automatically.patch
@@ -0,0 +1,37 @@
+From a64f1263a56bd8653267c1a9800daa0bc993a743 Mon Sep 17 00:00:00 2001
+From: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
+Date: Thu, 15 Oct 2020 10:45:29 +0200
+Subject: [PATCH 106/108] udev: start grow service automatically
+
+Grow continue via service or fork is started during raid assembly.
+If raid was assembled in initrd it will be newer restarted after
+switch root.
+Add udev support for starting mdadm-grow-continue service.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+---
+ udev-md-raid-arrays.rules | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
+index c8fa8e8..13c9076 100644
+--- a/udev-md-raid-arrays.rules
++++ b/udev-md-raid-arrays.rules
+@@ -15,6 +15,7 @@ ENV{DEVTYPE}=="partition", GOTO="md_ignore_state"
+ ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state"
+ TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end"
+ ATTR{md/array_state}=="clear*|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end"
++ATTR{md/sync_action}=="reshape", ENV{RESHAPE_ACTIVE}="yes"
+ LABEL="md_ignore_state"
+ 
+ IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode"
+@@ -38,5 +39,6 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
+ # Tell systemd to run mdmon for our container, if we need it.
+ ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
+ ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
++ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
+ 
+ LABEL="md_end"
+-- 
+2.7.5
+
diff --git a/SOURCES/0107-Incremental-Remove-redundant-spare-movement-logic.patch b/SOURCES/0107-Incremental-Remove-redundant-spare-movement-logic.patch
new file mode 100644
index 0000000..2a5092f
--- /dev/null
+++ b/SOURCES/0107-Incremental-Remove-redundant-spare-movement-logic.patch
@@ -0,0 +1,111 @@
+From 69068584f9ed68b8b2736287a1c9863e11b741d5 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+Date: Fri, 11 Dec 2020 12:28:38 +0100
+Subject: [PATCH 107/108] Incremental: Remove redundant spare movement logic
+
+If policy is set then mdmonitor is responsible for moving spares.
+This logic is reduntant and potentialy dangerus, spare could be moved at
+initrd stage depending on drives appearance order.
+
+Remove it.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 62 -----------------------------------------------------------
+ 1 file changed, 62 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index ad9ec1c..e849bdd 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -1460,12 +1460,6 @@ static int Incremental_container(struct supertype *st, char *devname,
+ 	int trustworthy;
+ 	struct mddev_ident *match;
+ 	int rv = 0;
+-	struct domainlist *domains;
+-	struct map_ent *smp;
+-	int suuid[4];
+-	int sfd;
+-	int ra_blocked = 0;
+-	int ra_all = 0;
+ 	int result = 0;
+ 
+ 	st->ss->getinfo_super(st, &info, NULL);
+@@ -1509,12 +1503,10 @@ static int Incremental_container(struct supertype *st, char *devname,
+ 		struct map_ent *mp;
+ 		struct mddev_ident *match = NULL;
+ 
+-		ra_all++;
+ 		/* do not activate arrays blocked by metadata handler */
+ 		if (ra->array.state & (1 << MD_SB_BLOCK_VOLUME)) {
+ 			pr_err("Cannot activate array %s in %s.\n",
+ 				ra->text_version, devname);
+-			ra_blocked++;
+ 			continue;
+ 		}
+ 		mp = map_by_uuid(&map, ra->uuid);
+@@ -1617,60 +1609,6 @@ static int Incremental_container(struct supertype *st, char *devname,
+ 		}
+ 		printf("\n");
+ 	}
+-
+-	/* don't move spares to container with volume being activated
+-	   when all volumes are blocked */
+-	if (ra_all == ra_blocked)
+-		return 0;
+-
+-	/* Now move all suitable spares from spare container */
+-	domains = domain_from_array(list, st->ss->name);
+-	memcpy(suuid, uuid_zero, sizeof(int[4]));
+-	if (domains &&
+-	    (smp = map_by_uuid(&map, suuid)) != NULL &&
+-	    (sfd = open(smp->path, O_RDONLY)) >= 0) {
+-		/* spare container found */
+-		struct supertype *sst =
+-			super_imsm.match_metadata_desc("imsm");
+-		struct mdinfo *sinfo;
+-
+-		if (!sst->ss->load_container(sst, sfd, NULL)) {
+-			struct spare_criteria sc = {0, 0};
+-
+-			if (st->ss->get_spare_criteria)
+-				st->ss->get_spare_criteria(st, &sc);
+-
+-			close(sfd);
+-			sinfo = container_choose_spares(sst, &sc,
+-							domains, NULL,
+-							st->ss->name, 0);
+-			sst->ss->free_super(sst);
+-			if (sinfo){
+-				int count = 0;
+-				struct mdinfo *disks = sinfo->devs;
+-				while (disks) {
+-					/* move spare from spare
+-					 * container to currently
+-					 * assembled one
+-					 */
+-					if (move_spare(
+-						    smp->path,
+-						    devname,
+-						    makedev(disks->disk.major,
+-							    disks->disk.minor)))
+-						count++;
+-					disks = disks->next;
+-				}
+-				if (count)
+-					pr_err("Added %d spare%s to %s\n",
+-					       count, count>1?"s":"", devname);
+-			}
+-			sysfs_free(sinfo);
+-		} else
+-			close(sfd);
+-	}
+-	domain_free(domains);
+-	map_free(map);
+ 	return 0;
+ }
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch b/SOURCES/0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch
new file mode 100644
index 0000000..d01c4f6
--- /dev/null
+++ b/SOURCES/0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch
@@ -0,0 +1,48 @@
+From 75562b57d43bd252399b55d0004b8eac4b337a67 Mon Sep 17 00:00:00 2001
+From: Lidong Zhong <lidong.zhong@suse.com>
+Date: Mon, 14 Dec 2020 22:51:33 +0800
+Subject: [PATCH 108/108] Dump: get stat from a wrong metadata file when
+ restoring metadata
+
+The dumped metadata files are shown as below
+localhost:~ # ll -ih test/
+total 16K
+34565564 -rw-r--r-- 2 root root 1.0G Dec 14 21:15
+scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-3
+34565563 -rw-r--r-- 2 root root 1.0G Dec 14 21:15
+scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-4
+34565563 -rw-r--r-- 2 root root 1.0G Dec 14 21:15 sda
+34565564 -rw-r--r-- 2 root root 1.0G Dec 14 21:15 sdb
+
+It reports such error when trying to restore metadata for /dev/sda
+localhost:~ # mdadm --restore=test /dev/sda
+mdadm: test/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-4 is not the same
+size as /dev/sda - cannot restore.
+It's because the stb value has been changed to other metadata file in
+the while statement.
+
+Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Dump.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/Dump.c b/Dump.c
+index 38e8f23..736bcb6 100644
+--- a/Dump.c
++++ b/Dump.c
+@@ -272,6 +272,11 @@ int Restore_metadata(char *dev, char *dir, struct context *c,
+ 		       fname);
+ 		goto err;
+ 	}
++	if (stat(fname, &stb) != 0) {
++		pr_err("Could not stat %s for --restore.\n",
++		       fname);
++		goto err;
++	}
+ 	if (((unsigned long long)stb.st_size) != size) {
+ 		pr_err("%s is not the same size as %s - cannot restore.\n",
+ 		       fname, dev);
+-- 
+2.7.5
+
diff --git a/SOURCES/mdadm-2.5.2-static.patch b/SOURCES/mdadm-2.5.2-static.patch
index 1eb335a..188b478 100644
--- a/SOURCES/mdadm-2.5.2-static.patch
+++ b/SOURCES/mdadm-2.5.2-static.patch
@@ -1,7 +1,7 @@
---- mdadm-3.2.1/Makefile.static	2011-03-27 22:31:20.000000000 -0400
-+++ mdadm-3.2.1/Makefile	2011-03-28 10:16:55.277900184 -0400
-@@ -238,16 +238,16 @@ install : mdadm mdmon install-man instal
- 	$(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon
+--- mdadm-3.2.1/Makefile.static	2021-01-11 15:46:47.292126848 +0800
++++ mdadm-3.2.1/Makefile	2021-01-11 15:46:10.720192519 +0800
+@@ -248,16 +248,16 @@
+ install : install-bin install-man install-udev
  
  install-static : mdadm.static install-man
 -	$(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm
diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec
index 19e6d8f..4b2bcd5 100644
--- a/SPECS/mdadm.spec
+++ b/SPECS/mdadm.spec
@@ -1,7 +1,7 @@
 Summary:     The mdadm program controls Linux md devices (software RAID arrays)
 Name:        mdadm
 Version:     4.1
-Release:     14%{?dist}
+Release:     15%{?dist}
 Source:      http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz
 Source1:     mdmonitor.init
 Source2:     raid-check
@@ -91,10 +91,41 @@ Patch74:     0074-Assemble-print-error-message-if-mdadm-fails-assembli.patch
 Patch75:     0075-clean-up-meaning-of-small-typo.patch
 Patch76:     0076-Assemble.c-respect-force-flag.patch
 Patch77:     0077-mdcheck-Log-when-done.patch
+Patch78:     0078-Makefile-add-EXTRAVERSION-support.patch
+Patch79:     0079-uuid.c-split-uuid-stuffs-from-util.c.patch
+Patch80:     0080-Include-count-for-0-character-when-using-strncpy-to-.patch
+Patch81:     0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch
+Patch82:     0082-Block-overwriting-existing-links-while-manual-assemb.patch
+Patch83:     0083-Detect-too-small-device-error-rather-than-underflow-.patch
+Patch84:     0084-Use-more-secure-HTTPS-URLs.patch
+Patch85:     0085-Update-link-to-Intel-page-for-IMSM.patch
+Patch86:     0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch
+Patch87:     0087-Specify-nodes-number-when-updating-cluster-nodes.patch
+Patch88:     0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch
+Patch89:     0089-manual-update-examine-badblocks.patch
+Patch90:     0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch
+Patch91:     0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch
+Patch92:     0092-Monitor-refresh-mdstat-fd-after-select.patch
+Patch93:     0093-Monitor-stop-notifing-about-containers.patch
+Patch94:     0094-mdmonitor-set-small-delay-once.patch
+Patch95:     0095-Check-if-other-Monitor-instance-running-before-fork.patch
+Patch96:     0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch
+Patch97:     0097-Detail-fix-segfault-during-IMSM-raid-creation.patch
+Patch98:     0098-Create.c-close-mdfd-and-generate-uevent.patch
+Patch99:     0099-imsm-update-num_data_stripes-according-to-dev_size.patch
+Patch100:    0100-imsm-remove-redundant-calls-to-imsm_get_map.patch
+Patch101:    0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch
+Patch102:    0102-imsm-limit-support-to-first-NVMe-namespace.patch
+Patch103:    0103-mdadm-Unify-forks-behaviour.patch
+Patch104:    0104-mdadm-Detail-show-correct-state-for-clustered-array.patch
+Patch105:    0105-Make-target-to-install-binaries-only.patch
+Patch106:    0106-udev-start-grow-service-automatically.patch
+Patch107:    0107-Incremental-Remove-redundant-spare-movement-logic.patch
+Patch108:    0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch
 
 # RHEL customization patches
-Patch97:     mdadm-3.3-udev.patch
-Patch98:     mdadm-2.5.2-static.patch
+Patch200:     mdadm-3.3-udev.patch
+Patch201:     mdadm-2.5.2-static.patch
 
 URL:         http://www.kernel.org/pub/linux/utils/raid/mdadm/
 License:     GPLv2+
@@ -198,10 +229,41 @@ file can be used to help with some common tasks.
 %patch75 -p1 -b .0075
 %patch76 -p1 -b .0076
 %patch77 -p1 -b .0077
+%patch78 -p1 -b .0078
+%patch79 -p1 -b .0079
+%patch80 -p1 -b .0080
+%patch81 -p1 -b .0081
+%patch82 -p1 -b .0082
+%patch83 -p1 -b .0083
+%patch84 -p1 -b .0084
+%patch85 -p1 -b .0085
+%patch86 -p1 -b .0086
+%patch87 -p1 -b .0087
+%patch88 -p1 -b .0088
+%patch89 -p1 -b .0089
+%patch90 -p1 -b .0090
+%patch91 -p1 -b .0091
+%patch92 -p1 -b .0092
+%patch93 -p1 -b .0093
+%patch94 -p1 -b .0094
+%patch95 -p1 -b .0095
+%patch96 -p1 -b .0096
+%patch97 -p1 -b .0097
+%patch98 -p1 -b .0098
+%patch99 -p1 -b .0099
+%patch100 -p1 -b .0100
+%patch101 -p1 -b .0101
+%patch102 -p1 -b .0102
+%patch103 -p1 -b .0103
+%patch104 -p1 -b .0104
+%patch105 -p1 -b .0105
+%patch106 -p1 -b .0106
+%patch107 -p1 -b .0107
+%patch108 -p1 -b .0108
 
 # RHEL customization patches
-%patch97 -p1 -b .udev
-%patch98 -p1 -b .static
+%patch200 -p1 -b .udev
+%patch201 -p1 -b .static
 
 %build
 make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon
@@ -269,6 +331,10 @@ rm -rf %{buildroot}
 /usr/lib/mdadm/mdadm_env.sh
 
 %changelog
+* Mon Jan 11 2021 Xiao Ni <xni@redhat.com> - 4.1.15
+- Update to latest upstream
+- Resolves rhbz#1838005
+
 * Fri Jun 05 2020 Xiao Ni <xni@redhat.com> - 4.1.14
 - Update to latest upstream
 - Resolves rhbz#1780501