diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..88c376b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/mdadm-4.1.tar.xz
diff --git a/.mdadm.metadata b/.mdadm.metadata
new file mode 100644
index 0000000..b2205ce
--- /dev/null
+++ b/.mdadm.metadata
@@ -0,0 +1 @@
+4bbbd02674ac67dc9773f41aace7677aa5374c1c SOURCES/mdadm-4.1.tar.xz
diff --git a/SOURCES/0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch b/SOURCES/0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch
new file mode 100644
index 0000000..17510de
--- /dev/null
+++ b/SOURCES/0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch
@@ -0,0 +1,39 @@
+From 0833f9c3dbaaee202b92ea956f9e2decc7b9593a Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@profitbricks.com>
+Date: Tue, 6 Nov 2018 15:27:42 +0100
+Subject: [RHEL7.7 PATCH 01/24] Assemble: keep MD_DISK_FAILFAST and
+ MD_DISK_WRITEMOSTLY flag
+
+Before updating superblock of slave disks, desired_state value
+is set for the target state of the slave disks. But it forgets
+to check MD_DISK_FAILFAST and MD_DISK_WRITEMOSTLY flags. Then
+start_arrays() calls ADD_NEW_DISK ioctl-call and pass the state
+without MD_DISK_FAILFAST and MD_DISK_WRITEMOSTLY.
+
+Currenlty it does not generate any problem because kernel does not
+care MD_DISK_FAILFAST or MD_DISK_WRITEMOSTLY flags.
+
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@profitbricks.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/Assemble.c b/Assemble.c
+index a79466c..f39c9e1 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1704,6 +1704,9 @@ try_again:
+ 		else
+ 			desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC);
+ 
++		desired_state |= devices[j].i.disk.state & ((1<<MD_DISK_FAILFAST) |
++							    (1<<MD_DISK_WRITEMOSTLY));
++
+ 		if (!devices[j].uptodate)
+ 			continue;
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0002-Document-PART-POLICY-lines.patch b/SOURCES/0002-Document-PART-POLICY-lines.patch
new file mode 100644
index 0000000..8968eb5
--- /dev/null
+++ b/SOURCES/0002-Document-PART-POLICY-lines.patch
@@ -0,0 +1,77 @@
+From 6b6112842030309c297a521918d1a2e982426fa3 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 9 Nov 2018 17:12:33 +1100
+Subject: [RHEL7.7 PATCH 02/24] Document PART-POLICY lines
+
+PART-POLICY has been accepted in mdadm.conf since the same
+time that POLICY was accepted, but it was never documented.
+So add the missing documentation.
+
+Also fix a bug which would have stopped it from working if
+anyone had ever tried to use it.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.conf.5 | 24 +++++++++++++++++++++++-
+ policy.c     |  2 +-
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.conf.5 b/mdadm.conf.5
+index 18512cb..47c962a 100644
+--- a/mdadm.conf.5
++++ b/mdadm.conf.5
+@@ -501,7 +501,7 @@ To update hot plug configuration it is necessary to execute
+ .B mdadm \-\-udev\-rules
+ command after changing the config file
+ 
+-Key words used in the
++Keywords used in the
+ .I POLICY
+ line and supported values are:
+ 
+@@ -565,6 +565,28 @@ be automatically added to that array (or it's container)
+ as above and the disk will become a spare in remaining cases
+ .RE
+ 
++.TP
++.B PART-POLICY
++This is similar to
++.B POLICY
++and accepts the same keyword assignments.  It allows a consistent set
++of policies to applied to each of the partitions of a device.
++
++A
++.B PART-POLICY
++line should set
++.I type=disk
++and identify the path to one or more disk devices.  Each partition on
++these disks will be treated according to the
++.I action=
++setting  from this line.  If a
++.I domain
++is set in the line, then the domain associated with each patition will
++be based on the domain, but with
++.RB \(dq -part N\(dq
++appended, when N is the partition number for the partition that was
++found.
++
+ .SH EXAMPLE
+ DEVICE /dev/sd[bcdjkl]1
+ .br
+diff --git a/policy.c b/policy.c
+index c0d18a7..258f393 100644
+--- a/policy.c
++++ b/policy.c
+@@ -300,7 +300,7 @@ static int path_has_part(char *path, char **part)
+ 		l--;
+ 	if (l < 5 || strncmp(path+l-5, "-part", 5) != 0)
+ 		return 0;
+-	*part = path+l-4;
++	*part = path+l-5;
+ 	return 1;
+ }
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0003-policy-support-devices-with-multiple-paths.patch b/SOURCES/0003-policy-support-devices-with-multiple-paths.patch
new file mode 100644
index 0000000..d4ffe1b
--- /dev/null
+++ b/SOURCES/0003-policy-support-devices-with-multiple-paths.patch
@@ -0,0 +1,334 @@
+From cd72f9d114da206baa01fd56ff2d8ffcc08f3239 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 9 Nov 2018 17:12:33 +1100
+Subject: [RHEL7.7 PATCH 03/24] policy: support devices with multiple paths.
+
+As new releases of Linux some time change the name of
+a path, some distros keep "legacy" names as well.  This
+is useful, but confuses mdadm which assumes each device has
+precisely one path.
+
+So change this assumption:  allow a disk to have several
+paths, and allow any to match when looking for a policy
+which matches a disk.
+
+Reported-and-tested-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c |   5 +-
+ mdadm.h       |   2 +-
+ policy.c      | 163 ++++++++++++++++++++++++++++++++--------------------------
+ 3 files changed, 95 insertions(+), 75 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index a4ff7d4..d4d3c35 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -1080,6 +1080,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 		struct supertype *st2 = NULL;
+ 		char *devname = NULL;
+ 		unsigned long long devsectors;
++		char *pathlist[2];
+ 
+ 		if (de->d_ino == 0 || de->d_name[0] == '.' ||
+ 		    (de->d_type != DT_LNK && de->d_type != DT_UNKNOWN))
+@@ -1094,7 +1095,9 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 			/* This is a partition - skip it */
+ 			goto next;
+ 
+-		pol2 = path_policy(de->d_name, type_disk);
++		pathlist[0] = de->d_name;
++		pathlist[1] = NULL;
++		pol2 = path_policy(pathlist, type_disk);
+ 
+ 		domain_merge(&domlist, pol2, st ? st->ss->name : NULL);
+ 		if (domain_test(domlist, pol, st ? st->ss->name : NULL) != 1)
+diff --git a/mdadm.h b/mdadm.h
+index 387e681..705bd9b 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1247,7 +1247,7 @@ extern void policyline(char *line, char *type);
+ extern void policy_add(char *type, ...);
+ extern void policy_free(void);
+ 
+-extern struct dev_policy *path_policy(char *path, char *type);
++extern struct dev_policy *path_policy(char **paths, char *type);
+ extern struct dev_policy *disk_policy(struct mdinfo *disk);
+ extern struct dev_policy *devid_policy(int devid);
+ extern void dev_policy_free(struct dev_policy *p);
+diff --git a/policy.c b/policy.c
+index 258f393..fa67d55 100644
+--- a/policy.c
++++ b/policy.c
+@@ -189,15 +189,17 @@ struct dev_policy *pol_find(struct dev_policy *pol, char *name)
+ 	return pol;
+ }
+ 
+-static char *disk_path(struct mdinfo *disk)
++static char **disk_paths(struct mdinfo *disk)
+ {
+ 	struct stat stb;
+ 	int prefix_len;
+ 	DIR *by_path;
+ 	char symlink[PATH_MAX] = "/dev/disk/by-path/";
+-	char nm[PATH_MAX];
++	char **paths;
++	int cnt = 0;
+ 	struct dirent *ent;
+-	int rv;
++
++	paths = xmalloc(sizeof(*paths) * (cnt+1));
+ 
+ 	by_path = opendir(symlink);
+ 	if (by_path) {
+@@ -214,22 +216,13 @@ static char *disk_path(struct mdinfo *disk)
+ 				continue;
+ 			if (stb.st_rdev != makedev(disk->disk.major, disk->disk.minor))
+ 				continue;
+-			closedir(by_path);
+-			return xstrdup(ent->d_name);
++			paths[cnt++] = xstrdup(ent->d_name);
++			paths = xrealloc(paths, sizeof(*paths) * (cnt+1));
+ 		}
+ 		closedir(by_path);
+ 	}
+-	/* A NULL path isn't really acceptable - use the devname.. */
+-	sprintf(symlink, "/sys/dev/block/%d:%d", disk->disk.major, disk->disk.minor);
+-	rv = readlink(symlink, nm, sizeof(nm)-1);
+-	if (rv > 0) {
+-		char *dname;
+-		nm[rv] = 0;
+-		dname = strrchr(nm, '/');
+-		if (dname)
+-			return xstrdup(dname + 1);
+-	}
+-	return xstrdup("unknown");
++	paths[cnt] = NULL;
++	return paths;
+ }
+ 
+ char type_part[] = "part";
+@@ -246,18 +239,53 @@ static char *disk_type(struct mdinfo *disk)
+ 		return type_disk;
+ }
+ 
+-static int pol_match(struct rule *rule, char *path, char *type)
++static int path_has_part(char *path, char **part)
++{
++	/* check if path ends with "-partNN" and
++	 * if it does, place a pointer to "-pathNN"
++	 * in 'part'.
++	 */
++	int l;
++	if (!path)
++		return 0;
++	l = strlen(path);
++	while (l > 1 && isdigit(path[l-1]))
++		l--;
++	if (l < 5 || strncmp(path+l-5, "-part", 5) != 0)
++		return 0;
++	*part = path+l-5;
++	return 1;
++}
++
++static int pol_match(struct rule *rule, char **paths, char *type, char **part)
+ {
+-	/* check if this rule matches on path and type */
++	/* Check if this rule matches on any path and type.
++	 * If 'part' is not NULL, then 'path' must end in -partN, which
++	 * we ignore for matching, and return in *part on success.
++	 */
+ 	int pathok = 0; /* 0 == no path, 1 == match, -1 == no match yet */
+ 	int typeok = 0;
+ 
+-	while (rule) {
++	for (; rule; rule = rule->next) {
+ 		if (rule->name == rule_path) {
++			char *p;
++			int i;
+ 			if (pathok == 0)
+ 				pathok = -1;
+-			if (path && fnmatch(rule->value, path, 0) == 0)
+-				pathok = 1;
++			if (!paths)
++				continue;
++			for (i = 0; paths[i]; i++) {
++				if (part) {
++					if (!path_has_part(paths[i], &p))
++						continue;
++					*p = '\0';
++					*part = p+1;
++				}
++				if (fnmatch(rule->value, paths[i], 0) == 0)
++					pathok = 1;
++				if (part)
++					*p = '-';
++			}
+ 		}
+ 		if (rule->name == rule_type) {
+ 			if (typeok == 0)
+@@ -265,7 +293,6 @@ static int pol_match(struct rule *rule, char *path, char *type)
+ 			if (type && strcmp(rule->value, type) == 0)
+ 				typeok = 1;
+ 		}
+-		rule = rule->next;
+ 	}
+ 	return pathok >= 0 && typeok >= 0;
+ }
+@@ -286,24 +313,6 @@ static void pol_merge(struct dev_policy **pol, struct rule *rule)
+ 			pol_new(pol, r->name, r->value, metadata);
+ }
+ 
+-static int path_has_part(char *path, char **part)
+-{
+-	/* check if path ends with "-partNN" and
+-	 * if it does, place a pointer to "-pathNN"
+-	 * in 'part'.
+-	 */
+-	int l;
+-	if (!path)
+-		return 0;
+-	l = strlen(path);
+-	while (l > 1 && isdigit(path[l-1]))
+-		l--;
+-	if (l < 5 || strncmp(path+l-5, "-part", 5) != 0)
+-		return 0;
+-	*part = path+l-5;
+-	return 1;
+-}
+-
+ static void pol_merge_part(struct dev_policy **pol, struct rule *rule, char *part)
+ {
+ 	/* copy any name assignments from rule into pol, appending
+@@ -352,7 +361,7 @@ static int config_rules_has_path = 0;
+  * path_policy() gathers policy information for the
+  * disk described in the given a 'path' and a 'type'.
+  */
+-struct dev_policy *path_policy(char *path, char *type)
++struct dev_policy *path_policy(char **paths, char *type)
+ {
+ 	struct pol_rule *rules;
+ 	struct dev_policy *pol = NULL;
+@@ -361,27 +370,24 @@ struct dev_policy *path_policy(char *path, char *type)
+ 	rules = config_rules;
+ 
+ 	while (rules) {
+-		char *part;
++		char *part = NULL;
+ 		if (rules->type == rule_policy)
+-			if (pol_match(rules->rule, path, type))
++			if (pol_match(rules->rule, paths, type, NULL))
+ 				pol_merge(&pol, rules->rule);
+ 		if (rules->type == rule_part && strcmp(type, type_part) == 0)
+-			if (path_has_part(path, &part)) {
+-				*part = 0;
+-				if (pol_match(rules->rule, path, type_disk))
+-					pol_merge_part(&pol, rules->rule, part+1);
+-				*part = '-';
+-			}
++			if (pol_match(rules->rule, paths, type_disk, &part))
++					pol_merge_part(&pol, rules->rule, part);
+ 		rules = rules->next;
+ 	}
+ 
+ 	/* Now add any metadata-specific internal knowledge
+ 	 * about this path
+ 	 */
+-	for (i=0; path && superlist[i]; i++)
++	for (i=0; paths[0] && superlist[i]; i++)
+ 		if (superlist[i]->get_disk_controller_domain) {
+ 			const char *d =
+-				superlist[i]->get_disk_controller_domain(path);
++				superlist[i]->get_disk_controller_domain(
++					paths[0]);
+ 			if (d)
+ 				pol_new(&pol, pol_domain, d, superlist[i]->name);
+ 		}
+@@ -400,22 +406,34 @@ void pol_add(struct dev_policy **pol,
+ 	pol_dedup(*pol);
+ }
+ 
++static void free_paths(char **paths)
++{
++	int i;
++
++	if (!paths)
++		return;
++
++	for (i = 0; paths[i]; i++)
++		free(paths[i]);
++	free(paths);
++}
++
+ /*
+  * disk_policy() gathers policy information for the
+  * disk described in the given mdinfo (disk.{major,minor}).
+  */
+ struct dev_policy *disk_policy(struct mdinfo *disk)
+ {
+-	char *path = NULL;
++	char **paths = NULL;
+ 	char *type = disk_type(disk);
+ 	struct dev_policy *pol = NULL;
+ 
+ 	if (config_rules_has_path)
+-		path = disk_path(disk);
++		paths = disk_paths(disk);
+ 
+-	pol = path_policy(path, type);
++	pol = path_policy(paths, type);
+ 
+-	free(path);
++	free_paths(paths);
+ 	return pol;
+ }
+ 
+@@ -756,27 +774,26 @@ int policy_check_path(struct mdinfo *disk, struct map_ent *array)
+ {
+ 	char path[PATH_MAX];
+ 	FILE *f = NULL;
+-	char *id_path = disk_path(disk);
+-	int rv;
++	char **id_paths = disk_paths(disk);
++	int i;
++	int rv = 0;
+ 
+-	if (!id_path)
+-		return 0;
++	for (i = 0; id_paths[i]; i++) {
++		snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_paths[i]);
++		f = fopen(path, "r");
++		if (!f)
++			continue;
+ 
+-	snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_path);
+-	f = fopen(path, "r");
+-	if (!f) {
+-		free(id_path);
+-		return 0;
++		rv = fscanf(f, " %s %x:%x:%x:%x\n",
++			    array->metadata,
++			    array->uuid,
++			    array->uuid+1,
++			    array->uuid+2,
++			    array->uuid+3);
++		fclose(f);
++		break;
+ 	}
+-
+-	rv = fscanf(f, " %s %x:%x:%x:%x\n",
+-		    array->metadata,
+-		    array->uuid,
+-		    array->uuid+1,
+-		    array->uuid+2,
+-		    array->uuid+3);
+-	fclose(f);
+-	free(id_path);
++	free_paths(id_paths);
+ 	return rv == 5;
+ }
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch b/SOURCES/0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch
new file mode 100644
index 0000000..97e1f6f
--- /dev/null
+++ b/SOURCES/0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch
@@ -0,0 +1,137 @@
+From 4199d3c629c14866505923d19fa50017ee92d2e1 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Wed, 5 Dec 2018 16:35:00 +1100
+Subject: [RHEL7.7 PATCH 04/24] mdcheck: add systemd unit files to run mdcheck.
+
+Having the mdcheck script is not use if is never run.
+This patch adds systemd unit files so that it can easily
+be run on the first Sunday of each month for 6 hours,
+then on every subsequent morning until the check is
+finished.
+
+The units still need to be enabled with
+  systemctl enable mdcheck_start.timer
+
+The timer will only actually be started when an array
+which might need it becomes active.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile                         |  5 ++++-
+ systemd/mdcheck_continue.service | 18 ++++++++++++++++++
+ systemd/mdcheck_continue.timer   | 13 +++++++++++++
+ systemd/mdcheck_start.service    | 17 +++++++++++++++++
+ systemd/mdcheck_start.timer      | 15 +++++++++++++++
+ 5 files changed, 67 insertions(+), 1 deletion(-)
+ create mode 100644 systemd/mdcheck_continue.service
+ create mode 100644 systemd/mdcheck_continue.timer
+ create mode 100644 systemd/mdcheck_start.service
+ create mode 100644 systemd/mdcheck_start.timer
+
+diff --git a/Makefile b/Makefile
+index 2767ac6..afb62cc 100644
+--- a/Makefile
++++ b/Makefile
+@@ -276,7 +276,10 @@ install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid
+ 
+ install-systemd: systemd/mdmon@.service
+ 	@for file in mdmon@.service mdmonitor.service mdadm-last-resort@.timer \
+-		mdadm-last-resort@.service mdadm-grow-continue@.service; \
++		mdadm-last-resort@.service mdadm-grow-continue@.service \
++		mdcheck_start.timer mdcheck_start.service \
++		mdcheck_continue.timer mdcheck_continue.service \
++		; \
+ 	do sed -e 's,BINDIR,$(BINDIR),g' systemd/$$file > .install.tmp.2 && \
+ 	   $(ECHO) $(INSTALL) -D -m 644 systemd/$$file $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
+ 	   $(INSTALL) -D -m 644 .install.tmp.2 $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
+diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
+new file mode 100644
+index 0000000..592c607
+--- /dev/null
++++ b/systemd/mdcheck_continue.service
+@@ -0,0 +1,18 @@
++#  This file is part of mdadm.
++#
++#  mdadm 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.
++
++[Unit]
++Description=MD array scrubbing - continuation
++ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_*
++
++[Service]
++Type=oneshot
++Environment= MDADM_CHECK_DURATION='"6 hours"'
++EnvironmentFile=-/run/sysconfig/mdadm
++ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
++ExecStart=/usr/share/mdadm/mdcheck --continue --duration $MDADM_CHECK_DURATION
++
+diff --git a/systemd/mdcheck_continue.timer b/systemd/mdcheck_continue.timer
+new file mode 100644
+index 0000000..3ccfd78
+--- /dev/null
++++ b/systemd/mdcheck_continue.timer
+@@ -0,0 +1,13 @@
++#  This file is part of mdadm.
++#
++#  mdadm 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.
++
++[Unit]
++Description=MD array scrubbing - continuation
++
++[Timer]
++OnCalendar= 1:05:00
++
+diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
+new file mode 100644
+index 0000000..812141b
+--- /dev/null
++++ b/systemd/mdcheck_start.service
+@@ -0,0 +1,17 @@
++#  This file is part of mdadm.
++#
++#  mdadm 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.
++
++[Unit]
++Description=MD array scrubbing
++Wants=mdcheck_continue.timer
++
++[Service]
++Type=oneshot
++Environment= MDADM_CHECK_DURATION='"6 hours"'
++EnvironmentFile=-/run/sysconfig/mdadm
++ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
++ExecStart=/usr/share/mdadm/mdcheck --duration $MDADM_CHECK_DURATION
+diff --git a/systemd/mdcheck_start.timer b/systemd/mdcheck_start.timer
+new file mode 100644
+index 0000000..6480736
+--- /dev/null
++++ b/systemd/mdcheck_start.timer
+@@ -0,0 +1,15 @@
++#  This file is part of mdadm.
++#
++#  mdadm 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.
++
++[Unit]
++Description=MD array scrubbing
++
++[Timer]
++OnCalendar=Sun *-*-1..7 1:00:00
++
++[Install]
++WantedBy= mdmonitor.service
+-- 
+2.7.5
+
diff --git a/SOURCES/0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch b/SOURCES/0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch
new file mode 100644
index 0000000..1cbf255
--- /dev/null
+++ b/SOURCES/0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch
@@ -0,0 +1,83 @@
+From 7cd7e91ab3de5aa75dc963cb08b0618c1885cf0d Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Wed, 5 Dec 2018 16:35:00 +1100
+Subject: [RHEL7.7 PATCH 05/24] Monitor: add system timer to run --oneshot
+ periodically
+
+"mdadm --monitor --oneshot" can be used to get a warning
+if there are any degraded arrays.  It can be helpful to get
+this warning periodically while the condition persists.
+
+This patch add a systemd service and timer which can
+be enabled with
+   systemctl enable mdmonitor-oneshot.service
+
+and will then provide daily warnings.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile                          |  1 +
+ systemd/mdmonitor-oneshot.service | 15 +++++++++++++++
+ systemd/mdmonitor-oneshot.timer   | 15 +++++++++++++++
+ 3 files changed, 31 insertions(+)
+ create mode 100644 systemd/mdmonitor-oneshot.service
+ create mode 100644 systemd/mdmonitor-oneshot.timer
+
+diff --git a/Makefile b/Makefile
+index afb62cc..dfe00b0 100644
+--- a/Makefile
++++ b/Makefile
+@@ -279,6 +279,7 @@ install-systemd: systemd/mdmon@.service
+ 		mdadm-last-resort@.service mdadm-grow-continue@.service \
+ 		mdcheck_start.timer mdcheck_start.service \
+ 		mdcheck_continue.timer mdcheck_continue.service \
++		mdmonitor-oneshot.timer mdmonitor-oneshot.service \
+ 		; \
+ 	do sed -e 's,BINDIR,$(BINDIR),g' systemd/$$file > .install.tmp.2 && \
+ 	   $(ECHO) $(INSTALL) -D -m 644 systemd/$$file $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \
+diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service
+new file mode 100644
+index 0000000..fd469b1
+--- /dev/null
++++ b/systemd/mdmonitor-oneshot.service
+@@ -0,0 +1,15 @@
++#  This file is part of mdadm.
++#
++#  mdadm 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.
++
++[Unit]
++Description=Reminder for degraded MD arrays
++
++[Service]
++Environment=  MDADM_MONITOR_ARGS=--scan
++EnvironmentFile=-/run/sysconfig/mdadm
++ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
++ExecStart=BINDIR/mdadm --monitor --oneshot $MDADM_MONITOR_ARGS
+diff --git a/systemd/mdmonitor-oneshot.timer b/systemd/mdmonitor-oneshot.timer
+new file mode 100644
+index 0000000..cb54bda
+--- /dev/null
++++ b/systemd/mdmonitor-oneshot.timer
+@@ -0,0 +1,15 @@
++#  This file is part of mdadm.
++#
++#  mdadm 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.
++
++[Unit]
++Description=Reminder for degraded MD arrays
++
++[Timer]
++OnCalendar= 2:00:00
++
++[Install]
++WantedBy= mdmonitor.service
+-- 
+2.7.5
+
diff --git a/SOURCES/0006-imsm-update-metadata-correctly-while-raid10-double-d.patch b/SOURCES/0006-imsm-update-metadata-correctly-while-raid10-double-d.patch
new file mode 100644
index 0000000..567a277
--- /dev/null
+++ b/SOURCES/0006-imsm-update-metadata-correctly-while-raid10-double-d.patch
@@ -0,0 +1,83 @@
+From d7a1fda2769ba272d89de6caeab35d52b73a9c3c Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 17 Oct 2018 12:11:41 +0200
+Subject: [RHEL7.7 PATCH 06/24] imsm: update metadata correctly while raid10
+ double degradation
+
+Mdmon calls end_migration() when map state changes from normal to
+degraded. It is not valid because in raid 10 double degradation case
+mdmon breaks checkpointing but array is still rebuilding.
+In this case mdmon has to mark map as degraded and continues marking
+recovery checkpoint in metadata. Migration can be finished only if newly
+failed device is a rebuilding device.
+
+Add catching double degraded to degraded transition. Migration is
+finished but map state doesn't change, array is still degraded.
+
+Update failed_disk_num correctly. If double degradation
+happens rebuild will start on the lowest slot, but this variable points
+to the first failed slot. If second fail happens while rebuild this
+variable shouldn't be updated until rebuild is not finished.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 6438987..d2035cc 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -8136,7 +8136,8 @@ static int mark_failure(struct intel_super *super,
+ 			set_imsm_ord_tbl_ent(map2, slot2,
+ 					     idx | IMSM_ORD_REBUILD);
+ 	}
+-	if (map->failed_disk_num == 0xff)
++	if (map->failed_disk_num == 0xff ||
++		(!is_rebuilding(dev) && map->failed_disk_num > slot))
+ 		map->failed_disk_num = slot;
+ 
+ 	clear_disk_badblocks(super->bbm_log, ord_to_idx(ord));
+@@ -8558,13 +8559,25 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 			break;
+ 		}
+ 		if (is_rebuilding(dev)) {
+-			dprintf_cont("while rebuilding.");
++			dprintf_cont("while rebuilding ");
+ 			if (map->map_state != map_state)  {
+-				dprintf_cont(" Map state change");
+-				end_migration(dev, super, map_state);
++				dprintf_cont("map state change ");
++				if (n == map->failed_disk_num) {
++					dprintf_cont("end migration");
++					end_migration(dev, super, map_state);
++				} else {
++					dprintf_cont("raid10 double degradation, map state change");
++					map->map_state = map_state;
++				}
+ 				super->updates_pending++;
+-			} else if (!rebuild_done) {
++			} else if (!rebuild_done)
+ 				break;
++			else if (n == map->failed_disk_num) {
++				/* r10 double degraded to degraded transition */
++				dprintf_cont("raid10 double degradation end migration");
++				end_migration(dev, super, map_state);
++				a->last_checkpoint = 0;
++				super->updates_pending++;
+ 			}
+ 
+ 			/* check if recovery is really finished */
+@@ -8575,7 +8588,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 				}
+ 			if (recovery_not_finished) {
+ 				dprintf_cont("\n");
+-				dprintf("Rebuild has not finished yet, state not changed");
++				dprintf_cont("Rebuild has not finished yet, map state changes only if raid10 double degradation happens");
+ 				if (a->last_checkpoint < mdi->recovery_start) {
+ 					a->last_checkpoint =
+ 						mdi->recovery_start;
+-- 
+2.7.5
+
diff --git a/SOURCES/0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch b/SOURCES/0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch
new file mode 100644
index 0000000..a9c41a5
--- /dev/null
+++ b/SOURCES/0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch
@@ -0,0 +1,43 @@
+From 563ac108659980b3d1e226fe416254a86656235f Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+Date: Tue, 6 Nov 2018 16:20:17 +0100
+Subject: [RHEL7.7 PATCH 07/24] Assemble: mask FAILFAST and WRITEMOSTLY flags
+ when finding the most recent device
+
+If devices[].i.disk.state has MD_DISK_FAILFAST or MD_DISK_WRITEMOSTLY
+flag, it cannot be the most recent device. Both flags should be masked
+before checking the state.
+
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index f39c9e1..9f75c68 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -578,6 +578,7 @@ static int load_devices(struct devs *devices, char *devmap,
+ 		struct supertype *tst;
+ 		int i;
+ 		int dfd;
++		int disk_state;
+ 
+ 		if (tmpdev->used != 1)
+ 			continue;
+@@ -711,7 +712,9 @@ static int load_devices(struct devs *devices, char *devmap,
+ 		devices[devcnt].i.disk.major = major(stb.st_rdev);
+ 		devices[devcnt].i.disk.minor = minor(stb.st_rdev);
+ 
+-		if (devices[devcnt].i.disk.state == 6) {
++		disk_state = devices[devcnt].i.disk.state & ~((1<<MD_DISK_FAILFAST) |
++							      (1<<MD_DISK_WRITEMOSTLY));
++		if (disk_state == ((1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC))) {
+ 			if (most_recent < 0 ||
+ 			    devices[devcnt].i.events
+ 			    > devices[most_recent].i.events) {
+-- 
+2.7.5
+
diff --git a/SOURCES/0008-Grow-avoid-overflow-in-compute_backup_blocks.patch b/SOURCES/0008-Grow-avoid-overflow-in-compute_backup_blocks.patch
new file mode 100644
index 0000000..5480125
--- /dev/null
+++ b/SOURCES/0008-Grow-avoid-overflow-in-compute_backup_blocks.patch
@@ -0,0 +1,34 @@
+From 085df42259cba7863cd6ebe5cd0d8492ac5b869e Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 6 Dec 2018 10:35:41 +1100
+Subject: [RHEL7.7 PATCH 08/24] Grow: avoid overflow in compute_backup_blocks()
+
+With a chunk size of 16Meg and data drive count of 8,
+this calculate can easily overflow the 'int' type that
+is used for the multiplications.
+So force it to use "long" instead.
+
+Reported-and-tested-by: Ed Spiridonov <edo.rus@gmail.com>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Grow.c b/Grow.c
+index 4436a4d..76f82c0 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -1196,7 +1196,8 @@ unsigned long compute_backup_blocks(int nchunk, int ochunk,
+ 	/* Find GCD */
+ 	a = GCD(a, b);
+ 	/* LCM == product / GCD */
+-	blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a;
++	blocks = (unsigned long)(ochunk/512) * (unsigned long)(nchunk/512) *
++		odata * ndata / a;
+ 
+ 	return blocks;
+ }
+-- 
+2.7.5
+
diff --git a/SOURCES/0009-Grow-report-correct-new-chunk-size.patch b/SOURCES/0009-Grow-report-correct-new-chunk-size.patch
new file mode 100644
index 0000000..3ae8fb9
--- /dev/null
+++ b/SOURCES/0009-Grow-report-correct-new-chunk-size.patch
@@ -0,0 +1,30 @@
+From 76d505dec6c9f92564553596fc8350324be82463 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 6 Dec 2018 10:36:28 +1100
+Subject: [RHEL7.7 PATCH 09/24] Grow: report correct new chunk size.
+
+When using "--grow --chunk=" to change chunk
+size, the old chunksize is reported instead of the new.
+
+Signed-off-by: NeilBrown <neilb@suse.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 76f82c0..363b209 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -3286,7 +3286,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 				goto release;
+ 			} else if (verbose >= 0)
+ 				printf("chunk size for %s set to %d\n",
+-				       devname, array.chunk_size);
++				       devname, info->new_chunk);
+ 		}
+ 		unfreeze(st);
+ 		return 0;
+-- 
+2.7.5
+
diff --git a/SOURCES/0010-policy.c-prevent-NULL-pointer-referencing.patch b/SOURCES/0010-policy.c-prevent-NULL-pointer-referencing.patch
new file mode 100644
index 0000000..73eb5db
--- /dev/null
+++ b/SOURCES/0010-policy.c-prevent-NULL-pointer-referencing.patch
@@ -0,0 +1,31 @@
+From 467e6a1b4ece8e552ee638dab7f44a4d235ece1a Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+Date: Fri, 7 Dec 2018 12:04:44 +0100
+Subject: [RHEL7.7 PATCH 10/24] policy.c: prevent NULL pointer referencing
+
+paths could be NULL and paths[0] should be followed by NULL pointer
+checking.
+
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ policy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/policy.c b/policy.c
+index fa67d55..e3a0671 100644
+--- a/policy.c
++++ b/policy.c
+@@ -383,7 +383,7 @@ struct dev_policy *path_policy(char **paths, char *type)
+ 	/* Now add any metadata-specific internal knowledge
+ 	 * about this path
+ 	 */
+-	for (i=0; paths[0] && superlist[i]; i++)
++	for (i=0; paths && paths[0] && superlist[i]; i++)
+ 		if (superlist[i]->get_disk_controller_domain) {
+ 			const char *d =
+ 				superlist[i]->get_disk_controller_domain(
+-- 
+2.7.5
+
diff --git a/SOURCES/0011-policy.c-Fix-for-compiler-error.patch b/SOURCES/0011-policy.c-Fix-for-compiler-error.patch
new file mode 100644
index 0000000..14a3c7b
--- /dev/null
+++ b/SOURCES/0011-policy.c-Fix-for-compiler-error.patch
@@ -0,0 +1,36 @@
+From 757e55435997e355ee9b03e5d913b5496a3c39a8 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Tue, 11 Dec 2018 15:04:07 +0100
+Subject: [RHEL7.7 PATCH 11/24] policy.c: Fix for compiler error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+After cd72f9d(policy: support devices with multiple paths.) compilation
+on old compilers fails because "‘p’ may be used uninitialized
+in this function".
+
+Initialize it with NULL to prevent this.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ policy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/policy.c b/policy.c
+index e3a0671..3c53bd3 100644
+--- a/policy.c
++++ b/policy.c
+@@ -268,7 +268,7 @@ static int pol_match(struct rule *rule, char **paths, char *type, char **part)
+ 
+ 	for (; rule; rule = rule->next) {
+ 		if (rule->name == rule_path) {
+-			char *p;
++			char *p = NULL;
+ 			int i;
+ 			if (pathok == 0)
+ 				pathok = -1;
+-- 
+2.7.5
+
diff --git a/SOURCES/0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch b/SOURCES/0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch
new file mode 100644
index 0000000..f146436
--- /dev/null
+++ b/SOURCES/0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch
@@ -0,0 +1,95 @@
+From a4e96fd8f3f0b5416783237c1cb6ee87e7eff23d Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Fri, 8 Feb 2019 11:07:10 +0100
+Subject: [RHEL7.7 PATCH 12/24] imsm: finish recovery when drive with rebuild
+ fails
+
+Commit d7a1fda2769b ("imsm: update metadata correctly while raid10 double
+degradation") resolves main Imsm double degradation problems but it
+omits one case. Now metadata hangs in the rebuilding state if the drive
+under rebuild is removed during recovery from double degradation.
+
+The root cause of this problem is comparing new map_state with current
+and if they both are degraded assuming that nothing new happens.
+
+Don't rely on map states, just check if device is failed. If the drive
+under rebuild fails then finish migration, in other cases update map
+state only (second fail means that destination map state can't be normal).
+
+To avoid problems with reassembling move end_migration (called after
+double degradation successful recovery) after check if recovery really
+finished, for details see (7ce057018 "imsm: fix: rebuild does not
+continue after reboot").
+Remove redundant code responsible for finishing rebuild process. Function
+end_migration do exactly the same. Set last_checkpoint to 0, to prepare
+it for the next rebuild.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 26 +++++++++++---------------
+ 1 file changed, 11 insertions(+), 15 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index d2035cc..38a1b6c 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -8560,26 +8560,22 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 		}
+ 		if (is_rebuilding(dev)) {
+ 			dprintf_cont("while rebuilding ");
+-			if (map->map_state != map_state)  {
+-				dprintf_cont("map state change ");
++			if (state & DS_FAULTY)  {
++				dprintf_cont("removing failed drive ");
+ 				if (n == map->failed_disk_num) {
+ 					dprintf_cont("end migration");
+ 					end_migration(dev, super, map_state);
++					a->last_checkpoint = 0;
+ 				} else {
+-					dprintf_cont("raid10 double degradation, map state change");
++					dprintf_cont("fail detected during rebuild, changing map state");
+ 					map->map_state = map_state;
+ 				}
+ 				super->updates_pending++;
+-			} else if (!rebuild_done)
+-				break;
+-			else if (n == map->failed_disk_num) {
+-				/* r10 double degraded to degraded transition */
+-				dprintf_cont("raid10 double degradation end migration");
+-				end_migration(dev, super, map_state);
+-				a->last_checkpoint = 0;
+-				super->updates_pending++;
+ 			}
+ 
++			if (!rebuild_done)
++				break;
++
+ 			/* check if recovery is really finished */
+ 			for (mdi = a->info.devs; mdi ; mdi = mdi->next)
+ 				if (mdi->recovery_start != MaxSector) {
+@@ -8588,7 +8584,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 				}
+ 			if (recovery_not_finished) {
+ 				dprintf_cont("\n");
+-				dprintf_cont("Rebuild has not finished yet, map state changes only if raid10 double degradation happens");
++				dprintf_cont("Rebuild has not finished yet");
+ 				if (a->last_checkpoint < mdi->recovery_start) {
+ 					a->last_checkpoint =
+ 						mdi->recovery_start;
+@@ -8598,9 +8594,9 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 			}
+ 
+ 			dprintf_cont(" Rebuild done, still degraded");
+-			dev->vol.migr_state = 0;
+-			set_migr_type(dev, 0);
+-			dev->vol.curr_migr_unit = 0;
++			end_migration(dev, super, map_state);
++			a->last_checkpoint = 0;
++			super->updates_pending++;
+ 
+ 			for (i = 0; i < map->num_members; i++) {
+ 				int idx = get_imsm_ord_tbl_ent(dev, i, MAP_0);
+-- 
+2.7.5
+
diff --git a/SOURCES/0013-imsm-fix-reshape-for-2TB-drives.patch b/SOURCES/0013-imsm-fix-reshape-for-2TB-drives.patch
new file mode 100644
index 0000000..19b4803
--- /dev/null
+++ b/SOURCES/0013-imsm-fix-reshape-for-2TB-drives.patch
@@ -0,0 +1,322 @@
+From 9f4218274cd4a1e1f356a1617f9a1d09960cf255 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Mon, 28 Jan 2019 17:10:41 +0100
+Subject: [RHEL7.7 PATCH 13/24] imsm: fix reshape for >2TB drives
+
+If reshape is performed on drives larger then 2 TB,
+migration checkpoint area that is calculated exeeds 32-bit value.
+This checkpoint area is a reserved space threated as backup
+during reshape - at the end of the drive, right before metadata.
+As a result - wrong space is used and the data that may exists there
+is overwritten.
+
+Adding additional field to migration record to track high order 32-bits
+of pba of this area. Three other fields that may exceed 32-bit value
+for large drives are added as well.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 149 +++++++++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 107 insertions(+), 42 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 38a1b6c..1cc7d5f 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -296,7 +296,7 @@ struct migr_record {
+ 	__u32 rec_status;	    /* Status used to determine how to restart
+ 				     * migration in case it aborts
+ 				     * in some fashion */
+-	__u32 curr_migr_unit;	    /* 0..numMigrUnits-1 */
++	__u32 curr_migr_unit_lo;    /* 0..numMigrUnits-1 */
+ 	__u32 family_num;	    /* Family number of MPB
+ 				     * containing the RaidDev
+ 				     * that is migrating */
+@@ -306,16 +306,23 @@ struct migr_record {
+ 	__u32 dest_depth_per_unit;  /* Num member blocks each destMap
+ 				     * member disk
+ 				     * advances per unit-of-operation */
+-	__u32 ckpt_area_pba;	    /* Pba of first block of ckpt copy area */
+-	__u32 dest_1st_member_lba;  /* First member lba on first
+-				     * stripe of destination */
+-	__u32 num_migr_units;	    /* Total num migration units-of-op */
++	__u32 ckpt_area_pba_lo;	    /* Pba of first block of ckpt copy area */
++	__u32 dest_1st_member_lba_lo;	/* First member lba on first
++					 * stripe of destination */
++	__u32 num_migr_units_lo;    /* Total num migration units-of-op */
+ 	__u32 post_migr_vol_cap;    /* Size of volume after
+ 				     * migration completes */
+ 	__u32 post_migr_vol_cap_hi; /* Expansion space for LBA64 */
+ 	__u32 ckpt_read_disk_num;   /* Which member disk in destSubMap[0] the
+ 				     * migration ckpt record was read from
+ 				     * (for recovered migrations) */
++	__u32 curr_migr_unit_hi;    /* 0..numMigrUnits-1 high order 32 bits */
++	__u32 ckpt_area_pba_hi;	    /* Pba of first block of ckpt copy area
++				     * high order 32 bits */
++	__u32 dest_1st_member_lba_hi; /* First member lba on first stripe of
++				       * destination - high order 32 bits */
++	__u32 num_migr_units_hi;      /* Total num migration units-of-op
++				       * high order 32 bits */
+ } __attribute__ ((__packed__));
+ 
+ struct md_list {
+@@ -1208,6 +1215,38 @@ static unsigned long long imsm_dev_size(struct imsm_dev *dev)
+ 	return join_u32(dev->size_low, dev->size_high);
+ }
+ 
++static unsigned long long migr_chkp_area_pba(struct migr_record *migr_rec)
++{
++	if (migr_rec == NULL)
++		return 0;
++	return join_u32(migr_rec->ckpt_area_pba_lo,
++			migr_rec->ckpt_area_pba_hi);
++}
++
++static unsigned long long current_migr_unit(struct migr_record *migr_rec)
++{
++	if (migr_rec == NULL)
++		return 0;
++	return join_u32(migr_rec->curr_migr_unit_lo,
++			migr_rec->curr_migr_unit_hi);
++}
++
++static unsigned long long migr_dest_1st_member_lba(struct migr_record *migr_rec)
++{
++	if (migr_rec == NULL)
++		return 0;
++	return join_u32(migr_rec->dest_1st_member_lba_lo,
++			migr_rec->dest_1st_member_lba_hi);
++}
++
++static unsigned long long get_num_migr_units(struct migr_record *migr_rec)
++{
++	if (migr_rec == NULL)
++		return 0;
++	return join_u32(migr_rec->num_migr_units_lo,
++			migr_rec->num_migr_units_hi);
++}
++
+ static void set_total_blocks(struct imsm_disk *disk, unsigned long long n)
+ {
+ 	split_ull(n, &disk->total_blocks_lo, &disk->total_blocks_hi);
+@@ -1233,6 +1272,33 @@ static void set_imsm_dev_size(struct imsm_dev *dev, unsigned long long n)
+ 	split_ull(n, &dev->size_low, &dev->size_high);
+ }
+ 
++static void set_migr_chkp_area_pba(struct migr_record *migr_rec,
++				   unsigned long long n)
++{
++	split_ull(n, &migr_rec->ckpt_area_pba_lo, &migr_rec->ckpt_area_pba_hi);
++}
++
++static void set_current_migr_unit(struct migr_record *migr_rec,
++				  unsigned long long n)
++{
++	split_ull(n, &migr_rec->curr_migr_unit_lo,
++		  &migr_rec->curr_migr_unit_hi);
++}
++
++static void set_migr_dest_1st_member_lba(struct migr_record *migr_rec,
++					 unsigned long long n)
++{
++	split_ull(n, &migr_rec->dest_1st_member_lba_lo,
++		  &migr_rec->dest_1st_member_lba_hi);
++}
++
++static void set_num_migr_units(struct migr_record *migr_rec,
++			       unsigned long long n)
++{
++	split_ull(n, &migr_rec->num_migr_units_lo,
++		  &migr_rec->num_migr_units_hi);
++}
++
+ static unsigned long long per_dev_array_size(struct imsm_map *map)
+ {
+ 	unsigned long long array_size = 0;
+@@ -1629,12 +1695,14 @@ void convert_to_4k_imsm_migr_rec(struct intel_super *super)
+ 	struct migr_record *migr_rec = super->migr_rec;
+ 
+ 	migr_rec->blocks_per_unit /= IMSM_4K_DIV;
+-	migr_rec->ckpt_area_pba /= IMSM_4K_DIV;
+-	migr_rec->dest_1st_member_lba /= IMSM_4K_DIV;
+ 	migr_rec->dest_depth_per_unit /= IMSM_4K_DIV;
+ 	split_ull((join_u32(migr_rec->post_migr_vol_cap,
+ 		 migr_rec->post_migr_vol_cap_hi) / IMSM_4K_DIV),
+ 		 &migr_rec->post_migr_vol_cap, &migr_rec->post_migr_vol_cap_hi);
++	set_migr_chkp_area_pba(migr_rec,
++		 migr_chkp_area_pba(migr_rec) / IMSM_4K_DIV);
++	set_migr_dest_1st_member_lba(migr_rec,
++		 migr_dest_1st_member_lba(migr_rec) / IMSM_4K_DIV);
+ }
+ 
+ void convert_to_4k_imsm_disk(struct imsm_disk *disk)
+@@ -1727,8 +1795,8 @@ void examine_migr_rec_imsm(struct intel_super *super)
+ 			printf("Normal\n");
+ 		else
+ 			printf("Contains Data\n");
+-		printf("               Current Unit : %u\n",
+-		       __le32_to_cpu(migr_rec->curr_migr_unit));
++		printf("               Current Unit : %llu\n",
++		       current_migr_unit(migr_rec));
+ 		printf("                     Family : %u\n",
+ 		       __le32_to_cpu(migr_rec->family_num));
+ 		printf("                  Ascending : %u\n",
+@@ -1737,16 +1805,15 @@ void examine_migr_rec_imsm(struct intel_super *super)
+ 		       __le32_to_cpu(migr_rec->blocks_per_unit));
+ 		printf("       Dest. Depth Per Unit : %u\n",
+ 		       __le32_to_cpu(migr_rec->dest_depth_per_unit));
+-		printf("        Checkpoint Area pba : %u\n",
+-		       __le32_to_cpu(migr_rec->ckpt_area_pba));
+-		printf("           First member lba : %u\n",
+-		       __le32_to_cpu(migr_rec->dest_1st_member_lba));
+-		printf("      Total Number of Units : %u\n",
+-		       __le32_to_cpu(migr_rec->num_migr_units));
+-		printf("             Size of volume : %u\n",
+-		       __le32_to_cpu(migr_rec->post_migr_vol_cap));
+-		printf("  Expansion space for LBA64 : %u\n",
+-		       __le32_to_cpu(migr_rec->post_migr_vol_cap_hi));
++		printf("        Checkpoint Area pba : %llu\n",
++		       migr_chkp_area_pba(migr_rec));
++		printf("           First member lba : %llu\n",
++		       migr_dest_1st_member_lba(migr_rec));
++		printf("      Total Number of Units : %llu\n",
++		       get_num_migr_units(migr_rec));
++		printf("             Size of volume : %llu\n",
++		       join_u32(migr_rec->post_migr_vol_cap,
++				migr_rec->post_migr_vol_cap_hi));
+ 		printf("       Record was read from : %u\n",
+ 		       __le32_to_cpu(migr_rec->ckpt_read_disk_num));
+ 
+@@ -1759,13 +1826,15 @@ void convert_from_4k_imsm_migr_rec(struct intel_super *super)
+ 	struct migr_record *migr_rec = super->migr_rec;
+ 
+ 	migr_rec->blocks_per_unit *= IMSM_4K_DIV;
+-	migr_rec->ckpt_area_pba *= IMSM_4K_DIV;
+-	migr_rec->dest_1st_member_lba *= IMSM_4K_DIV;
+ 	migr_rec->dest_depth_per_unit *= IMSM_4K_DIV;
+ 	split_ull((join_u32(migr_rec->post_migr_vol_cap,
+ 		 migr_rec->post_migr_vol_cap_hi) * IMSM_4K_DIV),
+ 		 &migr_rec->post_migr_vol_cap,
+ 		 &migr_rec->post_migr_vol_cap_hi);
++	set_migr_chkp_area_pba(migr_rec,
++		 migr_chkp_area_pba(migr_rec) * IMSM_4K_DIV);
++	set_migr_dest_1st_member_lba(migr_rec,
++		 migr_dest_1st_member_lba(migr_rec) * IMSM_4K_DIV);
+ }
+ 
+ void convert_from_4k(struct intel_super *super)
+@@ -3096,7 +3165,7 @@ static int imsm_create_metadata_checkpoint_update(
+ 		return 0;
+ 	}
+ 	(*u)->type = update_general_migration_checkpoint;
+-	(*u)->curr_migr_unit = __le32_to_cpu(super->migr_rec->curr_migr_unit);
++	(*u)->curr_migr_unit = current_migr_unit(super->migr_rec);
+ 	dprintf("prepared for %u\n", (*u)->curr_migr_unit);
+ 
+ 	return update_memory_size;
+@@ -3397,13 +3466,13 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ 		case MIGR_GEN_MIGR: {
+ 			__u64 blocks_per_unit = blocks_per_migr_unit(super,
+ 								     dev);
+-			__u64 units = __le32_to_cpu(migr_rec->curr_migr_unit);
++			__u64 units = current_migr_unit(migr_rec);
+ 			unsigned long long array_blocks;
+ 			int used_disks;
+ 
+ 			if (__le32_to_cpu(migr_rec->ascending_migr) &&
+ 			    (units <
+-				(__le32_to_cpu(migr_rec->num_migr_units)-1)) &&
++				(get_num_migr_units(migr_rec)-1)) &&
+ 			    (super->migr_rec->rec_status ==
+ 					__cpu_to_le32(UNIT_SRC_IN_CP_AREA)))
+ 				units++;
+@@ -10697,7 +10766,7 @@ void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev,
+ 
+ 	if (array_blocks % __le32_to_cpu(migr_rec->blocks_per_unit))
+ 		num_migr_units++;
+-	migr_rec->num_migr_units = __cpu_to_le32(num_migr_units);
++	set_num_migr_units(migr_rec, num_migr_units);
+ 
+ 	migr_rec->post_migr_vol_cap =  dev->size_low;
+ 	migr_rec->post_migr_vol_cap_hi = dev->size_high;
+@@ -10714,7 +10783,7 @@ void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev,
+ 			min_dev_sectors = dev_sectors;
+ 		close(fd);
+ 	}
+-	migr_rec->ckpt_area_pba = __cpu_to_le32(min_dev_sectors -
++	set_migr_chkp_area_pba(migr_rec, min_dev_sectors -
+ 					RAID_DISK_RESERVED_BLOCKS_IMSM_HI);
+ 
+ 	write_imsm_migr_rec(st);
+@@ -10765,8 +10834,7 @@ int save_backup_imsm(struct supertype *st,
+ 
+ 	start = info->reshape_progress * 512;
+ 	for (i = 0; i < new_disks; i++) {
+-		target_offsets[i] = (unsigned long long)
+-		  __le32_to_cpu(super->migr_rec->ckpt_area_pba) * 512;
++		target_offsets[i] = migr_chkp_area_pba(super->migr_rec) * 512;
+ 		/* move back copy area adderss, it will be moved forward
+ 		 * in restore_stripes() using start input variable
+ 		 */
+@@ -10845,12 +10913,11 @@ int save_checkpoint_imsm(struct supertype *st, struct mdinfo *info, int state)
+ 	if (info->reshape_progress % blocks_per_unit)
+ 		curr_migr_unit++;
+ 
+-	super->migr_rec->curr_migr_unit =
+-		__cpu_to_le32(curr_migr_unit);
++	set_current_migr_unit(super->migr_rec, curr_migr_unit);
+ 	super->migr_rec->rec_status = __cpu_to_le32(state);
+-	super->migr_rec->dest_1st_member_lba =
+-		__cpu_to_le32(curr_migr_unit *
+-			      __le32_to_cpu(super->migr_rec->dest_depth_per_unit));
++	set_migr_dest_1st_member_lba(super->migr_rec,
++			super->migr_rec->dest_depth_per_unit * curr_migr_unit);
++
+ 	if (write_imsm_migr_rec(st) < 0) {
+ 		dprintf("imsm: Cannot write migration record outside backup area\n");
+ 		return 1;
+@@ -10884,8 +10951,8 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info)
+ 	char *buf = NULL;
+ 	int retval = 1;
+ 	unsigned int sector_size = super->sector_size;
+-	unsigned long curr_migr_unit = __le32_to_cpu(migr_rec->curr_migr_unit);
+-	unsigned long num_migr_units = __le32_to_cpu(migr_rec->num_migr_units);
++	unsigned long curr_migr_unit = current_migr_unit(migr_rec);
++	unsigned long num_migr_units = get_num_migr_units(migr_rec);
+ 	char buffer[20];
+ 	int skipped_disks = 0;
+ 
+@@ -10912,11 +10979,9 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info)
+ 	map_dest = get_imsm_map(id->dev, MAP_0);
+ 	new_disks = map_dest->num_members;
+ 
+-	read_offset = (unsigned long long)
+-			__le32_to_cpu(migr_rec->ckpt_area_pba) * 512;
++	read_offset = migr_chkp_area_pba(migr_rec) * 512;
+ 
+-	write_offset = ((unsigned long long)
+-			__le32_to_cpu(migr_rec->dest_1st_member_lba) +
++	write_offset = (migr_dest_1st_member_lba(migr_rec) +
+ 			pba_of_lba0(map_dest)) * 512;
+ 
+ 	unit_len = __le32_to_cpu(migr_rec->dest_depth_per_unit) * 512;
+@@ -12019,12 +12084,12 @@ static int imsm_manage_reshape(
+ 	max_position = sra->component_size * ndata;
+ 	source_layout = imsm_level_to_layout(map_src->raid_level);
+ 
+-	while (__le32_to_cpu(migr_rec->curr_migr_unit) <
+-	       __le32_to_cpu(migr_rec->num_migr_units)) {
++	while (current_migr_unit(migr_rec) <
++	       get_num_migr_units(migr_rec)) {
+ 		/* current reshape position [blocks] */
+ 		unsigned long long current_position =
+ 			__le32_to_cpu(migr_rec->blocks_per_unit)
+-			* __le32_to_cpu(migr_rec->curr_migr_unit);
++			* current_migr_unit(migr_rec);
+ 		unsigned long long border;
+ 
+ 		/* Check that array hasn't become failed.
+-- 
+2.7.5
+
diff --git a/SOURCES/0014-Fix-spelling-typos.patch b/SOURCES/0014-Fix-spelling-typos.patch
new file mode 100644
index 0000000..838709c
--- /dev/null
+++ b/SOURCES/0014-Fix-spelling-typos.patch
@@ -0,0 +1,101 @@
+From ebf3be9931f31df54df52b1821479e6a80a4d9c6 Mon Sep 17 00:00:00 2001
+From: Dimitri John Ledkov <xnox@ubuntu.com>
+Date: Tue, 15 Jan 2019 19:08:37 +0000
+Subject: [RHEL7.7 PATCH 14/24] Fix spelling typos.
+
+Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c    | 2 +-
+ Create.c      | 2 +-
+ Grow.c        | 6 +++---
+ super-ddf.c   | 2 +-
+ super-intel.c | 2 +-
+ 5 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 9f75c68..9f050c1 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -879,7 +879,7 @@ static int force_array(struct mdinfo *content,
+ 		current_events = devices[chosen_drive].i.events;
+ 	add_another:
+ 		if (c->verbose >= 0)
+-			pr_err("forcing event count in %s(%d) from %d upto %d\n",
++			pr_err("forcing event count in %s(%d) from %d up to %d\n",
+ 			       devices[chosen_drive].devname,
+ 			       devices[chosen_drive].i.disk.raid_disk,
+ 			       (int)(devices[chosen_drive].i.events),
+diff --git a/Create.c b/Create.c
+index 04b1dfc..6f1b228 100644
+--- a/Create.c
++++ b/Create.c
+@@ -823,7 +823,7 @@ int Create(struct supertype *st, char *mddev,
+ 		}
+ 		bitmap_fd = open(s->bitmap_file, O_RDWR);
+ 		if (bitmap_fd < 0) {
+-			pr_err("weird: %s cannot be openned\n",
++			pr_err("weird: %s cannot be opened\n",
+ 				s->bitmap_file);
+ 			goto abort_locked;
+ 		}
+diff --git a/Grow.c b/Grow.c
+index 363b209..6d32661 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -446,7 +446,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 		if (offset_setable) {
+ 			st->ss->getinfo_super(st, mdi, NULL);
+ 			if (sysfs_init(mdi, fd, NULL)) {
+-				pr_err("failed to intialize sysfs.\n");
++				pr_err("failed to initialize sysfs.\n");
+ 				free(mdi);
+ 			}
+ 			rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
+@@ -2178,7 +2178,7 @@ size_change_error:
+ 	memset(&info, 0, sizeof(info));
+ 	info.array = array;
+ 	if (sysfs_init(&info, fd, NULL)) {
+-		pr_err("failed to intialize sysfs.\n");
++		pr_err("failed to initialize sysfs.\n");
+ 		rv = 1;
+ 		goto release;
+ 	}
+@@ -2903,7 +2903,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 	struct mdinfo info;
+ 
+ 	if (sysfs_init(&info, fd, NULL)) {
+-		pr_err("failed to intialize sysfs.\n");
++		pr_err("failed to initialize sysfs.\n");
+ 		return  1;
+ 	}
+ 
+diff --git a/super-ddf.c b/super-ddf.c
+index 618542c..c095e8a 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -1900,7 +1900,7 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst,
+ 		return conf;
+ 	}
+ bad:
+-	pr_err("Could't find disk %d in array %u\n", n, inst);
++	pr_err("Couldn't find disk %d in array %u\n", n, inst);
+ 	return NULL;
+ }
+ 
+diff --git a/super-intel.c b/super-intel.c
+index 1cc7d5f..c399433 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -10034,7 +10034,7 @@ static void imsm_process_update(struct supertype *st,
+ 		break;
+ 	}
+ 	default:
+-		pr_err("error: unsuported process update type:(type: %d)\n",	type);
++		pr_err("error: unsupported process update type:(type: %d)\n",	type);
+ 	}
+ }
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch b/SOURCES/0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch
new file mode 100644
index 0000000..2af2fa9
--- /dev/null
+++ b/SOURCES/0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch
@@ -0,0 +1,46 @@
+From e3615ecb5b6ad8eb408296878aad5628e0e27166 Mon Sep 17 00:00:00 2001
+From: Coly Li <colyli@suse.de>
+Date: Tue, 12 Feb 2019 12:53:18 +0800
+Subject: [RHEL7.7 PATCH 15/24] Detail.c: do not skip first character when
+ calling xstrdup in Detail()
+
+'Commit b9c9bd9bacaa ("Detail: ensure --export names are acceptable as
+shell variables")' duplicates mdi->sys_name to sysdev string by,
+	char *sysdev = xstrdup(mdi->sys_name + 1);
+which skips the first character of mdi->sys_name. Then when running
+mdadm --detail <md device> --export, the output looks like,
+	MD_DEVICE_ev_sda2_ROLE=1
+	MD_DEVICE_ev_sda2_DEV=/dev/sda2
+The first character of md device (between MD_DEVICE and _ROLE/_DEV)
+is dropped. The expected output should be,
+	MD_DEVICE_dev_sda2_ROLE=1
+	MD_DEVICE_dev_sda2_DEV=/dev/sda2
+
+This patch removes the '+ 1' from calling xstrdup() in Detail(), which
+gets the dropped first character back.
+
+Reported-by: Arvin Schnell <aschnell@suse.com>
+Fixes: b9c9bd9bacaa ("Detail: ensure --export names are acceptable as 4 shell variables")
+Signed-off-by: Coly Li <colyli@suse.de>
+Cc: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Detail.c b/Detail.c
+index b3e857a..20ea03a 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -284,7 +284,7 @@ int Detail(char *dev, struct context *c)
+ 			struct mdinfo *mdi;
+ 			for (mdi  = sra->devs; mdi; mdi = mdi->next) {
+ 				char *path;
+-				char *sysdev = xstrdup(mdi->sys_name + 1);
++				char *sysdev = xstrdup(mdi->sys_name);
+ 				char *cp;
+ 
+ 				path = map_dev(mdi->disk.major,
+-- 
+2.7.5
+
diff --git a/SOURCES/0016-Fix-reshape-for-decreasing-data-offset.patch b/SOURCES/0016-Fix-reshape-for-decreasing-data-offset.patch
new file mode 100644
index 0000000..72340f5
--- /dev/null
+++ b/SOURCES/0016-Fix-reshape-for-decreasing-data-offset.patch
@@ -0,0 +1,70 @@
+From cab114c5ca870e5f1b57fb2602cd9a038271c2e0 Mon Sep 17 00:00:00 2001
+From: Corey Hickey <bugfood-c@fatooh.org>
+Date: Mon, 11 Feb 2019 17:18:38 -0800
+Subject: [RHEL7.7 PATCH 16/24] Fix reshape for decreasing data offset
+
+...when not changing the number of disks.
+
+This patch needs context to explain. These are the relevant parts of
+the original code (condensed and annotated):
+
+if (dir > 0) {
+    /* Increase data offset (reshape backwards) */
+    if (data_offset < sd->data_offset + min) {
+        pr_err("--data-offset too small on %s\n",
+               dn);
+        goto release;
+    }
+} else {
+    /* Decrease data offset (reshape forwards) */
+    if (data_offset < sd->data_offset - min) {
+        pr_err("--data-offset too small on %s\n",
+               dn);
+        goto release;
+    }
+}
+
+When this code is reached, mdadm has already decided on a reshape
+direction. When increasing the data offset, the reshape runs backwards
+(dir==1); when decreasing the data offset, the reshape runs forwards
+(dir==-1).
+
+The conditional within the backwards reshape is correct: the requested
+offset must be larger than the old offset plus a minimum delta; thus the
+reshape has room to work.
+
+For the forwards reshape, the requested offset needs to be smaller than
+the old offset minus a minimum delta; to do this correctly, the
+comparison must be reversed.
+
+Also update the error message.
+
+Note: I have tested this change on a RAID 5 on Linux 4.18.0 and verified
+that there were no errors from the kernel and that the device data
+remained intact. I do not know if there are considerations for different
+RAID levels.
+
+Signed-off-by: Corey Hickey <bugfood-c@fatooh.org>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index 6d32661..764374f 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -2613,8 +2613,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
+ 					goto release;
+ 				}
+ 				if (data_offset != INVALID_SECTORS &&
+-				    data_offset < sd->data_offset - min) {
+-					pr_err("--data-offset too small on %s\n",
++				    data_offset > sd->data_offset - min) {
++					pr_err("--data-offset too large on %s\n",
+ 						dn);
+ 					goto release;
+ 				}
+-- 
+2.7.5
+
diff --git a/SOURCES/0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch b/SOURCES/0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch
new file mode 100644
index 0000000..1086a9d
--- /dev/null
+++ b/SOURCES/0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch
@@ -0,0 +1,100 @@
+From 76b906d2406cdf136f64de77e881eb2d180108d9 Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+Date: Fri, 7 Dec 2018 14:30:09 +0100
+Subject: [RHEL7.7 PATCH 17/24] mdadm/tests: add one test case for failfast of
+ raid1
+
+This creates raid1 device with the failfast option and check all
+slaves have the failfast flag. And it does assembling and growing
+the raid1 device and check the failfast works fine.
+
+Signed-off-by: Gioh Kim <gi-oh.kim@cloud.ionos.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ tests/05r1-failfast | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 74 insertions(+)
+ create mode 100644 tests/05r1-failfast
+
+diff --git a/tests/05r1-failfast b/tests/05r1-failfast
+new file mode 100644
+index 0000000..823dd6f
+--- /dev/null
++++ b/tests/05r1-failfast
+@@ -0,0 +1,74 @@
++
++# create a simple mirror and check failfast flag works
++mdadm -CR $md0 -e1.2 --level=raid1 --failfast -n2 $dev0 $dev1
++check raid1
++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null
++then
++   die "failfast missing"
++fi
++
++# Removing works with the failfast flag
++mdadm $md0 -f $dev0
++mdadm $md0 -r $dev0
++if grep -v failfast /sys/block/md0/md/rd1/state > /dev/null
++then
++   die "failfast missing"
++fi
++
++# Adding works with the failfast flag
++mdadm $md0 -a --failfast $dev0
++check wait
++if grep -v failfast /sys/block/md0/md/rd0/state > /dev/null
++then
++   die "failfast missing"
++fi
++
++mdadm -S $md0
++
++# Assembling works with the failfast flag
++mdadm -A $md0 $dev0 $dev1
++check raid1
++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null
++then
++   die "failfast missing"
++fi
++
++# Adding works with the nofailfast flag
++mdadm $md0 -f $dev0
++mdadm $md0 -r $dev0
++mdadm $md0 -a --nofailfast $dev0
++check wait
++if grep failfast /sys/block/md0/md/rd0/state > /dev/null
++then
++   die "failfast should be missing"
++fi
++
++# Assembling with one faulty slave works with the failfast flag
++mdadm $md0 -f $dev0
++mdadm $md0 -r $dev0
++mdadm -S $md0
++mdadm -A $md0 $dev0 $dev1
++check raid1
++mdadm -S $md0
++
++# Spare works with the failfast flag
++mdadm -CR $md0 -e1.2 --level=raid1 --failfast -n2 $dev0 $dev1
++check raid1
++mdadm $md0 -a --failfast $dev2
++check wait
++check spares 1
++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null
++then
++   die "failfast missing"
++fi
++
++# Grow works with the failfast flag
++mdadm -G $md0 --raid-devices=3
++check wait
++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null
++then
++   die "failfast missing"
++fi
++mdadm -S $md0
++
++exit 0
+-- 
+2.7.5
+
diff --git a/SOURCES/0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch b/SOURCES/0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch
new file mode 100644
index 0000000..1df909b
--- /dev/null
+++ b/SOURCES/0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch
@@ -0,0 +1,50 @@
+From 69d084784de196acec8ab703cd1b379af211d624 Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Fri, 22 Feb 2019 10:15:45 +0100
+Subject: [RHEL7.7 PATCH 18/24] mdmon: don't attempt to manage new arrays when
+ terminating
+
+When mdmon gets a SIGTERM, it stops managing arrays that are clean. If
+there is more that one array in the container and one of them is dirty
+and the clean one is still present in mdstat, mdmon will treat it as a
+new array and start managing it again. This leads to a cycle of
+remove_old() / manage_new() calls for the clean array, until the other
+one also becomes clean.
+
+Prevent this by not calling manage_new() if sigterm is set. Also, remove
+a check for sigterm in manage_new() because the condition will never be
+true.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ managemon.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/managemon.c b/managemon.c
+index 101231c..29b91ba 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -727,9 +727,7 @@ static void manage_new(struct mdstat_ent *mdstat,
+ 	dprintf("inst: %s action: %d state: %d\n", inst,
+ 		new->action_fd, new->info.state_fd);
+ 
+-	if (sigterm)
+-		new->info.safe_mode_delay = 1;
+-	else if (mdi->safe_mode_delay >= 50)
++	if (mdi->safe_mode_delay >= 50)
+ 		/* Normal start, mdadm set this. */
+ 		new->info.safe_mode_delay = mdi->safe_mode_delay;
+ 	else
+@@ -803,7 +801,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
+ 				break;
+ 			}
+ 		}
+-		if (a == NULL || !a->container)
++		if ((a == NULL || !a->container) && !sigterm)
+ 			manage_new(mdstat, container, a);
+ 	}
+ }
+-- 
+2.7.5
+
diff --git a/SOURCES/0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch b/SOURCES/0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch
new file mode 100644
index 0000000..fc6ead8
--- /dev/null
+++ b/SOURCES/0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch
@@ -0,0 +1,58 @@
+From d2e11da4b7fd0453e942f43e4196dc63b3dbd708 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Fri, 22 Feb 2019 13:30:27 +0100
+Subject: [RHEL7.7 PATCH 19/24] mdmon: wait for previous mdmon to exit during
+ takeover
+
+Since the patch c76242c5("mdmon: get safe mode delay file descriptor
+early"), safe_mode_dalay is set properly by initrd mdmon.  But in some
+cases with filesystem traffic since the very start of the system, it
+might take a while to transit to clean state.  Due to fact that new
+mdmon does not wait for the old one to exit - it might happen that the
+new one switches safe_mode_delay back to seconds, before old one exits.
+As the result two mdmons are running concurrently on same array.
+
+Wait for the old mdmon to exit by pinging it with SIGUSR1 signal, just
+in case it is sleeping.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdmon.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/mdmon.c b/mdmon.c
+index 0955fcc..ff985d2 100644
+--- a/mdmon.c
++++ b/mdmon.c
+@@ -171,6 +171,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock)
+ 	int fd;
+ 	int n;
+ 	long fl;
++	int rv;
+ 
+ 	/* first rule of survival... don't off yourself */
+ 	if (pid == getpid())
+@@ -201,9 +202,16 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock)
+ 	fl &= ~O_NONBLOCK;
+ 	fcntl(sock, F_SETFL, fl);
+ 	n = read(sock, buf, 100);
+-	/* Ignore result, it is just the wait that
+-	 * matters
+-	 */
++
++	/* If there is I/O going on it might took some time to get to
++	 * clean state. Wait for monitor to exit fully to avoid races.
++	 * Ping it with SIGUSR1 in case that it is sleeping  */
++	for (n = 0; n < 25; n++) {
++		rv = kill(pid, SIGUSR1);
++		if (rv < 0)
++			break;
++		usleep(200000);
++	}
+ }
+ 
+ void remove_pidfile(char *devname)
+-- 
+2.7.5
+
diff --git a/SOURCES/0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch b/SOURCES/0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch
new file mode 100644
index 0000000..498cf61
--- /dev/null
+++ b/SOURCES/0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch
@@ -0,0 +1,52 @@
+From 2b57e4fe041d52ae29866c93a878a11c07223cff Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Fri, 22 Feb 2019 12:56:27 +0100
+Subject: [RHEL7.7 PATCH 20/24] Assemble: Fix starting array with initial
+ reshape checkpoint
+
+If array was stopped during reshape initialization,
+there might be a "0" checkpoint recorded in metadata.
+If array with such condition (reshape with position 0)
+is passed to kernel - it will refuse to start such array.
+
+Treat such array as normal during assemble, Grow_continue() will
+reinitialize and start the reshape.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 9f050c1..420c7b3 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -2061,8 +2061,22 @@ int assemble_container_content(struct supertype *st, int mdfd,
+ 				   spare, &c->backup_file, c->verbose) == 1)
+ 			return 1;
+ 
+-		err = sysfs_set_str(content, NULL,
+-				    "array_state", "readonly");
++		if (content->reshape_progress == 0) {
++			/* If reshape progress is 0 - we are assembling the
++			 * array that was stopped, before reshape has started.
++			 * Array needs to be started as active, Grow_continue()
++			 * will start the reshape.
++			 */
++			sysfs_set_num(content, NULL, "reshape_position",
++				      MaxSector);
++			err = sysfs_set_str(content, NULL,
++					    "array_state", "active");
++			sysfs_set_num(content, NULL, "reshape_position", 0);
++		} else {
++			err = sysfs_set_str(content, NULL,
++					    "array_state", "readonly");
++		}
++
+ 		if (err)
+ 			return 1;
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0021-add-missing-units-to-examine.patch b/SOURCES/0021-add-missing-units-to-examine.patch
new file mode 100644
index 0000000..2ebb91e
--- /dev/null
+++ b/SOURCES/0021-add-missing-units-to-examine.patch
@@ -0,0 +1,59 @@
+From 227aeaa872d4898273cf87a4253898823d556c43 Mon Sep 17 00:00:00 2001
+From: Corey Hickey <bugfood-c@fatooh.org>
+Date: Mon, 11 Feb 2019 17:42:27 -0800
+Subject: [RHEL7.7 PATCH 21/24] add missing units to --examine
+
+Within the output of "mdadm --examine", there are three sizes reported
+on adjacent lines. For example:
+
+$ sudo mdadm --examine /dev/md3
+[...]
+ Avail Dev Size : 17580545024 (8383.06 GiB 9001.24 GB)
+     Array Size : 17580417024 (16765.99 GiB 18002.35 GB)
+  Used Dev Size : 11720278016 (5588.66 GiB 6000.78 GB)
+[...]
+
+This can be confusing, since the first and third line are in 512-byte
+sectors, and the second is in KiB.
+
+Add units to avoid ambiguity.
+
+(I don't particularly like the "KiB" notation, but it is at least
+unambiguous.)
+
+Signed-off-by: Corey Hickey <bugfood-c@fatooh.org>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index 636a286..b85dc20 100644
+--- a/super1.c
++++ b/super1.c
+@@ -360,7 +360,7 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	printf("     Raid Level : %s\n", c?c:"-unknown-");
+ 	printf("   Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
+ 	printf("\n");
+-	printf(" Avail Dev Size : %llu%s\n",
++	printf(" Avail Dev Size : %llu sectors%s\n",
+ 	       (unsigned long long)__le64_to_cpu(sb->data_size),
+ 	       human_size(__le64_to_cpu(sb->data_size)<<9));
+ 	if (__le32_to_cpu(sb->level) > 0) {
+@@ -378,11 +378,11 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 		if (ddsks) {
+ 			long long asize = __le64_to_cpu(sb->size);
+ 			asize = (asize << 9) * ddsks / ddsks_denom;
+-			printf("     Array Size : %llu%s\n",
++			printf("     Array Size : %llu KiB%s\n",
+ 			       asize >> 10,  human_size(asize));
+ 		}
+ 		if (sb->size != sb->data_size)
+-			printf("  Used Dev Size : %llu%s\n",
++			printf("  Used Dev Size : %llu sectors%s\n",
+ 			       (unsigned long long)__le64_to_cpu(sb->size),
+ 			       human_size(__le64_to_cpu(sb->size)<<9));
+ 	}
+-- 
+2.7.5
+
diff --git a/SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch b/SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch
new file mode 100644
index 0000000..b99afa6
--- /dev/null
+++ b/SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch
@@ -0,0 +1,117 @@
+From 05501181f18cdccdb0b3cec1d8cf59f0995504d7 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Fri, 8 Mar 2019 12:19:11 +0100
+Subject: [RHEL7.7 PATCH 22/24] imsm: fix spare activation for old matrix
+ arrays
+
+During spare activation get_extents() calculates metadata reserved space based
+on smallest active RAID member or it will take the defaults. Since patch
+611d9529("imsm: change reserved space to 4MB") default is extended.  If array
+was created prior that patch, reserved space is smaller. In case of matrix
+RAID - spare is activated in each array one-by-one, so it is spare for first
+activation, but treated as "active" during second one.
+
+In case of adding spare drive to old matrix RAID with the size the same as
+already existing member drive the routine will take the defaults during second
+run and mdmon will refuse to rebuild second volume, claiming that the drive
+does not have enough free space.
+
+Add parameter to get_extents(), so the during spare activation reserved space
+is always based on smallest active drive - even if given drive is already
+active in some other array of matrix RAID.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index c399433..5a7c9f8 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1313,7 +1313,8 @@ static unsigned long long per_dev_array_size(struct imsm_map *map)
+ 	return array_size;
+ }
+ 
+-static struct extent *get_extents(struct intel_super *super, struct dl *dl)
++static struct extent *get_extents(struct intel_super *super, struct dl *dl,
++				  int get_minimal_reservation)
+ {
+ 	/* find a list of used extents on the given physical device */
+ 	struct extent *rv, *e;
+@@ -1325,7 +1326,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
+ 	 * regardless of whether the OROM has assigned sectors from the
+ 	 * IMSM_RESERVED_SECTORS region
+ 	 */
+-	if (dl->index == -1)
++	if (dl->index == -1 || get_minimal_reservation)
+ 		reservation = imsm_min_reserved_sectors(super);
+ 	else
+ 		reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
+@@ -1386,7 +1387,7 @@ static __u32 imsm_reserved_sectors(struct intel_super *super, struct dl *dl)
+ 	if (dl->index == -1)
+ 		return MPB_SECTOR_CNT;
+ 
+-	e = get_extents(super, dl);
++	e = get_extents(super, dl, 0);
+ 	if (!e)
+ 		return MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
+ 
+@@ -1478,7 +1479,7 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super)
+ 		return rv;
+ 
+ 	/* find last lba used by subarrays on the smallest active disk */
+-	e = get_extents(super, dl_min);
++	e = get_extents(super, dl_min, 0);
+ 	if (!e)
+ 		return rv;
+ 	for (i = 0; e[i].size; i++)
+@@ -1519,7 +1520,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
+ 	if (!dl)
+ 		return -EINVAL;
+ 	/* find last lba used by subarrays */
+-	e = get_extents(super, dl);
++	e = get_extents(super, dl, 0);
+ 	if (!e)
+ 		return -EINVAL;
+ 	for (i = 0; e[i].size; i++)
+@@ -7203,7 +7204,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
+ 
+ 			pos = 0;
+ 			i = 0;
+-			e = get_extents(super, dl);
++			e = get_extents(super, dl, 0);
+ 			if (!e) continue;
+ 			do {
+ 				unsigned long long esize;
+@@ -7261,7 +7262,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
+ 	}
+ 
+ 	/* retrieve the largest free space block */
+-	e = get_extents(super, dl);
++	e = get_extents(super, dl, 0);
+ 	maxsize = 0;
+ 	i = 0;
+ 	if (e) {
+@@ -7359,7 +7360,7 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
+ 		if (super->orom && dl->index < 0 && mpb->num_raid_devs)
+ 			continue;
+ 
+-		e = get_extents(super, dl);
++		e = get_extents(super, dl, 0);
+ 		if (!e)
+ 			continue;
+ 		for (i = 1; e[i-1].size; i++)
+@@ -8846,7 +8847,7 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
+ 		/* Does this unused device have the requisite free space?
+ 		 * It needs to be able to cover all member volumes
+ 		 */
+-		ex = get_extents(super, dl);
++		ex = get_extents(super, dl, 1);
+ 		if (!ex) {
+ 			dprintf("cannot get extents\n");
+ 			continue;
+-- 
+2.7.5
+
diff --git a/SOURCES/0023-Create-Block-rounding-size-to-max.patch b/SOURCES/0023-Create-Block-rounding-size-to-max.patch
new file mode 100644
index 0000000..e8b8102
--- /dev/null
+++ b/SOURCES/0023-Create-Block-rounding-size-to-max.patch
@@ -0,0 +1,94 @@
+From 22dc741f63e6403d59c2c14f56fd4791265f9bbb Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Mon, 1 Apr 2019 16:53:41 +0200
+Subject: [RHEL7.7 PATCH 23/24] Create: Block rounding size to max
+
+When passed size is smaller than chunk, mdadm rounds it to 0 but 0 there
+means max available space.
+Block it for every metadata. Remove the same check from imsm routine.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Create.c      | 23 ++++++++++++++++++++---
+ super-intel.c |  5 ++---
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 6f1b228..292f92a 100644
+--- a/Create.c
++++ b/Create.c
+@@ -27,6 +27,18 @@
+ #include	"md_p.h"
+ #include	<ctype.h>
+ 
++static int round_size_and_verify(unsigned long long *size, int chunk)
++{
++	if (*size == 0)
++		return 0;
++	*size &= ~(unsigned long long)(chunk - 1);
++	if (*size == 0) {
++		pr_err("Size cannot be smaller than chunk.\n");
++		return 1;
++	}
++	return 0;
++}
++
+ static int default_layout(struct supertype *st, int level, int verbose)
+ {
+ 	int layout = UnSet;
+@@ -248,11 +260,14 @@ int Create(struct supertype *st, char *mddev,
+ 		pr_err("unknown level %d\n", s->level);
+ 		return 1;
+ 	}
++
+ 	if (s->size == MAX_SIZE)
+ 		/* use '0' to mean 'max' now... */
+ 		s->size = 0;
+ 	if (s->size && s->chunk && s->chunk != UnSet)
+-		s->size &= ~(unsigned long long)(s->chunk - 1);
++		if (round_size_and_verify(&s->size, s->chunk))
++			return 1;
++
+ 	newsize = s->size * 2;
+ 	if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks,
+ 					      &s->chunk, s->size*2,
+@@ -267,7 +282,8 @@ int Create(struct supertype *st, char *mddev,
+ 			/* default chunk was just set */
+ 			if (c->verbose > 0)
+ 				pr_err("chunk size defaults to %dK\n", s->chunk);
+-			s->size &= ~(unsigned long long)(s->chunk - 1);
++			if (round_size_and_verify(&s->size, s->chunk))
++				return 1;
+ 			do_default_chunk = 0;
+ 		}
+ 	}
+@@ -413,7 +429,8 @@ int Create(struct supertype *st, char *mddev,
+ 				/* default chunk was just set */
+ 				if (c->verbose > 0)
+ 					pr_err("chunk size defaults to %dK\n", s->chunk);
+-				s->size &= ~(unsigned long long)(s->chunk - 1);
++				if (round_size_and_verify(&s->size, s->chunk))
++					return 1;
+ 				do_default_chunk = 0;
+ 			}
+ 		}
+diff --git a/super-intel.c b/super-intel.c
+index 5a7c9f8..2ba045a 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7455,9 +7455,8 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
+ 							verbose);
+ 	}
+ 
+-	if (size && ((size < 1024) || (*chunk != UnSet &&
+-	    size < (unsigned long long) *chunk))) {
+-		pr_err("Given size must be greater than 1M and chunk size.\n");
++	if (size && (size < 1024)) {
++		pr_err("Given size must be greater than 1M.\n");
+ 		/* Depends on algorithm in Create.c :
+ 		 * if container was given (dev == NULL) return -1,
+ 		 * if block device was given ( dev != NULL) return 0.
+-- 
+2.7.5
+
diff --git a/SOURCES/0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch b/SOURCES/0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch
new file mode 100644
index 0000000..35b8741
--- /dev/null
+++ b/SOURCES/0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch
@@ -0,0 +1,31 @@
+From 3c9b46cf9ae15a9be98fc47e2080bd9494496246 Mon Sep 17 00:00:00 2001
+From: Liwei Song <liwei.song@windriver.com>
+Date: Tue, 19 Mar 2019 23:51:05 -0400
+Subject: [RHEL7.7 PATCH 24/24] udev: Add udev rules to create by-partuuid for
+ md device
+
+This rules will create link under /dev/disk/by-partuuid/ for
+MD devices partition, with which will support specify
+root=PARTUUID=XXX to boot rootfs.
+
+Signed-off-by: Liwei Song <liwei.song@windriver.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ udev-md-raid-arrays.rules | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
+index c95ec7b..5b99d58 100644
+--- a/udev-md-raid-arrays.rules
++++ b/udev-md-raid-arrays.rules
+@@ -30,6 +30,7 @@ IMPORT{builtin}="blkid"
+ OPTIONS+="link_priority=100"
+ OPTIONS+="watch"
+ ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
++ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
+ ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
+ 
+ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
+-- 
+2.7.5
+
diff --git a/SOURCES/0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch b/SOURCES/0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch
new file mode 100644
index 0000000..7b03614
--- /dev/null
+++ b/SOURCES/0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch
@@ -0,0 +1,109 @@
+From ae7d61e35ec2ab6361c3e509a8db00698ef3396f Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Tue, 7 May 2019 16:08:47 +0200
+Subject: [RHEL7.8 PATCH V2 25/47] mdmon: fix wrong array state when disk fails
+ during mdmon startup
+
+If a member drive disappears and is set faulty by the kernel during
+mdmon startup, after ss->load_container() but before manage_new(), mdmon
+will try to readd the faulty drive to the array and start rebuilding.
+Metadata on the active drive is updated, but the faulty drive is not
+removed from the array and is left in a "blocked" state and any write
+request to the array will block. If the faulty drive reappears in the
+system e.g. after a reboot, the array will not assemble because metadata
+on the drives will be incompatible (at least on imsm).
+
+Fix this by adding a new option for sysfs_read(): "GET_DEVS_ALL". This
+is an extension for the "GET_DEVS" option and causes all member devices
+to be returned, even if the associated block device has been removed.
+Use this option in manage_new() to include the faulty device on the
+active_array's devices list. Mdmon will then properly remove the faulty
+device from the array and update the metadata to reflect the degraded
+state.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ managemon.c   |  2 +-
+ mdadm.h       |  1 +
+ super-intel.c |  2 +-
+ sysfs.c       | 23 ++++++++++++++---------
+ 4 files changed, 17 insertions(+), 11 deletions(-)
+
+diff --git a/managemon.c b/managemon.c
+index 29b91ba..200cf83 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -678,7 +678,7 @@ static void manage_new(struct mdstat_ent *mdstat,
+ 	mdi = sysfs_read(-1, mdstat->devnm,
+ 			 GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT|
+ 			 GET_SAFEMODE|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
+-			 GET_LAYOUT);
++			 GET_LAYOUT|GET_DEVS_ALL);
+ 
+ 	if (!mdi)
+ 		return;
+diff --git a/mdadm.h b/mdadm.h
+index 705bd9b..427cc52 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -647,6 +647,7 @@ enum sysfs_read_flags {
+ 	GET_ERROR	= (1 << 24),
+ 	GET_ARRAY_STATE = (1 << 25),
+ 	GET_CONSISTENCY_POLICY	= (1 << 26),
++	GET_DEVS_ALL	= (1 << 27),
+ };
+ 
+ /* If fd >= 0, get the array it is open on,
+diff --git a/super-intel.c b/super-intel.c
+index 2ba045a..4fd5e84 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -8560,7 +8560,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 	disk = get_imsm_disk(super, ord_to_idx(ord));
+ 
+ 	/* check for new failures */
+-	if (state & DS_FAULTY) {
++	if (disk && (state & DS_FAULTY)) {
+ 		if (mark_failure(super, dev, disk, ord_to_idx(ord)))
+ 			super->updates_pending++;
+ 	}
+diff --git a/sysfs.c b/sysfs.c
+index df6fdda..2dd9ab6 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -313,17 +313,22 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 			/* assume this is a stale reference to a hot
+ 			 * removed device
+ 			 */
+-			free(dev);
+-			continue;
++			if (!(options & GET_DEVS_ALL)) {
++				free(dev);
++				continue;
++			}
++		} else {
++			sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
+ 		}
+-		sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
+ 
+-		/* special case check for block devices that can go 'offline' */
+-		strcpy(dbase, "block/device/state");
+-		if (load_sys(fname, buf, sizeof(buf)) == 0 &&
+-		    strncmp(buf, "offline", 7) == 0) {
+-			free(dev);
+-			continue;
++		if (!(options & GET_DEVS_ALL)) {
++			/* special case check for block devices that can go 'offline' */
++			strcpy(dbase, "block/device/state");
++			if (load_sys(fname, buf, sizeof(buf)) == 0 &&
++			    strncmp(buf, "offline", 7) == 0) {
++				free(dev);
++				continue;
++			}
+ 		}
+ 
+ 		/* finally add this disk to the array */
+-- 
+2.7.5
+
diff --git a/SOURCES/0026-Enable-probe_roms-to-scan-more-than-6-roms.patch b/SOURCES/0026-Enable-probe_roms-to-scan-more-than-6-roms.patch
new file mode 100644
index 0000000..8aaa33f
--- /dev/null
+++ b/SOURCES/0026-Enable-probe_roms-to-scan-more-than-6-roms.patch
@@ -0,0 +1,212 @@
+From 4ec389e3f0c1233f5aa2d5b4e63d96e33d2a37f0 Mon Sep 17 00:00:00 2001
+From: Roman Sobanski <roman.sobanski@intel.com>
+Date: Tue, 2 Jul 2019 13:29:27 +0200
+Subject: [RHEL7.8 PATCH V2 26/47] Enable probe_roms to scan more than 6 roms.
+
+In some cases if more than 6 oroms exist, resource for particular
+controller may not be found. Change method for storing
+adapter_rom_resources from array to list.
+
+Signed-off-by: Roman Sobanski <roman.sobanski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ probe_roms.c | 98 ++++++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 56 insertions(+), 42 deletions(-)
+
+diff --git a/probe_roms.c b/probe_roms.c
+index b0b0883..7ea04c7 100644
+--- a/probe_roms.c
++++ b/probe_roms.c
+@@ -35,6 +35,9 @@ static const int rom_len = 0xf0000 - 0xc0000; /* option-rom memory region */
+ static int _sigbus;
+ static unsigned long rom_align;
+ 
++static void roms_deinit(void);
++static int roms_init(void);
++
+ static void sigbus(int sig)
+ {
+ 	_sigbus = 1;
+@@ -75,6 +78,7 @@ void probe_roms_exit(void)
+ 		munmap(rom_mem, rom_len);
+ 		rom_mem = MAP_FAILED;
+ 	}
++	roms_deinit();
+ }
+ 
+ int probe_roms_init(unsigned long align)
+@@ -91,6 +95,9 @@ int probe_roms_init(unsigned long align)
+ 	else
+ 		return -1;
+ 
++	if (roms_init())
++		return -1;
++
+ 	if (signal(SIGBUS, sigbus) == SIG_ERR)
+ 		rc = -1;
+ 	if (rc == 0) {
+@@ -131,6 +138,7 @@ struct resource {
+ 	unsigned long end;
+ 	unsigned long data;
+ 	const char *name;
++	struct resource *next;
+ };
+ 
+ static struct resource system_rom_resource = {
+@@ -147,37 +155,7 @@ static struct resource extension_rom_resource = {
+ 	.end	= 0xeffff,
+ };
+ 
+-static struct resource adapter_rom_resources[] = { {
+-	.name	= "Adapter ROM",
+-	.start	= 0xc8000,
+-	.data   = 0,
+-	.end	= 0,
+-}, {
+-	.name	= "Adapter ROM",
+-	.start	= 0,
+-	.data   = 0,
+-	.end	= 0,
+-}, {
+-	.name	= "Adapter ROM",
+-	.start	= 0,
+-	.data   = 0,
+-	.end	= 0,
+-}, {
+-	.name	= "Adapter ROM",
+-	.start	= 0,
+-	.data   = 0,
+-	.end	= 0,
+-}, {
+-	.name	= "Adapter ROM",
+-	.start	= 0,
+-	.data   = 0,
+-	.end	= 0,
+-}, {
+-	.name	= "Adapter ROM",
+-	.start	= 0,
+-	.data   = 0,
+-	.end	= 0,
+-} };
++static struct resource *adapter_rom_resources;
+ 
+ static struct resource video_rom_resource = {
+ 	.name	= "Video ROM",
+@@ -186,8 +164,35 @@ static struct resource video_rom_resource = {
+ 	.end	= 0xc7fff,
+ };
+ 
++static int roms_init(void)
++{
++	adapter_rom_resources = malloc(sizeof(struct resource));
++	if (adapter_rom_resources == NULL)
++		return 1;
++	adapter_rom_resources->name = "Adapter ROM";
++	adapter_rom_resources->start = 0xc8000;
++	adapter_rom_resources->data = 0;
++	adapter_rom_resources->end = 0;
++	adapter_rom_resources->next = NULL;
++	return 0;
++}
++
++static void roms_deinit(void)
++{
++	struct resource *res;
++
++	res = adapter_rom_resources;
++	while (res) {
++		struct resource *tmp = res;
++
++		res = res->next;
++		free(tmp);
++	}
++}
++
+ #define ROMSIGNATURE 0xaa55
+ 
++
+ static int romsignature(const unsigned char *rom)
+ {
+ 	const unsigned short * const ptr = (const unsigned short *)rom;
+@@ -208,16 +213,14 @@ static int romchecksum(const unsigned char *rom, unsigned long length)
+ int scan_adapter_roms(scan_fn fn)
+ {
+ 	/* let scan_fn examing each of the adapter roms found by probe_roms */
+-	unsigned int i;
++	struct resource *res = adapter_rom_resources;
+ 	int found;
+ 
+ 	if (rom_fd < 0)
+ 		return 0;
+ 
+ 	found = 0;
+-	for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) {
+-		struct resource *res = &adapter_rom_resources[i];
+-
++	while (res) {
+ 		if (res->start) {
+ 			found = fn(isa_bus_to_virt(res->start),
+ 				   isa_bus_to_virt(res->end),
+@@ -226,6 +229,7 @@ int scan_adapter_roms(scan_fn fn)
+ 				break;
+ 		} else
+ 			break;
++		res = res->next;
+ 	}
+ 
+ 	return found;
+@@ -241,14 +245,14 @@ void probe_roms(void)
+ 	const void *rom;
+ 	unsigned long start, length, upper;
+ 	unsigned char c;
+-	unsigned int i;
++	struct resource *res = adapter_rom_resources;
+ 	__u16 val=0;
+ 
+ 	if (rom_fd < 0)
+ 		return;
+ 
+ 	/* video rom */
+-	upper = adapter_rom_resources[0].start;
++	upper = res->start;
+ 	for (start = video_rom_resource.start; start < upper; start += rom_align) {
+ 		rom = isa_bus_to_virt(start);
+ 		if (!romsignature(rom))
+@@ -283,8 +287,9 @@ void probe_roms(void)
+ 			upper = extension_rom_resource.start;
+ 	}
+ 
++	struct resource *prev_res = res;
+ 	/* check for adapter roms on 2k boundaries */
+-	for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += rom_align) {
++	for (; start < upper; start += rom_align) {
+ 		rom = isa_bus_to_virt(start);
+ 		if (!romsignature(rom))
+ 			continue;
+@@ -308,10 +313,19 @@ void probe_roms(void)
+ 		if (!length || start + length > upper || !romchecksum(rom, length))
+ 			continue;
+ 
+-		adapter_rom_resources[i].start = start;
+-		adapter_rom_resources[i].data = start + (unsigned long) val;
+-		adapter_rom_resources[i].end = start + length - 1;
++		if (res == NULL) {
++			res = calloc(1, sizeof(struct resource));
++			if (res == NULL)
++				return;
++			prev_res->next = res;
++		}
++
++		res->start = start;
++		res->data = start + (unsigned long)val;
++		res->end = start + length - 1;
+ 
+-		start = adapter_rom_resources[i++].end & ~(rom_align - 1);
++		start = res->end & ~(rom_align - 1);
++		prev_res = res;
++		res = res->next;
+ 	}
+ }
+-- 
+2.7.5
+
diff --git a/SOURCES/0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch b/SOURCES/0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch
new file mode 100644
index 0000000..6783118
--- /dev/null
+++ b/SOURCES/0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch
@@ -0,0 +1,39 @@
+From a4f7290c20c2ff78328c9db0b18029165cfb05b2 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 Jul 2019 13:26:08 -0400
+Subject: [RHEL7.8 PATCH V2 27/47] super-intel: Fix issue with abs() being
+ irrelevant
+
+gcc9 complains about subtracting unsigned from unsigned and code
+assuming the result can be negative.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 4fd5e84..230e164 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -2875,7 +2875,7 @@ static unsigned long long calc_component_size(struct imsm_map *map,
+ {
+ 	unsigned long long component_size;
+ 	unsigned long long dev_size = imsm_dev_size(dev);
+-	unsigned long long calc_dev_size = 0;
++	long long calc_dev_size = 0;
+ 	unsigned int member_disks = imsm_num_data_members(map);
+ 
+ 	if (member_disks == 0)
+@@ -2889,7 +2889,7 @@ static unsigned long long calc_component_size(struct imsm_map *map,
+ 	 * 2048 blocks per each device. If the difference is higher it means
+ 	 * that array size was expanded and num_data_stripes was not updated.
+ 	 */
+-	if ((unsigned int)abs(calc_dev_size - dev_size) >
++	if (llabs(calc_dev_size - (long long)dev_size) >
+ 	    (1 << SECT_PER_MB_SHIFT) * member_disks) {
+ 		component_size = dev_size / member_disks;
+ 		dprintf("Invalid num_data_stripes in metadata; expected=%llu, found=%llu\n",
+-- 
+2.7.5
+
diff --git a/SOURCES/0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch b/SOURCES/0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch
new file mode 100644
index 0000000..7daa513
--- /dev/null
+++ b/SOURCES/0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch
@@ -0,0 +1,57 @@
+From 7039d1f8200b9599b23db5953934fdb43b0442e0 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 Jul 2019 14:15:38 -0400
+Subject: [RHEL7.8 PATCH V2 28/47] mdadm.h: Introduced unaligned
+ {get,put}_unaligned{16,32}()
+
+We need these to avoid gcc9 going all crazy on us.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.h | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/mdadm.h b/mdadm.h
+index 427cc52..0fa9e1b 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -192,6 +192,36 @@ struct dlm_lksb {
+ #endif /* __KLIBC__ */
+ 
+ /*
++ * Partially stolen from include/linux/unaligned/packed_struct.h
++ */
++struct __una_u16 { __u16 x; } __attribute__ ((packed));
++struct __una_u32 { __u32 x; } __attribute__ ((packed));
++
++static inline __u16 __get_unaligned16(const void *p)
++{
++	const struct __una_u16 *ptr = (const struct __una_u16 *)p;
++	return ptr->x;
++}
++
++static inline __u32 __get_unaligned32(const void *p)
++{
++	const struct __una_u32 *ptr = (const struct __una_u32 *)p;
++	return ptr->x;
++}
++
++static inline void __put_unaligned16(__u16 val, void *p)
++{
++	struct __una_u16 *ptr = (struct __una_u16 *)p;
++	ptr->x = val;
++}
++
++static inline void __put_unaligned32(__u32 val, void *p)
++{
++	struct __una_u32 *ptr = (struct __una_u32 *)p;
++	ptr->x = val;
++}
++
++/*
+   * Check at compile time that something is of a particular type.
+   * Always evaluates to 1 so you may use it easily in comparisons.
+ */
+-- 
+2.7.5
+
diff --git a/SOURCES/0029-super-intel-Use-put_unaligned-in-split_ull.patch b/SOURCES/0029-super-intel-Use-put_unaligned-in-split_ull.patch
new file mode 100644
index 0000000..0b643b1
--- /dev/null
+++ b/SOURCES/0029-super-intel-Use-put_unaligned-in-split_ull.patch
@@ -0,0 +1,38 @@
+From 486720e0c2418e7e2e0a16221f7c42a308622254 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 Jul 2019 14:49:22 -0400
+Subject: [RHEL7.8 PATCH V2 29/47] super-intel: Use put_unaligned in split_ull
+
+Shut up some gcc9 errors by using put_unaligned() accessors. Not pretty,
+but better than it was.
+
+Also correct to the correct swap macros.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 230e164..d7e8a65 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1165,12 +1165,12 @@ static int count_memberships(struct dl *dl, struct intel_super *super)
+ 
+ static __u32 imsm_min_reserved_sectors(struct intel_super *super);
+ 
+-static int split_ull(unsigned long long n, __u32 *lo, __u32 *hi)
++static int split_ull(unsigned long long n, void *lo, void *hi)
+ {
+ 	if (lo == 0 || hi == 0)
+ 		return 1;
+-	*lo = __le32_to_cpu((unsigned)n);
+-	*hi = __le32_to_cpu((unsigned)(n >> 32));
++	__put_unaligned32(__cpu_to_le32((__u32)n), lo);
++	__put_unaligned32(__cpu_to_le32((n >> 32)), hi);
+ 	return 0;
+ }
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch b/SOURCES/0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch
new file mode 100644
index 0000000..8941a5e
--- /dev/null
+++ b/SOURCES/0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch
@@ -0,0 +1,345 @@
+From b06815989179e0f153e44e4336290e655edce9a1 Mon Sep 17 00:00:00 2001
+From: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Date: Wed, 10 Jul 2019 13:38:53 +0200
+Subject: [RHEL7.8 PATCH V2 30/47] mdadm: load default sysfs attributes after
+ assemblation
+
+Added new type of line to mdadm.conf which allows to specify values of
+sysfs attributes for MD devices that should be loaded after the array is
+assembled. Each line is interpreted as list of structures containing
+sysname of MD device (md126 etc.) and list of sysfs attributes and their
+values.
+
+Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+Signed-off-by: Krzysztof Smolinski <krzysztof.smolinski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c    |  12 +++--
+ Incremental.c |   1 +
+ config.c      |   7 ++-
+ mdadm.conf.5  |  25 ++++++++++
+ mdadm.h       |   3 ++
+ sysfs.c       | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 202 insertions(+), 4 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 420c7b3..b2e6914 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1063,9 +1063,12 @@ static int start_array(int mdfd,
+ 			       mddev, okcnt + sparecnt + journalcnt,
+ 			       okcnt + sparecnt + journalcnt == 1 ? "" : "s");
+ 			if (okcnt < (unsigned)content->array.raid_disks)
+-				fprintf(stderr, " (out of %d)",
++				fprintf(stderr, " (out of %d)\n",
+ 					content->array.raid_disks);
+-			fprintf(stderr, "\n");
++			else {
++				fprintf(stderr, "\n");
++				sysfs_rules_apply(mddev, content);
++			}
+ 		}
+ 
+ 		if (st->ss->validate_container) {
+@@ -1139,6 +1142,7 @@ static int start_array(int mdfd,
+ 			rv = ioctl(mdfd, RUN_ARRAY, NULL);
+ 		reopen_mddev(mdfd); /* drop O_EXCL */
+ 		if (rv == 0) {
++			sysfs_rules_apply(mddev, content);
+ 			if (c->verbose >= 0) {
+ 				pr_err("%s has been started with %d drive%s",
+ 				       mddev, okcnt, okcnt==1?"":"s");
+@@ -2130,10 +2134,12 @@ int assemble_container_content(struct supertype *st, int mdfd,
+ 			pr_err("array %s now has %d device%s",
+ 			       chosen_name, working + preexist,
+ 			       working + preexist == 1 ? "":"s");
+-		else
++		else {
++			sysfs_rules_apply(chosen_name, content);
+ 			pr_err("Started %s with %d device%s",
+ 			       chosen_name, working + preexist,
+ 			       working + preexist == 1 ? "":"s");
++		}
+ 		if (preexist)
+ 			fprintf(stderr, " (%d new)", working);
+ 		if (expansion)
+diff --git a/Incremental.c b/Incremental.c
+index d4d3c35..98dbcd9 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -480,6 +480,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 			pr_err("container %s now has %d device%s\n",
+ 			       chosen_name, info.array.working_disks,
+ 			       info.array.working_disks == 1?"":"s");
++		sysfs_rules_apply(chosen_name, &info);
+ 		wait_for(chosen_name, mdfd);
+ 		if (st->ss->external)
+ 			strcpy(devnm, fd2devnm(mdfd));
+diff --git a/config.c b/config.c
+index e14eae0..7592b2d 100644
+--- a/config.c
++++ b/config.c
+@@ -80,7 +80,8 @@ char DefaultAltConfFile[] = CONFFILE2;
+ char DefaultAltConfDir[] = CONFFILE2 ".d";
+ 
+ enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev,
+-		Homehost, HomeCluster, AutoMode, Policy, PartPolicy, LTEnd };
++		Homehost, HomeCluster, AutoMode, Policy, PartPolicy, Sysfs,
++		LTEnd };
+ char *keywords[] = {
+ 	[Devices]  = "devices",
+ 	[Array]    = "array",
+@@ -93,6 +94,7 @@ char *keywords[] = {
+ 	[AutoMode] = "auto",
+ 	[Policy]   = "policy",
+ 	[PartPolicy]="part-policy",
++	[Sysfs]    = "sysfs",
+ 	[LTEnd]    = NULL
+ };
+ 
+@@ -764,6 +766,9 @@ void conf_file(FILE *f)
+ 		case PartPolicy:
+ 			policyline(line, rule_part);
+ 			break;
++		case Sysfs:
++			sysfsline(line);
++			break;
+ 		default:
+ 			pr_err("Unknown keyword %s\n", line);
+ 		}
+diff --git a/mdadm.conf.5 b/mdadm.conf.5
+index 47c962a..27dbab1 100644
+--- a/mdadm.conf.5
++++ b/mdadm.conf.5
+@@ -587,6 +587,26 @@ be based on the domain, but with
+ appended, when N is the partition number for the partition that was
+ found.
+ 
++.TP
++.B SYSFS
++The SYSFS line lists custom values of MD device's sysfs attributes which will be
++stored in sysfs after the array is assembled. Multiple lines are allowed and each
++line has to contain the uuid or the name of the device to which it relates.
++.RS 4
++.TP
++.B uuid=
++hexadecimal identifier of MD device. This has to match the uuid stored in the
++superblock.
++.TP
++.B name=
++name of the MD device as was given to
++.I mdadm
++when the array was created. It will be ignored if
++.B uuid
++is not empty.
++.TP
++.RS 7
++
+ .SH EXAMPLE
+ DEVICE /dev/sd[bcdjkl]1
+ .br
+@@ -657,6 +677,11 @@ CREATE group=system mode=0640 auto=part\-8
+ HOMEHOST <system>
+ .br
+ AUTO +1.x homehost \-all
++.br
++SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000
++.br
++SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4
++sync_speed_max=1000000
+ 
+ .SH SEE ALSO
+ .BR mdadm (8),
+diff --git a/mdadm.h b/mdadm.h
+index 0fa9e1b..c36d7fd 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1322,6 +1322,9 @@ void domain_add(struct domainlist **domp, char *domain);
+ extern void policy_save_path(char *id_path, struct map_ent *array);
+ extern int policy_check_path(struct mdinfo *disk, struct map_ent *array);
+ 
++extern void sysfs_rules_apply(char *devnm, struct mdinfo *dev);
++extern void sysfsline(char *line);
++
+ #if __GNUC__ < 3
+ struct stat64;
+ #endif
+diff --git a/sysfs.c b/sysfs.c
+index 2dd9ab6..c313781 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -26,9 +26,22 @@
+ #include	"mdadm.h"
+ #include	<dirent.h>
+ #include	<ctype.h>
++#include	"dlink.h"
+ 
+ #define MAX_SYSFS_PATH_LEN	120
+ 
++struct dev_sysfs_rule {
++	struct dev_sysfs_rule *next;
++	char *devname;
++	int uuid[4];
++	int uuid_set;
++	struct sysfs_entry {
++		struct sysfs_entry *next;
++		char *name;
++		char *value;
++	} *entry;
++};
++
+ int load_sys(char *path, char *buf, int len)
+ {
+ 	int fd = open(path, O_RDONLY);
+@@ -999,3 +1012,148 @@ int sysfs_wait(int fd, int *msec)
+ 	}
+ 	return n;
+ }
++
++int sysfs_rules_apply_check(const struct mdinfo *sra,
++			    const struct sysfs_entry *ent)
++{
++	/* Check whether parameter is regular file,
++	 * exists and is under specified directory.
++	 */
++	char fname[MAX_SYSFS_PATH_LEN];
++	char dname[MAX_SYSFS_PATH_LEN];
++	char resolved_path[PATH_MAX];
++	char resolved_dir[PATH_MAX];
++
++	if (sra == NULL || ent == NULL)
++		return -1;
++
++	snprintf(dname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md/", sra->sys_name);
++	snprintf(fname, MAX_SYSFS_PATH_LEN, "%s/%s", dname, ent->name);
++
++	if (realpath(fname, resolved_path) == NULL ||
++	    realpath(dname, resolved_dir) == NULL)
++		return -1;
++
++	if (strncmp(resolved_dir, resolved_path,
++		    strnlen(resolved_dir, PATH_MAX)) != 0)
++		return -1;
++
++	return 0;
++}
++
++static struct dev_sysfs_rule *sysfs_rules;
++
++void sysfs_rules_apply(char *devnm, struct mdinfo *dev)
++{
++	struct dev_sysfs_rule *rules = sysfs_rules;
++
++	while (rules) {
++		struct sysfs_entry *ent = rules->entry;
++		int match  = 0;
++
++		if (!rules->uuid_set) {
++			if (rules->devname)
++				match = strcmp(devnm, rules->devname) == 0;
++		} else {
++			match = memcmp(dev->uuid, rules->uuid,
++				       sizeof(int[4])) == 0;
++		}
++
++		while (match && ent) {
++			if (sysfs_rules_apply_check(dev, ent) < 0)
++				pr_err("SYSFS: failed to write '%s' to '%s'\n",
++					ent->value, ent->name);
++			else
++				sysfs_set_str(dev, NULL, ent->name, ent->value);
++			ent = ent->next;
++		}
++		rules = rules->next;
++	}
++}
++
++static void sysfs_rule_free(struct dev_sysfs_rule *rule)
++{
++	struct sysfs_entry *entry;
++
++	while (rule) {
++		struct dev_sysfs_rule *tmp = rule->next;
++
++		entry = rule->entry;
++		while (entry) {
++			struct sysfs_entry *tmp = entry->next;
++
++			free(entry->name);
++			free(entry->value);
++			free(entry);
++			entry = tmp;
++		}
++
++		if (rule->devname)
++			free(rule->devname);
++		free(rule);
++		rule = tmp;
++	}
++}
++
++void sysfsline(char *line)
++{
++	struct dev_sysfs_rule *sr;
++	char *w;
++
++	sr = xcalloc(1, sizeof(*sr));
++	for (w = dl_next(line); w != line ; w = dl_next(w)) {
++		if (strncasecmp(w, "name=", 5) == 0) {
++			char *devname = w + 5;
++
++			if (strncmp(devname, "/dev/md/", 8) == 0) {
++				if (sr->devname)
++					pr_err("Only give one device per SYSFS line: %s\n",
++						devname);
++				else
++					sr->devname = xstrdup(devname);
++			} else {
++				pr_err("%s is an invalid name for an md device - ignored.\n",
++				       devname);
++			}
++		} else if (strncasecmp(w, "uuid=", 5) == 0) {
++			char *uuid = w + 5;
++
++			if (sr->uuid_set) {
++				pr_err("Only give one uuid per SYSFS line: %s\n",
++					uuid);
++			} else {
++				if (parse_uuid(w + 5, sr->uuid) &&
++				    memcmp(sr->uuid, uuid_zero,
++					   sizeof(int[4])) != 0)
++					sr->uuid_set = 1;
++				else
++					pr_err("Invalid uuid: %s\n", uuid);
++			}
++		} else {
++			struct sysfs_entry *prop;
++
++			char *sep = strchr(w, '=');
++
++			if (sep == NULL || *(sep + 1) == 0) {
++				pr_err("Cannot parse \"%s\" - ignoring.\n", w);
++				continue;
++			}
++
++			prop = xmalloc(sizeof(*prop));
++			prop->value = xstrdup(sep + 1);
++			*sep = 0;
++			prop->name = xstrdup(w);
++			prop->next = sr->entry;
++			sr->entry = prop;
++		}
++	}
++
++	if (!sr->devname && !sr->uuid_set) {
++		pr_err("Device name not found in sysfs config entry - ignoring.\n");
++		sysfs_rule_free(sr);
++		return;
++	}
++
++	sr->next = sysfs_rules;
++	sysfs_rules = sr;
++}
+-- 
+2.7.5
+
diff --git a/SOURCES/0031-mdadm.h-include-sysmacros.h-unconditionally.patch b/SOURCES/0031-mdadm.h-include-sysmacros.h-unconditionally.patch
new file mode 100644
index 0000000..3ef846a
--- /dev/null
+++ b/SOURCES/0031-mdadm.h-include-sysmacros.h-unconditionally.patch
@@ -0,0 +1,34 @@
+From 452dc4d13a012cdcb05088c0dbc699959c4d6c73 Mon Sep 17 00:00:00 2001
+From: Baruch Siach <baruch@tkos.co.il>
+Date: Tue, 6 Aug 2019 16:05:23 +0300
+Subject: [RHEL7.8 PATCH V2 31/47] mdadm.h: include sysmacros.h unconditionally
+
+musl libc now also requires sys/sysmacros.h for the major/minor macros.
+All supported libc implementations carry sys/sysmacros.h, including
+diet-libc, klibc, and uclibc-ng.
+
+Cc: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index c36d7fd..d61a9ca 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -45,10 +45,8 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
+ #include	<errno.h>
+ #include	<string.h>
+ #include	<syslog.h>
+-#ifdef __GLIBC__
+ /* Newer glibc requires sys/sysmacros.h directly for makedev() */
+ #include	<sys/sysmacros.h>
+-#endif
+ #ifdef __dietlibc__
+ #include	<strings.h>
+ /* dietlibc has deprecated random and srandom!! */
+-- 
+2.7.5
+
diff --git a/SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch b/SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch
new file mode 100644
index 0000000..bf58eb9
--- /dev/null
+++ b/SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch
@@ -0,0 +1,161 @@
+From d11abe4bd5cad39803726ddff1888674e417bda5 Mon Sep 17 00:00:00 2001
+From: Coly Li <colyli@suse.de>
+Date: Wed, 31 Jul 2019 13:29:29 +0800
+Subject: [RHEL7.8 PATCH V2 32/47] mdadm: add --no-devices to avoid component
+ devices detail information
+
+When people assemble a md raid device with a large number of
+component deivces (e.g. 1500 DASD disks), the raid device detail
+information generated by 'mdadm --detail --export $devnode' is very
+large. It is because the detail information contains information of
+all the component disks (even the missing/failed ones).
+
+In such condition, when udev-md-raid-arrays.rules is triggered and
+internally calls "mdadm --detail --no-devices --export $devnode",
+user may observe systemd error message ""invalid message length". It
+is because the following on-stack raw message buffer in systemd code
+is not big enough,
+        systemd/src/libudev/libudev-monitor.c
+        _public_ struct udev_device *udev_monito ...
+                struct ucred *cred;
+                union {
+                        struct udev_monitor_netlink_header nlh;
+                        char raw[8192];
+                } buf;
+Even change size of raw[] from 8KB to larger size, it may still be not
+enough for detail message of a md raid device with much larger number of
+component devices.
+
+To fix this problem, an extra option '--no-devices' is added (the
+original idea is proposed by Neil Brown). When printing detailed
+information of a md raid device, if '--no-devices' is specified, then
+all component devices information will not be printed, then the output
+message size can be restricted to a small number, even with the systemd
+only has 8KB on-disk raw buffer, the md raid array udev rules can work
+correctly without failure message.
+
+Signed-off-by: Coly Li <colyli@suse.de>
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 24 ++++++++++++++++--------
+ ReadMe.c |  1 +
+ mdadm.c  |  4 ++++
+ mdadm.h  |  2 ++
+ 4 files changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index 20ea03a..ad60434 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -56,7 +56,7 @@ int Detail(char *dev, struct context *c)
+ 	 */
+ 	int fd = open(dev, O_RDONLY);
+ 	mdu_array_info_t array;
+-	mdu_disk_info_t *disks;
++	mdu_disk_info_t *disks = NULL;
+ 	int next;
+ 	int d;
+ 	time_t atime;
+@@ -280,7 +280,7 @@ int Detail(char *dev, struct context *c)
+ 			}
+ 			map_free(map);
+ 		}
+-		if (sra) {
++		if (!c->no_devices && sra) {
+ 			struct mdinfo *mdi;
+ 			for (mdi  = sra->devs; mdi; mdi = mdi->next) {
+ 				char *path;
+@@ -655,12 +655,17 @@ This is pretty boring
+ 			printf("\n\n");
+ 		}
+ 
+-		if (array.raid_disks)
+-			printf("    Number   Major   Minor   RaidDevice State\n");
+-		else
+-			printf("    Number   Major   Minor   RaidDevice\n");
++		if (!c->no_devices) {
++			if (array.raid_disks)
++				printf("    Number   Major   Minor   RaidDevice State\n");
++			else
++				printf("    Number   Major   Minor   RaidDevice\n");
++		}
+ 	}
+-	free(info);
++
++	/* if --no_devices specified, not print component devices info */
++	if (c->no_devices)
++		goto skip_devices_state;
+ 
+ 	for (d = 0; d < max_disks * 2; d++) {
+ 		char *dv;
+@@ -747,6 +752,8 @@ This is pretty boring
+ 		if (!c->brief)
+ 			printf("\n");
+ 	}
++
++skip_devices_state:
+ 	if (spares && c->brief && array.raid_disks)
+ 		printf(" spares=%d", spares);
+ 	if (c->brief && st && st->sb)
+@@ -766,8 +773,9 @@ This is pretty boring
+ 	    !enough(array.level, array.raid_disks, array.layout, 1, avail))
+ 		rv = 2;
+ 
+-	free(disks);
+ out:
++	free(info);
++	free(disks);
+ 	close(fd);
+ 	free(subarray);
+ 	free(avail);
+diff --git a/ReadMe.c b/ReadMe.c
+index 12ccf83..eaf1042 100644
+--- a/ReadMe.c
++++ b/ReadMe.c
+@@ -181,6 +181,7 @@ struct option long_options[] = {
+ 
+     /* For Detail/Examine */
+     {"brief",	  0, 0, Brief},
++    {"no-devices",0, 0, NoDevices},
+     {"export",	  0, 0, 'Y'},
+     {"sparc2.2",  0, 0, Sparc22},
+     {"test",      0, 0, 't'},
+diff --git a/mdadm.c b/mdadm.c
+index 25a1abd..1fb8086 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -159,6 +159,10 @@ int main(int argc, char *argv[])
+ 			c.brief = 1;
+ 			continue;
+ 
++		case NoDevices:
++			c.no_devices = 1;
++			continue;
++
+ 		case 'Y': c.export++;
+ 			continue;
+ 
+diff --git a/mdadm.h b/mdadm.h
+index d61a9ca..43b07d5 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -440,6 +440,7 @@ enum special_options {
+ 	NoSharing,
+ 	HelpOptions,
+ 	Brief,
++	NoDevices,
+ 	ManageOpt,
+ 	Add,
+ 	AddSpare,
+@@ -550,6 +551,7 @@ struct context {
+ 	int	runstop;
+ 	int	verbose;
+ 	int	brief;
++	int	no_devices;
+ 	int	force;
+ 	char	*homehost;
+ 	int	require_homehost;
+-- 
+2.7.5
+
diff --git a/SOURCES/0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch b/SOURCES/0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch
new file mode 100644
index 0000000..53463f0
--- /dev/null
+++ b/SOURCES/0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch
@@ -0,0 +1,42 @@
+From 1a52f1fc0266d438c996789d4addbfac999a6139 Mon Sep 17 00:00:00 2001
+From: Coly Li <colyli@suse.de>
+Date: Wed, 31 Jul 2019 13:29:30 +0800
+Subject: [RHEL7.8 PATCH V2 33/47] udev: add --no-devices option for calling
+ 'mdadm --detail'
+
+When creating symlink of a md raid device, the detailed information of
+component disks are unnecessary for rule udev-md-raid-arrays.rules. For
+md raid devices with huge number of component disks (e.g. 1500 DASD
+disks), the detail information of component devices can be very large
+and exceed udev monitor's on-stack message buffer.
+
+This patch adds '--no-devices' option when calling mdadm by,
+IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode"
+
+Now the detailed output won't include component disks information,
+and the error message "invalid message length" reported by systemd can
+be removed.
+
+Signed-off-by: Coly Li <colyli@suse.de>
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ udev-md-raid-arrays.rules | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
+index 5b99d58..d391665 100644
+--- a/udev-md-raid-arrays.rules
++++ b/udev-md-raid-arrays.rules
+@@ -17,7 +17,7 @@ TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end"
+ ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end"
+ LABEL="md_ignore_state"
+ 
+-IMPORT{program}="BINDIR/mdadm --detail --export $devnode"
++IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode"
+ ENV{DEVTYPE}=="disk", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}", OPTIONS+="string_escape=replace"
+ ENV{DEVTYPE}=="disk", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}"
+ ENV{DEVTYPE}=="disk", ENV{MD_DEVNAME}=="?*", SYMLINK+="md/$env{MD_DEVNAME}"
+-- 
+2.7.5
+
diff --git a/SOURCES/0034-imsm-close-removed-drive-fd.patch b/SOURCES/0034-imsm-close-removed-drive-fd.patch
new file mode 100644
index 0000000..9abd879
--- /dev/null
+++ b/SOURCES/0034-imsm-close-removed-drive-fd.patch
@@ -0,0 +1,44 @@
+From 91c97c5432028875db5f8abeddb5cb5f31902001 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Mon, 15 Jul 2019 09:25:35 +0200
+Subject: [RHEL7.8 PATCH V2 34/47] imsm: close removed drive fd.
+
+When member drive fails, managemon prepares metadata update and adds
+the drive to disk_mgmt_list with DISK_REMOVE flag. It fills only
+minor and major. It is enough to recognize the device later.
+
+Monitor thread while processing this update will remove the drive from
+super only if it is a spare. It never removes failed member from
+disks list. As a result, it still keeps opened descriptor to
+non-existing device.
+
+If removed drive is not a spare fill fd in disk_cfg structure
+(prepared by managemon), monitor will close fd during freeing it.
+
+Also set this drive fd to -1 in super to avoid double closing because
+monitor will close the fd (if needed) while replacing removed drive
+in array.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/super-intel.c b/super-intel.c
+index d7e8a65..a103a3f 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -9200,6 +9200,9 @@ static int add_remove_disk_update(struct intel_super *super)
+ 					remove_disk_super(super,
+ 							  disk_cfg->major,
+ 							  disk_cfg->minor);
++				} else {
++					disk_cfg->fd = disk->fd;
++					disk->fd = -1;
+ 				}
+ 			}
+ 			/* release allocate disk structure */
+-- 
+2.7.5
+
diff --git a/SOURCES/0035-mdadm-check-value-returned-by-snprintf-against-error.patch b/SOURCES/0035-mdadm-check-value-returned-by-snprintf-against-error.patch
new file mode 100644
index 0000000..8395e0b
--- /dev/null
+++ b/SOURCES/0035-mdadm-check-value-returned-by-snprintf-against-error.patch
@@ -0,0 +1,46 @@
+From fd5b09c9a9107f0393ce194c4aac6e7b8f163e85 Mon Sep 17 00:00:00 2001
+From: Krzysztof Smolinski <krzysztof.smolinski@intel.com>
+Date: Fri, 16 Aug 2019 11:06:17 +0200
+Subject: [RHEL7.8 PATCH V2 35/47] mdadm: check value returned by snprintf
+ against errors
+
+GCC 8 checks possible truncation during snprintf more strictly
+than GCC 7 which result in compilation errors. To fix this
+problem checking result of snprintf against errors has been added.
+
+Signed-off-by: Krzysztof Smolinski <krzysztof.smolinski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ sysfs.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/sysfs.c b/sysfs.c
+index c313781..2995713 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -1023,12 +1023,20 @@ int sysfs_rules_apply_check(const struct mdinfo *sra,
+ 	char dname[MAX_SYSFS_PATH_LEN];
+ 	char resolved_path[PATH_MAX];
+ 	char resolved_dir[PATH_MAX];
++	int result;
+ 
+ 	if (sra == NULL || ent == NULL)
+ 		return -1;
+ 
+-	snprintf(dname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md/", sra->sys_name);
+-	snprintf(fname, MAX_SYSFS_PATH_LEN, "%s/%s", dname, ent->name);
++	result = snprintf(dname, MAX_SYSFS_PATH_LEN,
++			  "/sys/block/%s/md/", sra->sys_name);
++	if (result < 0 || result >= MAX_SYSFS_PATH_LEN)
++		return -1;
++
++	result = snprintf(fname, MAX_SYSFS_PATH_LEN,
++			  "%s/%s", dname, ent->name);
++	if (result < 0 || result >= MAX_SYSFS_PATH_LEN)
++		return -1;
+ 
+ 	if (realpath(fname, resolved_path) == NULL ||
+ 	    realpath(dname, resolved_dir) == NULL)
+-- 
+2.7.5
+
diff --git a/SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch b/SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch
new file mode 100644
index 0000000..3a26484
--- /dev/null
+++ b/SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch
@@ -0,0 +1,163 @@
+From 43ebc9105e9dafe5145b3e801c05da4736bf6e02 Mon Sep 17 00:00:00 2001
+From: "Guilherme G. Piccoli" <gpiccoli@canonical.com>
+Date: Tue, 3 Sep 2019 16:49:01 -0300
+Subject: [RHEL7.8 PATCH V2 36/47] mdadm: Introduce new array state 'broken'
+ for raid0/linear
+
+Currently if a md raid0/linear array gets one or more members removed while
+being mounted, kernel keeps showing state 'clean' in the 'array_state'
+sysfs attribute. Despite udev signaling the member device is gone, 'mdadm'
+cannot issue the STOP_ARRAY ioctl successfully, given the array is mounted.
+
+Nothing else hints that something is wrong (except that the removed devices
+don't show properly in the output of mdadm 'detail' command). There is no
+other property to be checked, and if user is not performing reads/writes
+to the array, even kernel log is quiet and doesn't give a clue about the
+missing member.
+
+This patch is the mdadm counterpart of kernel new array state 'broken'.
+The 'broken' state mimics the state 'clean' in every aspect, being useful
+only to distinguish if an array has some member missing. All necessary
+paths in mdadm were changed to deal with 'broken' state, and in case the
+tool runs in a kernel that is not updated, it'll work normally, i.e., it
+doesn't require the 'broken' state in order to work.
+Also, this patch changes the way the array state is showed in the 'detail'
+command (for raid0/linear only) - now it takes the 'array_state' sysfs
+attribute into account instead of only rely in the MD_SB_CLEAN flag.
+
+Cc: Jes Sorensen <jes.sorensen@gmail.com>
+Cc: NeilBrown <neilb@suse.de>
+Cc: Song Liu <songliubraving@fb.com>
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c  | 14 ++++++++++++--
+ Monitor.c |  8 ++++++--
+ maps.c    |  1 +
+ mdadm.h   |  1 +
+ mdmon.h   |  2 +-
+ monitor.c |  4 ++--
+ 6 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index ad60434..3e61e37 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -81,6 +81,7 @@ int Detail(char *dev, struct context *c)
+ 	int external;
+ 	int inactive;
+ 	int is_container = 0;
++	char *arrayst;
+ 
+ 	if (fd < 0) {
+ 		pr_err("cannot open %s: %s\n",
+@@ -485,9 +486,18 @@ int Detail(char *dev, struct context *c)
+ 			else
+ 				st = ", degraded";
+ 
++			if (array.state & (1 << MD_SB_CLEAN)) {
++				if ((array.level == 0) ||
++				    (array.level == LEVEL_LINEAR))
++					arrayst = map_num(sysfs_array_states,
++							  sra->array_state);
++				else
++					arrayst = "clean";
++			} else
++				arrayst = "active";
++
+ 			printf("             State : %s%s%s%s%s%s \n",
+-			       (array.state & (1 << MD_SB_CLEAN)) ?
+-			       "clean" : "active", st,
++			       arrayst, st,
+ 			       (!e || (e->percent < 0 &&
+ 				       e->percent != RESYNC_PENDING &&
+ 				       e->percent != RESYNC_DELAYED)) ?
+diff --git a/Monitor.c b/Monitor.c
+index 036103f..b527165 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -1055,8 +1055,11 @@ int Wait(char *dev)
+ 	}
+ }
+ 
++/* The state "broken" is used only for RAID0/LINEAR - it's the same as
++ * "clean", but used in case the array has one or more members missing.
++ */
+ static char *clean_states[] = {
+-	"clear", "inactive", "readonly", "read-auto", "clean", NULL };
++	"clear", "inactive", "readonly", "read-auto", "clean", "broken", NULL };
+ 
+ int WaitClean(char *dev, int verbose)
+ {
+@@ -1116,7 +1119,8 @@ int WaitClean(char *dev, int verbose)
+ 			rv = read(state_fd, buf, sizeof(buf));
+ 			if (rv < 0)
+ 				break;
+-			if (sysfs_match_word(buf, clean_states) <= 4)
++			if (sysfs_match_word(buf, clean_states) <
++			    (int)ARRAY_SIZE(clean_states) - 1)
+ 				break;
+ 			rv = sysfs_wait(state_fd, &delay);
+ 			if (rv < 0 && errno != EINTR)
+diff --git a/maps.c b/maps.c
+index 02a0474..49b7f2c 100644
+--- a/maps.c
++++ b/maps.c
+@@ -150,6 +150,7 @@ mapping_t sysfs_array_states[] = {
+ 	{ "read-auto", ARRAY_READ_AUTO },
+ 	{ "clean", ARRAY_CLEAN },
+ 	{ "write-pending", ARRAY_WRITE_PENDING },
++	{ "broken", ARRAY_BROKEN },
+ 	{ NULL, ARRAY_UNKNOWN_STATE }
+ };
+ 
+diff --git a/mdadm.h b/mdadm.h
+index 43b07d5..c88ceab 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -373,6 +373,7 @@ struct mdinfo {
+ 		ARRAY_ACTIVE,
+ 		ARRAY_WRITE_PENDING,
+ 		ARRAY_ACTIVE_IDLE,
++		ARRAY_BROKEN,
+ 		ARRAY_UNKNOWN_STATE,
+ 	} array_state;
+ 	struct md_bb bb;
+diff --git a/mdmon.h b/mdmon.h
+index 818367c..b3d72ac 100644
+--- a/mdmon.h
++++ b/mdmon.h
+@@ -21,7 +21,7 @@
+ extern const char Name[];
+ 
+ enum array_state { clear, inactive, suspended, readonly, read_auto,
+-		   clean, active, write_pending, active_idle, bad_word};
++		   clean, active, write_pending, active_idle, broken, bad_word};
+ 
+ enum sync_action { idle, reshape, resync, recover, check, repair, bad_action };
+ 
+diff --git a/monitor.c b/monitor.c
+index 81537ed..e0d3be6 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -26,7 +26,7 @@
+ 
+ static char *array_states[] = {
+ 	"clear", "inactive", "suspended", "readonly", "read-auto",
+-	"clean", "active", "write-pending", "active-idle", NULL };
++	"clean", "active", "write-pending", "active-idle", "broken", NULL };
+ static char *sync_actions[] = {
+ 	"idle", "reshape", "resync", "recover", "check", "repair", NULL
+ };
+@@ -476,7 +476,7 @@ static int read_and_act(struct active_array *a, fd_set *fds)
+ 		a->next_state = clean;
+ 		ret |= ARRAY_DIRTY;
+ 	}
+-	if (a->curr_state == clean) {
++	if ((a->curr_state == clean) || (a->curr_state == broken)) {
+ 		a->container->ss->set_array_state(a, 1);
+ 	}
+ 	if (a->curr_state == active ||
+-- 
+2.7.5
+
diff --git a/SOURCES/0037-mdadm-force-a-uuid-swap-on-big-endian.patch b/SOURCES/0037-mdadm-force-a-uuid-swap-on-big-endian.patch
new file mode 100644
index 0000000..6c47ae8
--- /dev/null
+++ b/SOURCES/0037-mdadm-force-a-uuid-swap-on-big-endian.patch
@@ -0,0 +1,40 @@
+From 2c2d9c48d2daf0d78d20494c3779c0f6dc4bfa75 Mon Sep 17 00:00:00 2001
+From: Nigel Croxon <ncroxon@redhat.com>
+Date: Tue, 24 Sep 2019 11:39:24 -0400
+Subject: [RHEL7.8 PATCH V2 37/47] mdadm: force a uuid swap on big endian
+
+The code path for metadata 0.90 calls a common routine
+fname_from_uuid that uses metadata 1.2. The code expects member
+swapuuid to be setup and usable. But it is only setup when using
+metadata 1.2. Since the metadata 0.90 did not create swapuuid
+and set it. The test (st->ss == &super1) ? 1 : st->ss->swapuuid
+fails. The swapuuid is set at compile time based on byte order.
+Any call based on metadata 0.90 and on big endian processors,
+the --export uuid will be incorrect.
+
+Signed-Off-by: Nigel Croxon <ncroxon@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ util.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/util.c b/util.c
+index c26cf5f..64dd409 100644
+--- a/util.c
++++ b/util.c
+@@ -685,8 +685,12 @@ char *fname_from_uuid(struct supertype *st, struct mdinfo *info,
+ 	// work, but can't have it set if we want this printout to match
+ 	// all the other uuid printouts in super1.c, so we force swapuuid
+ 	// to 1 to make our printout match the rest of super1
++#if __BYTE_ORDER == BIG_ENDIAN
++	return __fname_from_uuid(info->uuid, 1, buf, sep);
++#else
+ 	return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 :
+ 				 st->ss->swapuuid, buf, sep);
++#endif
+ }
+ 
+ int check_ext2(int fd, char *name)
+-- 
+2.7.5
+
diff --git a/SOURCES/0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch b/SOURCES/0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch
new file mode 100644
index 0000000..0e2f390
--- /dev/null
+++ b/SOURCES/0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch
@@ -0,0 +1,99 @@
+From e53cb968691d9e40d83caf5570da3bb7b83c64e1 Mon Sep 17 00:00:00 2001
+From: Guoqing Jiang <gqjiang@suse.com>
+Date: Fri, 31 May 2019 10:10:00 +0800
+Subject: [RHEL7.8 PATCH V2 38/47] mdadm/md.4: add the descriptions for bitmap
+ sysfs nodes
+
+The sysfs nodes under bitmap are not recorded in md.4,
+add them based on md.rst and kernel source code.
+
+Cc: NeilBrown <neilb@suse.com>
+Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ md.4 | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 69 insertions(+)
+
+diff --git a/md.4 b/md.4
+index 3a1d677..e86707a 100644
+--- a/md.4
++++ b/md.4
+@@ -1101,6 +1101,75 @@ stripe that requires some "prereading".  For fairness this defaults to
+ maximizes sequential-write throughput at the cost of fairness to threads
+ doing small or random writes.
+ 
++.TP
++.B md/bitmap/backlog
++The value stored in the file only has any effect on RAID1 when write-mostly
++devices are active, and write requests to those devices are proceed in the
++background.
++
++This variable sets a limit on the number of concurrent background writes,
++the valid values are 0 to 16383, 0 means that write-behind is not allowed,
++while any other number means it can happen.  If there are more write requests
++than the number, new writes will by synchronous.
++
++.TP
++.B md/bitmap/can_clear
++This is for externally managed bitmaps, where the kernel writes the bitmap
++itself, but metadata describing the bitmap is managed by mdmon or similar.
++
++When the array is degraded, bits mustn't be cleared. When the array becomes
++optimal again, bit can be cleared, but first the metadata needs to record
++the current event count. So md sets this to 'false' and notifies mdmon,
++then mdmon updates the metadata and writes 'true'.
++
++There is no code in mdmon to actually do this, so maybe it doesn't even
++work.
++
++.TP
++.B md/bitmap/chunksize
++The bitmap chunksize can only be changed when no bitmap is active, and
++the value should be power of 2 and at least 512.
++
++.TP
++.B md/bitmap/location
++This indicates where the write-intent bitmap for the array is stored.
++It can be "none" or "file" or a signed offset from the array metadata
++- measured in sectors. You cannot set a file by writing here - that can
++only be done with the SET_BITMAP_FILE ioctl.
++
++Write 'none' to 'bitmap/location' will clear bitmap, and the previous
++location value must be write to it to restore bitmap.
++
++.TP
++.B md/bitmap/max_backlog_used
++This keeps track of the maximum number of concurrent write-behind requests
++for an md array, writing any value to this file will clear it.
++
++.TP
++.B md/bitmap/metadata
++This can be 'internal' or 'clustered' or 'external'. 'internal' is set
++by default, which means the metadata for bitmap is stored in the first 256
++bytes of the bitmap space. 'clustered' means separate bitmap metadata are
++used for each cluster node. 'external' means that bitmap metadata is managed
++externally to the kernel.
++
++.TP
++.B md/bitmap/space
++This shows the space (in sectors) which is available at md/bitmap/location,
++and allows the kernel to know when it is safe to resize the bitmap to match
++a resized array. It should big enough to contain the total bytes in the bitmap.
++
++For 1.0 metadata, assume we can use up to the superblock if before, else
++to 4K beyond superblock. For other metadata versions, assume no change is
++possible.
++
++.TP
++.B md/bitmap/time_base
++This shows the time (in seconds) between disk flushes, and is used to looking
++for bits in the bitmap to be cleared.
++
++The default value is 5 seconds, and it should be an unsigned long value.
++
+ .SS KERNEL PARAMETERS
+ 
+ The md driver recognised several different kernel parameters.
+-- 
+2.7.5
+
diff --git a/SOURCES/0039-Init-devlist-as-an-array.patch b/SOURCES/0039-Init-devlist-as-an-array.patch
new file mode 100644
index 0000000..12c7fba
--- /dev/null
+++ b/SOURCES/0039-Init-devlist-as-an-array.patch
@@ -0,0 +1,35 @@
+From 8063fd0f9e8abd718bd65928c19bc607cee5acd8 Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Mon, 30 Sep 2019 19:47:59 +0800
+Subject: [RHEL7.8 PATCH V2 39/47] Init devlist as an array
+
+devlist is an string. It will change to an array if there is disk that
+is sbd disk. If one device is sbd, it runs devlist=().
+This line code changes devlist from a string to an array. If there is
+no sbd device, it can't run this line code. So it will still be a string.
+The later codes need an array, rather than an string. So init devlist
+as an array to fix this problem.
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ clustermd_tests/func.sh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/clustermd_tests/func.sh b/clustermd_tests/func.sh
+index 642cc96..801d604 100644
+--- a/clustermd_tests/func.sh
++++ b/clustermd_tests/func.sh
+@@ -39,6 +39,9 @@ fetch_devlist()
+ 		devlist=($(ls /dev/disk/by-path/*$ISCSI_ID*))
+ 	fi
+ 	# sbd disk cannot use in testing
++	# Init devlist as an array
++	i=''
++	devlist=(${devlist[@]#$i})
+ 	for i in ${devlist[@]}
+ 	do
+ 		sbd -d $i dump &> /dev/null
+-- 
+2.7.5
+
diff --git a/SOURCES/0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch b/SOURCES/0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch
new file mode 100644
index 0000000..c47173d
--- /dev/null
+++ b/SOURCES/0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch
@@ -0,0 +1,31 @@
+From 611093148574164fcf4f24f8c076d09473f655d7 Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Mon, 30 Sep 2019 19:48:00 +0800
+Subject: [RHEL7.8 PATCH V2 40/47] Don't need to check recovery after re-add
+ when no I/O writes to raid
+
+If there is no write I/O between removing member disk and re-add it, there is no
+recovery after re-adding member disk.
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ clustermd_tests/02r1_Manage_re-add | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/clustermd_tests/02r1_Manage_re-add b/clustermd_tests/02r1_Manage_re-add
+index dd9c416..d0d13e5 100644
+--- a/clustermd_tests/02r1_Manage_re-add
++++ b/clustermd_tests/02r1_Manage_re-add
+@@ -9,8 +9,6 @@ check all state UU
+ check all dmesg
+ mdadm --manage $md0 --fail $dev0 --remove $dev0
+ mdadm --manage $md0 --re-add $dev0
+-check $NODE1 recovery
+-check all wait
+ check all state UU
+ check all dmesg
+ stop_md all $md0
+-- 
+2.7.5
+
diff --git a/SOURCES/0041-udev-allow-for-udev-attribute-reading-bug.patch b/SOURCES/0041-udev-allow-for-udev-attribute-reading-bug.patch
new file mode 100644
index 0000000..099b937
--- /dev/null
+++ b/SOURCES/0041-udev-allow-for-udev-attribute-reading-bug.patch
@@ -0,0 +1,47 @@
+From 7bd59e7926c6921121087eb067befaa896c900a4 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 18 Sep 2019 15:12:55 +1000
+Subject: [RHEL7.8 PATCH V2 41/47] udev: allow for udev attribute reading bug.
+
+There is a bug in udev (which will hopefully get fixed, but
+we should allow for it anways).
+When reading a sysfs attribute, it first reads the whole
+value of the attribute, then reads again expecting to get
+a read of 0 bytes, like you would with an ordinary file.
+If the sysfs attribute changed between these two reads, it can
+get a mixture of two values.
+
+In particular, if it reads when 'array_state' is changing from
+'clear' to 'inactive', it can find the value as "clear\nve".
+
+This causes the test for "|clear|active" to fail, so systemd is allowed
+to think that the array is ready - when it isn't.
+
+So change the pattern to allow for this but adding a wildcard at
+the end.
+Also don't allow for an empty string - reading array_state will
+never return an empty string - if it exists at all, it will be
+non-empty.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ udev-md-raid-arrays.rules | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
+index d391665..c8fa8e8 100644
+--- a/udev-md-raid-arrays.rules
++++ b/udev-md-raid-arrays.rules
+@@ -14,7 +14,7 @@ ENV{DEVTYPE}=="partition", GOTO="md_ignore_state"
+ # never leave state 'inactive'
+ 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/array_state}=="clear*|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end"
+ LABEL="md_ignore_state"
+ 
+ IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode"
+-- 
+2.7.5
+
diff --git a/SOURCES/0042-imsm-save-current_vol-number.patch b/SOURCES/0042-imsm-save-current_vol-number.patch
new file mode 100644
index 0000000..5699f84
--- /dev/null
+++ b/SOURCES/0042-imsm-save-current_vol-number.patch
@@ -0,0 +1,40 @@
+From b6180160f78f0182b296bdceed6419b26a6fccc7 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Fri, 4 Oct 2019 12:07:28 +0200
+Subject: [RHEL7.8 PATCH V2 42/47] imsm: save current_vol number
+
+The imsm container_content routine will set curr_volume index in super
+for getting volume information. This flag has never been restored to
+original value, later other function may rely on it.
+
+Restore this flag to original value.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/super-intel.c b/super-intel.c
+index a103a3f..e02bbd7 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7826,6 +7826,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 	int sb_errors = 0;
+ 	struct dl *d;
+ 	int spare_disks = 0;
++	int current_vol = super->current_vol;
+ 
+ 	/* do not assemble arrays when not all attributes are supported */
+ 	if (imsm_check_attributes(mpb->attributes) == 0) {
+@@ -7993,6 +7994,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		rest = this;
+ 	}
+ 
++	super->current_vol = current_vol;
+ 	return rest;
+ }
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0043-imsm-allow-to-specify-second-volume-size.patch b/SOURCES/0043-imsm-allow-to-specify-second-volume-size.patch
new file mode 100644
index 0000000..ba34896
--- /dev/null
+++ b/SOURCES/0043-imsm-allow-to-specify-second-volume-size.patch
@@ -0,0 +1,50 @@
+From 1a1ced1e2e64a6b4b349a3fb559f6b39e4cf7103 Mon Sep 17 00:00:00 2001
+From: Krzysztof Smolinski <krzysztof.smolinski@intel.com>
+Date: Fri, 8 Nov 2019 11:59:11 +0100
+Subject: [RHEL7.8 PATCH V2 43/47] imsm: allow to specify second volume size
+
+Removed checks which limited second volume size only to max value (the
+largest size that fits on all current drives). It is now permitted
+to create second volume with size lower then maximum possible.
+
+Signed-off-by: Krzysztof Smolinski <krzysztof.smolinski@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index e02bbd7..713058c 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7298,11 +7298,8 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
+ 
+ 	maxsize = merge_extents(super, i);
+ 
+-	if (!check_env("IMSM_NO_PLATFORM") &&
+-	    mpb->num_raid_devs > 0 && size && size != maxsize) {
+-		pr_err("attempting to create a second volume with size less then remaining space. Aborting...\n");
+-		return 0;
+-	}
++	if (mpb->num_raid_devs > 0 && size && size != maxsize)
++		pr_err("attempting to create a second volume with size less then remaining space.\n");
+ 
+ 	if (maxsize < size || maxsize == 0) {
+ 		if (verbose) {
+@@ -7393,11 +7390,8 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
+ 		}
+ 		maxsize = size;
+ 	}
+-	if (!check_env("IMSM_NO_PLATFORM") &&
+-	    mpb->num_raid_devs > 0 && size && size != maxsize) {
+-		pr_err("attempting to create a second volume with size less then remaining space. Aborting...\n");
+-		return 0;
+-	}
++	if (mpb->num_raid_devs > 0 && size && size != maxsize)
++		pr_err("attempting to create a second volume with size less then remaining space.\n");
+ 	cnt = 0;
+ 	for (dl = super->disks; dl; dl = dl->next)
+ 		if (dl->e)
+-- 
+2.7.5
+
diff --git a/SOURCES/0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch b/SOURCES/0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch
new file mode 100644
index 0000000..bff9eaa
--- /dev/null
+++ b/SOURCES/0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch
@@ -0,0 +1,45 @@
+From 6636788aaf4ec0cacaefb6e77592e4a68e70a957 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 30 Oct 2019 10:32:41 +1100
+Subject: [RHEL7.8 PATCH V2 44/47] mdcheck: when mdcheck_start is enabled,
+ enable mdcheck_continue too.
+
+mdcheck_continue continues a regular array scan that was started by
+mdcheck_start.
+mdcheck_start will ensure that mdcheck_continue is active.
+Howver if you reboot after a check has started, but before it finishes,
+then mdcheck_continue won't cause it to continue, because nothing
+starts it on boot.
+
+So add an install option for mdcheck_contine, and make sure it
+gets enabled when mdcheck_start is enabled.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ systemd/mdcheck_continue.timer | 2 ++
+ systemd/mdcheck_start.timer    | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/systemd/mdcheck_continue.timer b/systemd/mdcheck_continue.timer
+index 3ccfd78..dba1074 100644
+--- a/systemd/mdcheck_continue.timer
++++ b/systemd/mdcheck_continue.timer
+@@ -11,3 +11,5 @@ Description=MD array scrubbing - continuation
+ [Timer]
+ OnCalendar= 1:05:00
+ 
++[Install]
++WantedBy= mdmonitor.service
+diff --git a/systemd/mdcheck_start.timer b/systemd/mdcheck_start.timer
+index 6480736..9e7e02a 100644
+--- a/systemd/mdcheck_start.timer
++++ b/systemd/mdcheck_start.timer
+@@ -13,3 +13,4 @@ OnCalendar=Sun *-*-1..7 1:00:00
+ 
+ [Install]
+ WantedBy= mdmonitor.service
++Also= mdcheck_continue.timer
+-- 
+2.7.5
+
diff --git a/SOURCES/0045-mdcheck-use-to-pass-variable-to-mdcheck.patch b/SOURCES/0045-mdcheck-use-to-pass-variable-to-mdcheck.patch
new file mode 100644
index 0000000..6b13d18
--- /dev/null
+++ b/SOURCES/0045-mdcheck-use-to-pass-variable-to-mdcheck.patch
@@ -0,0 +1,51 @@
+From 4ca799c581703d4d0ad840833c037c2fff088ca7 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 30 Oct 2019 10:32:41 +1100
+Subject: [RHEL7.8 PATCH V2 45/47] mdcheck: use ${} to pass variable to mdcheck
+
+$MDADM_CHECK_DURATION allows the value to be split on spaces.
+${MDADM_CHECK_DURATION} avoids such splitting.
+
+Making this change removes the need for double quoting when setting
+the default Environment, and means that double quoting isn't needed
+in the EnvironmentFile.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ systemd/mdcheck_continue.service | 5 ++---
+ systemd/mdcheck_start.service    | 4 ++--
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
+index 592c607..deac695 100644
+--- a/systemd/mdcheck_continue.service
++++ b/systemd/mdcheck_continue.service
+@@ -11,8 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_*
+ 
+ [Service]
+ Type=oneshot
+-Environment= MDADM_CHECK_DURATION='"6 hours"'
++Environment= MDADM_CHECK_DURATION="6 hours"
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+-ExecStart=/usr/share/mdadm/mdcheck --continue --duration $MDADM_CHECK_DURATION
+-
++ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
+diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
+index 812141b..f17f1aa 100644
+--- a/systemd/mdcheck_start.service
++++ b/systemd/mdcheck_start.service
+@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer
+ 
+ [Service]
+ Type=oneshot
+-Environment= MDADM_CHECK_DURATION='"6 hours"'
++Environment= MDADM_CHECK_DURATION="6 hours"
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+-ExecStart=/usr/share/mdadm/mdcheck --duration $MDADM_CHECK_DURATION
++ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
+-- 
+2.7.5
+
diff --git a/SOURCES/0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch b/SOURCES/0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch
new file mode 100644
index 0000000..d88de9e
--- /dev/null
+++ b/SOURCES/0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch
@@ -0,0 +1,29 @@
+From 85b83a7920bca5b93d2458f093f2c640a130614c Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Wed, 30 Oct 2019 10:32:41 +1100
+Subject: [RHEL7.8 PATCH V2 46/47] SUSE-mdadm_env.sh: handle
+ MDADM_CHECK_DURATION
+
+The suse sysconfig/mdadm allows MDADM_CHECK_DURATION
+to be set, but it is currently ignored.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ systemd/SUSE-mdadm_env.sh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/systemd/SUSE-mdadm_env.sh b/systemd/SUSE-mdadm_env.sh
+index 10b2e74..c13b48a 100644
+--- a/systemd/SUSE-mdadm_env.sh
++++ b/systemd/SUSE-mdadm_env.sh
+@@ -43,3 +43,6 @@ fi
+ 
+ mkdir -p /run/sysconfig
+ echo "MDADM_MONITOR_ARGS=$MDADM_RAIDDEVICES $MDADM_DELAY $MDADM_MAIL $MDADM_PROGRAM $MDADM_SCAN $MDADM_SEND_MAIL $MDADM_CONFIG" > /run/sysconfig/mdadm
++if [ -n "$MDADM_CHECK_DURATION" ]; then
++ echo "MDADM_CHECK_DURATION=$MDADM_CHECK_DURATION" >> /run/sysconfig/mdadm
++fi
+-- 
+2.7.5
+
diff --git a/SOURCES/0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch b/SOURCES/0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch
new file mode 100644
index 0000000..3eda582
--- /dev/null
+++ b/SOURCES/0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch
@@ -0,0 +1,122 @@
+From 761e3bd9f5e3aafa95ad3ae50a637dc67c8774f0 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 31 Oct 2019 15:15:38 +1100
+Subject: [RHEL7.8 PATCH V2 47/47] super-intel: don't mark structs 'packed'
+ unnecessarily
+
+super-intel marks a number of structures 'packed', but this
+doesn't change the layout - they are already well organized.
+
+This is a problem a gcc warns when code takes the address
+of a field in a packet struct - as super-intel sometimes does.
+
+So remove the marking where isn't needed.
+Do ensure this does introduce a regression, add a compile-time
+assertion that the size of the structure is exactly the value
+it had before the 'packed' notation was removed.
+
+Note that a couple of structure do need to be packed.
+As the address of fields is never taken, that is safe.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Acked-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 32 ++++++++++++++++++++++++++------
+ 1 file changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 713058c..a7fbed4 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -96,6 +96,19 @@
+ 						   * mutliple PPL area
+ 						   */
+ 
++/*
++ * This macro let's us ensure that no-one accidentally
++ * changes the size of a struct
++ */
++#define ASSERT_SIZE(_struct, size) \
++static inline void __assert_size_##_struct(void)	\
++{							\
++	switch (0) {					\
++	case 0: break;					\
++	case (sizeof(struct _struct) == size): break;	\
++	}						\
++}
++
+ /* Disk configuration info. */
+ #define IMSM_MAX_DEVICES 255
+ struct imsm_disk {
+@@ -112,6 +125,7 @@ struct imsm_disk {
+ #define	IMSM_DISK_FILLERS	3
+ 	__u32 filler[IMSM_DISK_FILLERS]; /* 0xF5 - 0x107 MPB_DISK_FILLERS for future expansion */
+ };
++ASSERT_SIZE(imsm_disk, 48)
+ 
+ /* map selector for map managment
+  */
+@@ -146,7 +160,8 @@ struct imsm_map {
+ 	__u32 disk_ord_tbl[1];	/* disk_ord_tbl[num_members],
+ 				 * top byte contains some flags
+ 				 */
+-} __attribute__ ((packed));
++};
++ASSERT_SIZE(imsm_map, 52)
+ 
+ struct imsm_vol {
+ 	__u32 curr_migr_unit;
+@@ -169,7 +184,8 @@ struct imsm_vol {
+ 	__u32 filler[4];
+ 	struct imsm_map map[1];
+ 	/* here comes another one if migr_state */
+-} __attribute__ ((packed));
++};
++ASSERT_SIZE(imsm_vol, 84)
+ 
+ struct imsm_dev {
+ 	__u8  volume[MAX_RAID_SERIAL_LEN];
+@@ -220,7 +236,8 @@ struct imsm_dev {
+ #define IMSM_DEV_FILLERS 3
+ 	__u32 filler[IMSM_DEV_FILLERS];
+ 	struct imsm_vol vol;
+-} __attribute__ ((packed));
++};
++ASSERT_SIZE(imsm_dev, 164)
+ 
+ struct imsm_super {
+ 	__u8 sig[MAX_SIGNATURE_LENGTH];	/* 0x00 - 0x1F */
+@@ -248,7 +265,8 @@ struct imsm_super {
+ 	struct imsm_disk disk[1];	/* 0xD8 diskTbl[numDisks] */
+ 	/* here comes imsm_dev[num_raid_devs] */
+ 	/* here comes BBM logs */
+-} __attribute__ ((packed));
++};
++ASSERT_SIZE(imsm_super, 264)
+ 
+ #define BBM_LOG_MAX_ENTRIES 254
+ #define BBM_LOG_MAX_LBA_ENTRY_VAL 256		/* Represents 256 LBAs */
+@@ -269,7 +287,8 @@ struct bbm_log {
+ 	__u32 signature; /* 0xABADB10C */
+ 	__u32 entry_count;
+ 	struct bbm_log_entry marked_block_entries[BBM_LOG_MAX_ENTRIES];
+-} __attribute__ ((__packed__));
++};
++ASSERT_SIZE(bbm_log, 2040)
+ 
+ static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" };
+ 
+@@ -323,7 +342,8 @@ struct migr_record {
+ 				       * destination - high order 32 bits */
+ 	__u32 num_migr_units_hi;      /* Total num migration units-of-op
+ 				       * high order 32 bits */
+-} __attribute__ ((__packed__));
++};
++ASSERT_SIZE(migr_record, 64)
+ 
+ struct md_list {
+ 	/* usage marker:
+-- 
+2.7.5
+
diff --git a/SOURCES/0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch b/SOURCES/0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch
new file mode 100644
index 0000000..a106dd2
--- /dev/null
+++ b/SOURCES/0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch
@@ -0,0 +1,45 @@
+From e1512e7b7d060f0346738b237ea34eac21b29a26 Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Wed, 18 Dec 2019 14:46:21 +0800
+Subject: [RHEL8.2 PATCH 1/1] mdcheck service can't start succesfully because
+ of syntax error
+
+It reports error when starting mdcheck_start and mdcheck_continue service.
+Invalid environment assignment, ignoring: MDADM_CHECK_DURATION="6 hours"
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ systemd/mdcheck_continue.service | 2 +-
+ systemd/mdcheck_start.service    | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
+index deac695..aa02dde 100644
+--- a/systemd/mdcheck_continue.service
++++ b/systemd/mdcheck_continue.service
+@@ -11,7 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_*
+ 
+ [Service]
+ Type=oneshot
+-Environment= MDADM_CHECK_DURATION="6 hours"
++Environment= "MDADM_CHECK_DURATION=6 hours"
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+ ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
+diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
+index f17f1aa..da62d5f 100644
+--- a/systemd/mdcheck_start.service
++++ b/systemd/mdcheck_start.service
+@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer
+ 
+ [Service]
+ Type=oneshot
+-Environment= MDADM_CHECK_DURATION="6 hours"
++Environment= "MDADM_CHECK_DURATION=6 hours"
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+ ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
+-- 
+2.7.5
+
diff --git a/SOURCES/0049-Remove-last-traces-of-HOT_ADD_DISK.patch b/SOURCES/0049-Remove-last-traces-of-HOT_ADD_DISK.patch
new file mode 100644
index 0000000..e9e7674
--- /dev/null
+++ b/SOURCES/0049-Remove-last-traces-of-HOT_ADD_DISK.patch
@@ -0,0 +1,41 @@
+From 02af379337c73e751ad97c0fed9123121f8b4289 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 27 Nov 2019 10:19:54 -0500
+Subject: [RHEL8.2 PATCH 49/61] Remove last traces of HOT_ADD_DISK
+
+This ioctl is no longer used, so remove all references to it.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c | 2 --
+ md_u.h   | 1 -
+ 2 files changed, 3 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index ffe55f8..deeba2b 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1289,8 +1289,6 @@ int Manage_subdevs(char *devname, int fd,
+ 	/* Do something to each dev.
+ 	 * devmode can be
+ 	 *  'a' - add the device
+-	 *	   try HOT_ADD_DISK
+-	 *         If that fails EINVAL, try ADD_NEW_DISK
+ 	 *  'S' - add the device as a spare - don't try re-add
+ 	 *  'j' - add the device as a journal device
+ 	 *  'A' - re-add the device
+diff --git a/md_u.h b/md_u.h
+index 2d66d52..b30893c 100644
+--- a/md_u.h
++++ b/md_u.h
+@@ -28,7 +28,6 @@
+ #define ADD_NEW_DISK		_IOW (MD_MAJOR, 0x21, mdu_disk_info_t)
+ #define HOT_REMOVE_DISK		_IO (MD_MAJOR, 0x22)
+ #define SET_ARRAY_INFO		_IOW (MD_MAJOR, 0x23, mdu_array_info_t)
+-#define HOT_ADD_DISK		_IO (MD_MAJOR, 0x28)
+ #define SET_DISK_FAULTY		_IO (MD_MAJOR, 0x29)
+ #define SET_BITMAP_FILE		_IOW (MD_MAJOR, 0x2b, int)
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0050-Fix-up-a-few-formatting-issues.patch b/SOURCES/0050-Fix-up-a-few-formatting-issues.patch
new file mode 100644
index 0000000..f74c9b7
--- /dev/null
+++ b/SOURCES/0050-Fix-up-a-few-formatting-issues.patch
@@ -0,0 +1,51 @@
+From 9cf361f8791d86aaced821c19af556819bc03732 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 27 Nov 2019 11:33:15 -0500
+Subject: [RHEL8.2 PATCH 50/61] Fix up a few formatting issues
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index deeba2b..b22c396 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1728,8 +1728,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
+ 	int fd2 = open(from_devname, O_RDONLY);
+ 
+ 	if (fd1 < 0 || fd2 < 0) {
+-		if (fd1>=0) close(fd1);
+-		if (fd2>=0) close(fd2);
++		if (fd1 >= 0)
++			close(fd1);
++		if (fd2 >= 0)
++			close(fd2);
+ 		return 0;
+ 	}
+ 
+@@ -1743,7 +1745,8 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
+ 	devlist.disposition = 'r';
+ 	if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) {
+ 		devlist.disposition = 'a';
+-		if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL, 0) == 0) {
++		if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0,
++				   NULL, 0) == 0) {
+ 			/* make sure manager is aware of changes */
+ 			ping_manager(to_devname);
+ 			ping_manager(from_devname);
+@@ -1751,7 +1754,9 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
+ 			close(fd2);
+ 			return 1;
+ 		}
+-		else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0);
++		else
++			Manage_subdevs(from_devname, fd2, &devlist,
++				       -1, 0, NULL, 0);
+ 	}
+ 	close(fd1);
+ 	close(fd2);
+-- 
+2.7.5
+
diff --git a/SOURCES/0051-Remove-unused-code.patch b/SOURCES/0051-Remove-unused-code.patch
new file mode 100644
index 0000000..cd4aa2a
--- /dev/null
+++ b/SOURCES/0051-Remove-unused-code.patch
@@ -0,0 +1,26 @@
+From 4b31846f3f90aa24f883ceed80e91f204c0a9389 Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Fri, 29 Nov 2019 17:14:47 +0800
+Subject: [RHEL8.2 PATCH 51/61] Remove unused code
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ platform-intel.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/platform-intel.h b/platform-intel.h
+index 29c85f1..7cb370e 100644
+--- a/platform-intel.h
++++ b/platform-intel.h
+@@ -169,7 +169,6 @@ static inline int fls(int x)
+ 		r -= 2;
+ 	}
+ 	if (!(x & 0x80000000u)) {
+-		x <<= 1;
+ 		r -= 1;
+ 	}
+ 	return r;
+-- 
+2.7.5
+
diff --git a/SOURCES/0052-imsm-return-correct-uuid-for-volume-in-detail.patch b/SOURCES/0052-imsm-return-correct-uuid-for-volume-in-detail.patch
new file mode 100644
index 0000000..642297f
--- /dev/null
+++ b/SOURCES/0052-imsm-return-correct-uuid-for-volume-in-detail.patch
@@ -0,0 +1,176 @@
+From b771faef931c798a4553db0a8c1366aff90079c6 Mon Sep 17 00:00:00 2001
+From: Blazej Kucman <blazej.kucman@intel.com>
+Date: Fri, 29 Nov 2019 15:21:08 +0100
+Subject: [RHEL8.2 PATCH 52/61] imsm: return correct uuid for volume in detail
+
+Fixes the side effect of the patch b6180160f ("imsm: save current_vol number")
+- wrong UUID is printed in detail for each volume.
+New parameter "subarray" is added to determine what info should be extracted
+from metadata (subarray or container).
+The parameter affects only IMSM metadata.
+
+Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c      |  4 ++--
+ mdadm.h       |  5 +++--
+ super-ddf.c   |  5 +++--
+ super-intel.c | 20 ++++++++++++++++++--
+ super0.c      |  4 ++--
+ super1.c      |  4 ++--
+ 6 files changed, 30 insertions(+), 12 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index 3e61e37..24fa462 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -623,7 +623,7 @@ This is pretty boring
+ 		free_mdstat(ms);
+ 
+ 		if (st && st->sb)
+-			st->ss->detail_super(st, c->homehost);
++			st->ss->detail_super(st, c->homehost, subarray);
+ 
+ 		if (array.raid_disks == 0 && sra &&
+ 		    sra->array.major_version == -1 &&
+@@ -767,7 +767,7 @@ skip_devices_state:
+ 	if (spares && c->brief && array.raid_disks)
+ 		printf(" spares=%d", spares);
+ 	if (c->brief && st && st->sb)
+-		st->ss->brief_detail_super(st);
++		st->ss->brief_detail_super(st, subarray);
+ 	if (st)
+ 		st->ss->free_super(st);
+ 
+diff --git a/mdadm.h b/mdadm.h
+index c88ceab..91f1338 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -847,8 +847,9 @@ extern struct superswitch {
+ 	/* Used to report details of an active array.
+ 	 * ->load_super was possibly given a 'component' string.
+ 	 */
+-	void (*detail_super)(struct supertype *st, char *homehost);
+-	void (*brief_detail_super)(struct supertype *st);
++	void (*detail_super)(struct supertype *st, char *homehost,
++			     char *subarray);
++	void (*brief_detail_super)(struct supertype *st, char *subarray);
+ 	void (*export_detail_super)(struct supertype *st);
+ 
+ 	/* Optional: platform hardware / firmware details */
+diff --git a/super-ddf.c b/super-ddf.c
+index c095e8a..7802063 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -1730,7 +1730,8 @@ err:
+ 	return 1;
+ }
+ 
+-static void detail_super_ddf(struct supertype *st, char *homehost)
++static void detail_super_ddf(struct supertype *st, char *homehost,
++			     char *subarray)
+ {
+ 	struct ddf_super *sb = st->sb;
+ 	int cnt = be16_to_cpu(sb->virt->populated_vdes);
+@@ -1787,7 +1788,7 @@ static void uuid_of_ddf_subarray(const struct ddf_super *ddf,
+ 	memcpy(uuid, sha, 4*4);
+ }
+ 
+-static void brief_detail_super_ddf(struct supertype *st)
++static void brief_detail_super_ddf(struct supertype *st, char *subarray)
+ {
+ 	struct mdinfo info;
+ 	char nbuf[64];
+diff --git a/super-intel.c b/super-intel.c
+index a7fbed4..86dcb69 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -2183,23 +2183,39 @@ err:
+ 	return 1;
+ }
+ 
+-static void detail_super_imsm(struct supertype *st, char *homehost)
++static void detail_super_imsm(struct supertype *st, char *homehost,
++			      char *subarray)
+ {
+ 	struct mdinfo info;
+ 	char nbuf[64];
++	struct intel_super *super = st->sb;
++	int temp_vol = super->current_vol;
++
++	if (subarray)
++		super->current_vol = strtoul(subarray, NULL, 10);
+ 
+ 	getinfo_super_imsm(st, &info, NULL);
+ 	fname_from_uuid(st, &info, nbuf, ':');
+ 	printf("\n              UUID : %s\n", nbuf + 5);
++
++	super->current_vol = temp_vol;
+ }
+ 
+-static void brief_detail_super_imsm(struct supertype *st)
++static void brief_detail_super_imsm(struct supertype *st, char *subarray)
+ {
+ 	struct mdinfo info;
+ 	char nbuf[64];
++	struct intel_super *super = st->sb;
++	int temp_vol = super->current_vol;
++
++	if (subarray)
++		super->current_vol = strtoul(subarray, NULL, 10);
++
+ 	getinfo_super_imsm(st, &info, NULL);
+ 	fname_from_uuid(st, &info, nbuf, ':');
+ 	printf(" UUID=%s", nbuf + 5);
++
++	super->current_vol = temp_vol;
+ }
+ 
+ static int imsm_read_serial(int fd, char *devname, __u8 *serial);
+diff --git a/super0.c b/super0.c
+index 42989b9..6b7c0e3 100644
+--- a/super0.c
++++ b/super0.c
+@@ -348,7 +348,7 @@ err:
+ 	return 1;
+ }
+ 
+-static void detail_super0(struct supertype *st, char *homehost)
++static void detail_super0(struct supertype *st, char *homehost, char *subarray)
+ {
+ 	mdp_super_t *sb = st->sb;
+ 	printf("              UUID : ");
+@@ -368,7 +368,7 @@ static void detail_super0(struct supertype *st, char *homehost)
+ 	printf("\n            Events : %d.%d\n\n", sb->events_hi, sb->events_lo);
+ }
+ 
+-static void brief_detail_super0(struct supertype *st)
++static void brief_detail_super0(struct supertype *st, char *subarray)
+ {
+ 	mdp_super_t *sb = st->sb;
+ 	printf(" UUID=");
+diff --git a/super1.c b/super1.c
+index b85dc20..929466d 100644
+--- a/super1.c
++++ b/super1.c
+@@ -833,7 +833,7 @@ err:
+ 	return 1;
+ }
+ 
+-static void detail_super1(struct supertype *st, char *homehost)
++static void detail_super1(struct supertype *st, char *homehost, char *subarray)
+ {
+ 	struct mdp_superblock_1 *sb = st->sb;
+ 	bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
+@@ -857,7 +857,7 @@ static void detail_super1(struct supertype *st, char *homehost)
+ 	       (unsigned long long)__le64_to_cpu(sb->events));
+ }
+ 
+-static void brief_detail_super1(struct supertype *st)
++static void brief_detail_super1(struct supertype *st, char *subarray)
+ {
+ 	struct mdp_superblock_1 *sb = st->sb;
+ 	int i;
+-- 
+2.7.5
+
diff --git a/SOURCES/0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch b/SOURCES/0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch
new file mode 100644
index 0000000..3c1c221
--- /dev/null
+++ b/SOURCES/0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch
@@ -0,0 +1,208 @@
+From 6da53c0e2aab200605722795798b1e4f2352cd64 Mon Sep 17 00:00:00 2001
+From: Blazej Kucman <blazej.kucman@intel.com>
+Date: Mon, 2 Dec 2019 10:52:05 +0100
+Subject: [RHEL8.2 PATCH 53/61] imsm: Change the way of printing nvme drives in
+ detail-platform.
+
+Change NVMe controller path to device node path
+in mdadm --detail-platform and print serial number.
+The method imsm_read_serial always trimes serial to
+MAX_RAID_SERIAL_LEN, added parameter 'serial_buf_len'
+will be used to check the serial fit
+to passed buffor, if not, will be trimed.
+
+Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 97 ++++++++++++++++++++++++++++-------------------------------
+ 1 file changed, 46 insertions(+), 51 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 86dcb69..5c1f759 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -2218,7 +2218,8 @@ static void brief_detail_super_imsm(struct supertype *st, char *subarray)
+ 	super->current_vol = temp_vol;
+ }
+ 
+-static int imsm_read_serial(int fd, char *devname, __u8 *serial);
++static int imsm_read_serial(int fd, char *devname, __u8 *serial,
++			    size_t serial_buf_len);
+ static void fd2devname(int fd, char *name);
+ 
+ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose)
+@@ -2364,8 +2365,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
+ 		else {
+ 			fd2devname(fd, buf);
+ 			printf("          Port%d : %s", port, buf);
+-			if (imsm_read_serial(fd, NULL, (__u8 *) buf) == 0)
+-				printf(" (%.*s)\n", MAX_RAID_SERIAL_LEN, buf);
++			if (imsm_read_serial(fd, NULL, (__u8 *)buf,
++					     sizeof(buf)) == 0)
++				printf(" (%s)\n", buf);
+ 			else
+ 				printf(" ()\n");
+ 			close(fd);
+@@ -2388,52 +2390,45 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
+ 	return err;
+ }
+ 
+-static int print_vmd_attached_devs(struct sys_dev *hba)
++static int print_nvme_info(struct sys_dev *hba)
+ {
++	char buf[1024];
+ 	struct dirent *ent;
+ 	DIR *dir;
+-	char path[292];
+-	char link[256];
+-	char *c, *rp;
+-
+-	if (hba->type != SYS_DEV_VMD)
+-		return 1;
++	char *rp;
++	int fd;
+ 
+-	/* scroll through /sys/dev/block looking for devices attached to
+-	 * this hba
+-	 */
+-	dir = opendir("/sys/bus/pci/drivers/nvme");
++	dir = opendir("/sys/block/");
+ 	if (!dir)
+ 		return 1;
+ 
+ 	for (ent = readdir(dir); ent; ent = readdir(dir)) {
+-		int n;
+-
+-		/* is 'ent' a device? check that the 'subsystem' link exists and
+-		 * that its target matches 'bus'
+-		 */
+-		sprintf(path, "/sys/bus/pci/drivers/nvme/%s/subsystem",
+-			ent->d_name);
+-		n = readlink(path, link, sizeof(link));
+-		if (n < 0 || n >= (int)sizeof(link))
+-			continue;
+-		link[n] = '\0';
+-		c = strrchr(link, '/');
+-		if (!c)
+-			continue;
+-		if (strncmp("pci", c+1, strlen("pci")) != 0)
+-			continue;
+-
+-		sprintf(path, "/sys/bus/pci/drivers/nvme/%s", ent->d_name);
+-
+-		rp = realpath(path, NULL);
+-		if (!rp)
+-			continue;
++		if (strstr(ent->d_name, "nvme")) {
++			sprintf(buf, "/sys/block/%s", ent->d_name);
++			rp = realpath(buf, NULL);
++			if (!rp)
++				continue;
++			if (path_attached_to_hba(rp, hba->path)) {
++				fd = open_dev(ent->d_name);
++				if (fd < 0) {
++					free(rp);
++					continue;
++				}
+ 
+-		if (path_attached_to_hba(rp, hba->path)) {
+-			printf(" NVMe under VMD : %s\n", rp);
++				fd2devname(fd, buf);
++				if (hba->type == SYS_DEV_VMD)
++					printf(" NVMe under VMD : %s", buf);
++				else if (hba->type == SYS_DEV_NVME)
++					printf("    NVMe Device : %s", buf);
++				if (!imsm_read_serial(fd, NULL, (__u8 *)buf,
++						      sizeof(buf)))
++					printf(" (%s)\n", buf);
++				else
++					printf("()\n");
++				close(fd);
++			}
++			free(rp);
+ 		}
+-		free(rp);
+ 	}
+ 
+ 	closedir(dir);
+@@ -2648,7 +2643,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
+ 					char buf[PATH_MAX];
+ 					printf(" I/O Controller : %s (%s)\n",
+ 						vmd_domain_to_controller(hba, buf), get_sys_dev_type(hba->type));
+-					if (print_vmd_attached_devs(hba)) {
++					if (print_nvme_info(hba)) {
+ 						if (verbose > 0)
+ 							pr_err("failed to get devices attached to VMD domain.\n");
+ 						result |= 2;
+@@ -2663,7 +2658,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
+ 		if (entry->type == SYS_DEV_NVME) {
+ 			for (hba = list; hba; hba = hba->next) {
+ 				if (hba->type == SYS_DEV_NVME)
+-					printf("    NVMe Device : %s\n", hba->path);
++					print_nvme_info(hba);
+ 			}
+ 			printf("\n");
+ 			continue;
+@@ -4028,11 +4023,11 @@ static int nvme_get_serial(int fd, void *buf, size_t buf_len)
+ extern int scsi_get_serial(int fd, void *buf, size_t buf_len);
+ 
+ static int imsm_read_serial(int fd, char *devname,
+-			    __u8 serial[MAX_RAID_SERIAL_LEN])
++			    __u8 *serial, size_t serial_buf_len)
+ {
+ 	char buf[50];
+ 	int rv;
+-	int len;
++	size_t len;
+ 	char *dest;
+ 	char *src;
+ 	unsigned int i;
+@@ -4075,13 +4070,13 @@ static int imsm_read_serial(int fd, char *devname,
+ 	len = dest - buf;
+ 	dest = buf;
+ 
+-	/* truncate leading characters */
+-	if (len > MAX_RAID_SERIAL_LEN) {
+-		dest += len - MAX_RAID_SERIAL_LEN;
+-		len = MAX_RAID_SERIAL_LEN;
++	if (len > serial_buf_len) {
++		/* truncate leading characters */
++		dest += len - serial_buf_len;
++		len = serial_buf_len;
+ 	}
+ 
+-	memset(serial, 0, MAX_RAID_SERIAL_LEN);
++	memset(serial, 0, serial_buf_len);
+ 	memcpy(serial, dest, len);
+ 
+ 	return 0;
+@@ -4136,7 +4131,7 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
+ 	char name[40];
+ 	__u8 serial[MAX_RAID_SERIAL_LEN];
+ 
+-	rv = imsm_read_serial(fd, devname, serial);
++	rv = imsm_read_serial(fd, devname, serial, MAX_RAID_SERIAL_LEN);
+ 
+ 	if (rv != 0)
+ 		return 2;
+@@ -5844,7 +5839,7 @@ int mark_spare(struct dl *disk)
+ 		return ret_val;
+ 
+ 	ret_val = 0;
+-	if (!imsm_read_serial(disk->fd, NULL, serial)) {
++	if (!imsm_read_serial(disk->fd, NULL, serial, MAX_RAID_SERIAL_LEN)) {
+ 		/* Restore disk serial number, because takeover marks disk
+ 		 * as failed and adds to serial ':0' before it becomes
+ 		 * a spare disk.
+@@ -5895,7 +5890,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
+ 	dd->fd = fd;
+ 	dd->e = NULL;
+ 	dd->action = DISK_ADD;
+-	rv = imsm_read_serial(fd, devname, dd->serial);
++	rv = imsm_read_serial(fd, devname, dd->serial, MAX_RAID_SERIAL_LEN);
+ 	if (rv) {
+ 		pr_err("failed to retrieve scsi serial, aborting\n");
+ 		if (dd->devname)
+-- 
+2.7.5
+
diff --git a/SOURCES/0054-Create-add-support-for-RAID0-layouts.patch b/SOURCES/0054-Create-add-support-for-RAID0-layouts.patch
new file mode 100644
index 0000000..b87e668
--- /dev/null
+++ b/SOURCES/0054-Create-add-support-for-RAID0-layouts.patch
@@ -0,0 +1,342 @@
+From 329dfc28debb58ffe7bd1967cea00fc583139aca Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Mon, 4 Nov 2019 14:27:49 +1100
+Subject: [RHEL8.2 PATCH 54/61] Create: add support for RAID0 layouts.
+
+Since Linux 5.4 a layout is needed for RAID0 arrays with
+varying device sizes.
+This patch makes the layout of an array visible (via --examine)
+and sets the layout on newly created arrays.
+--layout=dangerous
+can be used to avoid setting a layout so that they array
+can be used on older kernels.
+
+Tested-by: dann frazier <dann.frazier@canonical.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Create.c   | 11 +++++++++++
+ Detail.c   |  5 +++++
+ maps.c     | 12 ++++++++++++
+ md.4       | 14 ++++++++++++++
+ mdadm.8.in | 30 +++++++++++++++++++++++++++++-
+ mdadm.c    |  8 ++++++++
+ mdadm.h    |  8 +++++++-
+ super0.c   |  6 ++++++
+ super1.c   | 30 +++++++++++++++++++++++++++++-
+ 9 files changed, 121 insertions(+), 3 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 292f92a..6f84e5b 100644
+--- a/Create.c
++++ b/Create.c
+@@ -51,6 +51,9 @@ static int default_layout(struct supertype *st, int level, int verbose)
+ 		default: /* no layout */
+ 			layout = 0;
+ 			break;
++		case 0:
++			layout = RAID0_ORIG_LAYOUT;
++			break;
+ 		case 10:
+ 			layout = 0x102; /* near=2, far=1 */
+ 			if (verbose > 0)
+@@ -950,6 +953,11 @@ int Create(struct supertype *st, char *mddev,
+ 				if (rv) {
+ 					pr_err("ADD_NEW_DISK for %s failed: %s\n",
+ 					       dv->devname, strerror(errno));
++					if (errno == EINVAL &&
++					    info.array.level == 0) {
++						pr_err("Possibly your kernel doesn't support RAID0 layouts.\n");
++						pr_err("Either upgrade, or use --layout=dangerous\n");
++					}
+ 					goto abort_locked;
+ 				}
+ 				break;
+@@ -1046,6 +1054,9 @@ int Create(struct supertype *st, char *mddev,
+ 			if (ioctl(mdfd, RUN_ARRAY, &param)) {
+ 				pr_err("RUN_ARRAY failed: %s\n",
+ 				       strerror(errno));
++				if (errno == 524 /* ENOTSUP */ &&
++				    info.array.level == 0)
++					cont_err("Please use --layout=original or --layout=alternate\n");
+ 				if (info.array.chunk_size & (info.array.chunk_size-1)) {
+ 					cont_err("Problem may be that chunk size is not a power of 2\n");
+ 				}
+diff --git a/Detail.c b/Detail.c
+index 24fa462..832485f 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -525,6 +525,11 @@ int Detail(char *dev, struct context *c)
+ 			printf("            Layout : %s\n",
+ 			       str ? str : "-unknown-");
+ 		}
++		if (array.level == 0 && array.layout) {
++			str = map_num(r0layout, array.layout);
++			printf("            Layout : %s\n",
++			       str ? str : "-unknown-");
++		}
+ 		if (array.level == 6) {
+ 			str = map_num(r6layout, array.layout);
+ 			printf("            Layout : %s\n",
+diff --git a/maps.c b/maps.c
+index 49b7f2c..a4fd279 100644
+--- a/maps.c
++++ b/maps.c
+@@ -73,6 +73,18 @@ mapping_t r6layout[] = {
+ 	{ NULL, UnSet }
+ };
+ 
++/* raid0 layout is only needed because of a bug in 3.14 which changed
++ * the effective layout of raid0 arrays with varying device sizes.
++ */
++mapping_t r0layout[] = {
++	{ "original", RAID0_ORIG_LAYOUT},
++	{ "alternate", RAID0_ALT_MULTIZONE_LAYOUT},
++	{ "1", 1}, /* aka ORIG */
++	{ "2", 2}, /* aka ALT */
++	{ "dangerous", 0},
++	{ NULL, UnSet},
++};
++
+ mapping_t pers[] = {
+ 	{ "linear", LEVEL_LINEAR},
+ 	{ "raid0", 0},
+diff --git a/md.4 b/md.4
+index e86707a..6fe2755 100644
+--- a/md.4
++++ b/md.4
+@@ -193,6 +193,20 @@ smallest device has been exhausted, the RAID0 driver starts
+ collecting chunks into smaller stripes that only span the drives which
+ still have remaining space.
+ 
++A bug was introduced in linux 3.14 which changed the layout of blocks in
++a RAID0 beyond the region that is striped over all devices.  This bug
++does not affect an array with all devices the same size, but can affect
++other RAID0 arrays.
++
++Linux 5.4 (and some stable kernels to which the change was backported)
++will not normally assemble such an array as it cannot know which layout
++to use.  There is a module parameter "raid0.default_layout" which can be
++set to "1" to force the kernel to use the pre-3.14 layout or to "2" to
++force it to use the 3.14-and-later layout.  when creating a new RAID0
++array,
++.I mdadm
++will record the chosen layout in the metadata in a way that allows newer
++kernels to assemble the array without needing a module parameter.
+ 
+ .SS RAID1
+ 
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 9aec9f4..fc9b6a6 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -593,6 +593,8 @@ to change the RAID level in some cases.  See LEVEL CHANGES below.
+ This option configures the fine details of data layout for RAID5, RAID6,
+ and RAID10 arrays, and controls the failure modes for
+ .IR faulty .
++It can also be used for working around a kernel bug with RAID0, but generally
++doesn't need to be used explicitly.
+ 
+ The layout of the RAID5 parity block can be one of
+ .BR left\-asymmetric ,
+@@ -652,7 +654,7 @@ option to set subsequent failure modes.
+ "clear" or "none" will remove any pending or periodic failure modes,
+ and "flush" will clear any persistent faults.
+ 
+-Finally, the layout options for RAID10 are one of 'n', 'o' or 'f' followed
++The layout options for RAID10 are one of 'n', 'o' or 'f' followed
+ by a small number.  The default is 'n2'.  The supported options are:
+ 
+ .I 'n'
+@@ -677,6 +679,32 @@ devices in the array.  It does not need to divide evenly into that
+ number (e.g. it is perfectly legal to have an 'n2' layout for an array
+ with an odd number of devices).
+ 
++A bug introduced in Linux 3.14 means that RAID0 arrays
++.B "with devices of differing sizes"
++started using a different layout.  This could lead to
++data corruption.  Since Linux 5.4 (and various stable releases that received
++backports), the kernel will not accept such an array unless
++a layout is explictly set.  It can be set to
++.RB ' original '
++or
++.RB ' alternate '.
++When creating a new array,
++.I mdadm
++will select
++.RB ' original '
++by default, so the layout does not normally need to be set.
++An array created for either
++.RB ' original '
++or
++.RB ' alternate '
++will not be recognized by an (unpatched) kernel prior to 5.4.  To create
++a RAID0 array with devices of differing sizes that can be used on an
++older kernel, you can set the layout to
++.RB ' dangerous '.
++This will use whichever layout the running kernel supports, so the data
++on the array may become corrupt when changing kernel from pre-3.14 to a
++later kernel.
++
+ When an array is converted between RAID5 and RAID6 an intermediate
+ RAID6 layout is used in which the second parity block (Q) is always on
+ the last device.  To convert a RAID5 to RAID6 and leave it in this new
+diff --git a/mdadm.c b/mdadm.c
+index 1fb8086..e438f9c 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -550,6 +550,14 @@ int main(int argc, char *argv[])
+ 				pr_err("raid level must be given before layout.\n");
+ 				exit(2);
+ 
++			case 0:
++				s.layout = map_name(r0layout, optarg);
++				if (s.layout == UnSet) {
++					pr_err("layout %s not understood for raid0.\n",
++						optarg);
++					exit(2);
++				}
++				break;
+ 			case 5:
+ 				s.layout = map_name(r5layout, optarg);
+ 				if (s.layout == UnSet) {
+diff --git a/mdadm.h b/mdadm.h
+index 91f1338..9e98778 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -763,7 +763,8 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
+ 
+ extern char *map_num(mapping_t *map, int num);
+ extern int map_name(mapping_t *map, char *name);
+-extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
++extern mapping_t r0layout[], r5layout[], r6layout[],
++	pers[], modes[], faultylayout[];
+ extern mapping_t consistency_policies[], sysfs_array_states[];
+ 
+ extern char *map_dev_preferred(int major, int minor, int create,
+@@ -1758,6 +1759,11 @@ char *xstrdup(const char *str);
+ #define makedev(M,m) (((M)<<8) | (m))
+ #endif
+ 
++enum r0layout {
++	RAID0_ORIG_LAYOUT = 1,
++	RAID0_ALT_MULTIZONE_LAYOUT = 2,
++};
++
+ /* for raid4/5/6 */
+ #define ALGORITHM_LEFT_ASYMMETRIC	0
+ #define ALGORITHM_RIGHT_ASYMMETRIC	1
+diff --git a/super0.c b/super0.c
+index 6b7c0e3..6af140b 100644
+--- a/super0.c
++++ b/super0.c
+@@ -1291,6 +1291,12 @@ static int validate_geometry0(struct supertype *st, int level,
+ 	if (*chunk == UnSet)
+ 		*chunk = DEFAULT_CHUNK;
+ 
++	if (level == 0 && layout != UnSet) {
++		if (verbose)
++			pr_err("0.90 metadata does not support layouts for RAID0\n");
++		return 0;
++	}
++
+ 	if (!subdev)
+ 		return 1;
+ 
+diff --git a/super1.c b/super1.c
+index 929466d..cedbb53 100644
+--- a/super1.c
++++ b/super1.c
+@@ -43,7 +43,7 @@ struct mdp_superblock_1 {
+ 
+ 	__u64	ctime;		/* lo 40 bits are seconds, top 24 are microseconds or 0*/
+ 	__u32	level;		/* -4 (multipath), -1 (linear), 0,1,4,5 */
+-	__u32	layout;		/* only for raid5 currently */
++	__u32	layout;		/* used for raid5, raid6, raid10, and raid0 */
+ 	__u64	size;		/* used size of component devices, in 512byte sectors */
+ 
+ 	__u32	chunksize;	/* in 512byte sectors */
+@@ -144,6 +144,7 @@ struct misc_dev_info {
+ #define	MD_FEATURE_JOURNAL		512 /* support write journal */
+ #define	MD_FEATURE_PPL			1024 /* support PPL */
+ #define	MD_FEATURE_MUTLIPLE_PPLS	2048 /* support for multiple PPLs */
++#define	MD_FEATURE_RAID0_LAYOUT		4096 /* layout is meaningful in RAID0 */
+ #define	MD_FEATURE_ALL			(MD_FEATURE_BITMAP_OFFSET	\
+ 					|MD_FEATURE_RECOVERY_OFFSET	\
+ 					|MD_FEATURE_RESHAPE_ACTIVE	\
+@@ -155,6 +156,7 @@ struct misc_dev_info {
+ 					|MD_FEATURE_JOURNAL		\
+ 					|MD_FEATURE_PPL			\
+ 					|MD_FEATURE_MULTIPLE_PPLS	\
++					|MD_FEATURE_RAID0_LAYOUT	\
+ 					)
+ 
+ static int role_from_sb(struct mdp_superblock_1 *sb)
+@@ -498,6 +500,11 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	printf("         Events : %llu\n",
+ 	       (unsigned long long)__le64_to_cpu(sb->events));
+ 	printf("\n");
++	if (__le32_to_cpu(sb->level) == 0 &&
++	    (sb->feature_map & __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT))) {
++		c = map_num(r0layout, __le32_to_cpu(sb->layout));
++		printf("         Layout : %s\n", c?c:"-unknown-");
++	}
+ 	if (__le32_to_cpu(sb->level) == 5) {
+ 		c = map_num(r5layout, __le32_to_cpu(sb->layout));
+ 		printf("         Layout : %s\n", c?c:"-unknown-");
+@@ -1646,6 +1653,7 @@ struct devinfo {
+ 	int fd;
+ 	char *devname;
+ 	long long data_offset;
++	unsigned long long dev_size;
+ 	mdu_disk_info_t disk;
+ 	struct devinfo *next;
+ };
+@@ -1687,6 +1695,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 	di->devname = devname;
+ 	di->disk = *dk;
+ 	di->data_offset = data_offset;
++	get_dev_size(fd, NULL, &di->dev_size);
+ 	di->next = NULL;
+ 	*dip = di;
+ 
+@@ -1888,10 +1897,25 @@ static int write_init_super1(struct supertype *st)
+ 	unsigned long long sb_offset;
+ 	unsigned long long data_offset;
+ 	long bm_offset;
++	int raid0_need_layout = 0;
+ 
+ 	for (di = st->info; di; di = di->next) {
+ 		if (di->disk.state & (1 << MD_DISK_JOURNAL))
+ 			sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
++		if (sb->level == 0 && sb->layout != 0) {
++			struct devinfo *di2 = st->info;
++			unsigned long long s1, s2;
++			s1 = di->dev_size;
++			if (di->data_offset != INVALID_SECTORS)
++				s1 -= di->data_offset;
++			s1 /= __le32_to_cpu(sb->chunksize);
++			s2 = di2->dev_size;
++			if (di2->data_offset != INVALID_SECTORS)
++				s2 -= di2->data_offset;
++			s2 /= __le32_to_cpu(sb->chunksize);
++			if (s1 != s2)
++				raid0_need_layout = 1;
++		}
+ 	}
+ 
+ 	for (di = st->info; di; di = di->next) {
+@@ -2039,6 +2063,10 @@ static int write_init_super1(struct supertype *st)
+ 			sb->bblog_offset = 0;
+ 		}
+ 
++		/* RAID0 needs a layout if devices aren't all the same size */
++		if (raid0_need_layout)
++			sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
++
+ 		sb->sb_csum = calc_sb_1_csum(sb);
+ 		rv = store_super1(st, di->fd);
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0055-Assemble-add-support-for-RAID0-layouts.patch b/SOURCES/0055-Assemble-add-support-for-RAID0-layouts.patch
new file mode 100644
index 0000000..c747892
--- /dev/null
+++ b/SOURCES/0055-Assemble-add-support-for-RAID0-layouts.patch
@@ -0,0 +1,150 @@
+From 027c099fd1a31fb3815e592de75d0791a22353b4 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Mon, 4 Nov 2019 14:27:49 +1100
+Subject: [RHEL8.2 PATCH 55/61] Assemble: add support for RAID0 layouts.
+
+If you have a RAID0 array with varying sized devices
+on a kernel before 5.4, you cannot assembling it on
+5.4 or later without explicitly setting the layout.
+This is now possible with
+  --update=layout-original (For 3.13 and earlier kernels)
+or
+  --update=layout-alternate (for 3.14 and later kernels)
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c |  8 ++++++++
+ md.4       |  7 +++++++
+ mdadm.8.in | 17 +++++++++++++++++
+ mdadm.c    |  4 ++++
+ super1.c   | 12 +++++++++++-
+ 5 files changed, 47 insertions(+), 1 deletion(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index b2e6914..6b5a7c8 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1031,6 +1031,11 @@ static int start_array(int mdfd,
+ 				pr_err("failed to add %s to %s: %s\n",
+ 				       devices[j].devname, mddev,
+ 				       strerror(errno));
++				if (errno == EINVAL && content->array.level == 0 &&
++				    content->array.layout != 0) {
++					cont_err("Possibly your kernel doesn't support RAID0 layouts.\n");
++					cont_err("Please upgrade.\n");
++				}
+ 				if (i < content->array.raid_disks * 2 ||
+ 				    i == bestcnt)
+ 					okcnt--;
+@@ -1220,6 +1225,9 @@ static int start_array(int mdfd,
+ 			return 0;
+ 		}
+ 		pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno));
++		if (errno == 524 /* ENOTSUP */ &&
++		    content->array.level == 0 && content->array.layout == 0)
++			cont_err("Please use --update=layout-original or --update=layout-alternate\n");
+ 
+ 		if (!enough(content->array.level, content->array.raid_disks,
+ 			    content->array.layout, 1, avail))
+diff --git a/md.4 b/md.4
+index 6fe2755..0712af2 100644
+--- a/md.4
++++ b/md.4
+@@ -208,6 +208,13 @@ array,
+ will record the chosen layout in the metadata in a way that allows newer
+ kernels to assemble the array without needing a module parameter.
+ 
++To assemble an old array on a new kernel without using the module parameter,
++use either the
++.B "--update=layout-original"
++option or the
++.B "--update=layout-alternate"
++option.
++
+ .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 fc9b6a6..6b63bb4 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -1213,6 +1213,8 @@ argument given to this flag can be one of
+ .BR no\-bbl ,
+ .BR ppl ,
+ .BR no\-ppl ,
++.BR layout\-original ,
++.BR layout\-alternate ,
+ .BR metadata ,
+ or
+ .BR super\-minor .
+@@ -1364,6 +1366,21 @@ The
+ .B no\-ppl
+ option will disable PPL in the superblock.
+ 
++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,
++.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
++.B \-\-update=layout\-alternate
++must be given.  This only needs to be given once.  Subsequent assembly of the array
++will happen normally.
++For more information, see
++.IR md (4).
++
+ .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 e438f9c..256a97e 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -795,6 +795,9 @@ int main(int argc, char *argv[])
+ 				continue;
+ 			if (strcmp(c.update, "revert-reshape") == 0)
+ 				continue;
++			if (strcmp(c.update, "layout-original") == 0 ||
++			    strcmp(c.update, "layout-alternate") == 0)
++				continue;
+ 			if (strcmp(c.update, "byteorder") == 0) {
+ 				if (ss) {
+ 					pr_err("must not set metadata type with --update=byteorder.\n");
+@@ -825,6 +828,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"
+ 				);
+ 			exit(outf == stdout ? 0 : 2);
+ 
+diff --git a/super1.c b/super1.c
+index cedbb53..e0d80be 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1550,7 +1550,17 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		sb->devflags |= FailFast1;
+ 	else if (strcmp(update, "nofailfast") == 0)
+ 		sb->devflags &= ~FailFast1;
+-	else
++	else if (strcmp(update, "layout-original") == 0 ||
++		 strcmp(update, "layout-alternate") == 0) {
++		if (__le32_to_cpu(sb->level) != 0) {
++			pr_err("%s: %s only supported for RAID0\n",
++			       devname?:"", update);
++			rv = -1;
++		} else {
++			sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
++			sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2);
++		}
++	} else
+ 		rv = -1;
+ 
+ 	sb->sb_csum = calc_sb_1_csum(sb);
+-- 
+2.7.5
+
diff --git a/SOURCES/0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch b/SOURCES/0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch
new file mode 100644
index 0000000..9219ae8
--- /dev/null
+++ b/SOURCES/0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch
@@ -0,0 +1,36 @@
+From aced6fc9542077a69b00d05bc9cd66c12fc34950 Mon Sep 17 00:00:00 2001
+From: dann frazier <dann.frazier@canonical.com>
+Date: Mon, 9 Dec 2019 13:54:13 -0700
+Subject: [RHEL8.2 PATCH 56/61] Respect $(CROSS_COMPILE) when $(CC) is the
+ default
+
+Commit 1180ed5 told make to only respect $(CROSS_COMPILE) when $(CC)
+was unset. But that will never be the case, as make provides
+a default value for $(CC). Change this logic to respect $(CROSS_COMPILE)
+when $(CC) is the default. Patch originally by Helmet Grohne.
+
+Fixes: 1180ed5 ("Makefile: make the CC definition conditional")
+Signed-off-by: dann frazier <dann.frazier@canonical.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index dfe00b0..a33319a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -46,7 +46,9 @@ ifdef COVERITY
+ COVERITY_FLAGS=-include coverity-gcc-hack.h
+ endif
+ 
+-CC ?= $(CROSS_COMPILE)gcc
++ifeq ($(origin CC),default)
++CC := $(CROSS_COMPILE)gcc
++endif
+ CXFLAGS ?= -ggdb
+ CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter
+ ifdef WARN_UNUSED
+-- 
+2.7.5
+
diff --git a/SOURCES/0057-Change-warning-message.patch b/SOURCES/0057-Change-warning-message.patch
new file mode 100644
index 0000000..312cc13
--- /dev/null
+++ b/SOURCES/0057-Change-warning-message.patch
@@ -0,0 +1,39 @@
+From 1a87493014050e3bd94000cd36122c3cadf21270 Mon Sep 17 00:00:00 2001
+From: Kinga Tanska <kinga.tanska@intel.com>
+Date: Tue, 10 Dec 2019 12:21:21 +0100
+Subject: [RHEL8.2 PATCH 57/61] Change warning message
+
+In commit 039b7225e6 ("md: allow creation of mdNNN arrays via
+md_mod/parameters/new_array") support for name like mdNNN
+was added. Special warning, when kernel is unable to handle
+request, was added in commit 7105228e19
+("mdadm/mdopen: create new function create_named_array for
+writing to new_array"), but it was not adequate enough,
+because in this situation mdadm tries to do it in old way.
+This commit changes warning to be more relevant when
+creating RAID container with "/dev/mdNNN" name and mdadm
+back to old approach.
+
+Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdopen.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mdopen.c b/mdopen.c
+index 98c54e4..245be53 100644
+--- a/mdopen.c
++++ b/mdopen.c
+@@ -120,7 +120,8 @@ int create_named_array(char *devnm)
+ 		close(fd);
+ 	}
+ 	if (fd < 0 || n != (int)strlen(devnm)) {
+-		pr_err("Fail create %s when using %s\n", devnm, new_array_file);
++		pr_err("Fail to create %s when using %s, fallback to creation via node\n",
++			devnm, new_array_file);
+ 		return 0;
+ 	}
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch b/SOURCES/0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch
new file mode 100644
index 0000000..9f664ff
--- /dev/null
+++ b/SOURCES/0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch
@@ -0,0 +1,52 @@
+From 1cc3965d48deb0fb3e0657159c608ffb124643c1 Mon Sep 17 00:00:00 2001
+From: Xiao Yang <ice_yangxiao@163.com>
+Date: Wed, 27 Nov 2019 11:59:24 +0800
+Subject: [RHEL8.2 PATCH 48/61] Manage: Remove the legacy code for md driver
+ prior to 0.90.03
+
+Previous re-add operation only calls ioctl(HOT_ADD_DISK) for array without
+metadata(e.g. mdadm -B/--build) when md driver is less than 0.90.02, but
+commit 091e8e6 breaks the logic and current re-add operation can call
+ioctl(HOT_ADD_DISK) even if md driver is 0.90.03.
+
+This issue is reproduced by 05r1-re-add-nosuper:
+------------------------------------------------
+++ die 'resync or recovery is happening!'
+++ echo -e '\n\tERROR: resync or recovery is happening! \n'
+ERROR: resync or recovery is happening!
+------------------------------------------------
+
+Fixes: 091e8e6("Manage: Remove all references to md_get_version()")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Xiao Yang <ice_yangxiao@163.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index 21536f5..ffe55f8 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -741,18 +741,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 		       "       Adding anyway as --force was given.\n",
+ 		       dv->devname, devname);
+ 	}
+-	if (!tst->ss->external && array->major_version == 0) {
+-		if (ioctl(fd, HOT_ADD_DISK, rdev)==0) {
+-			if (verbose >= 0)
+-				pr_err("hot added %s\n",
+-				       dv->devname);
+-			return 1;
+-		}
+-
+-		pr_err("hot add failed for %s: %s\n",
+-		       dv->devname, strerror(errno));
+-		return -1;
+-	}
+ 
+ 	if (array->not_persistent == 0 || tst->ss->external) {
+ 
+-- 
+2.7.5
+
diff --git a/SOURCES/0059-imsm-Update-grow-manual.patch b/SOURCES/0059-imsm-Update-grow-manual.patch
new file mode 100644
index 0000000..2b54b8f
--- /dev/null
+++ b/SOURCES/0059-imsm-Update-grow-manual.patch
@@ -0,0 +1,43 @@
+From 4431efebabd0dd39f33dc1dd8ada312b8da1c9d8 Mon Sep 17 00:00:00 2001
+From: Blazej Kucman <blazej.kucman@intel.com>
+Date: Thu, 16 Jan 2020 09:34:44 +0100
+Subject: [RHEL8.2 PATCH 59/61] imsm: Update grow manual.
+
+Update --grow option description in manual, according to
+the supported grow operations by IMSM.
+
+Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 6b63bb4..ca02a33 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -481,9 +481,7 @@ still be larger than any replacement.
+ This value can be set with
+ .B \-\-grow
+ for RAID level 1/4/5/6 though
+-.B CONTAINER
+-based arrays such as those with IMSM metadata may not be able to
+-support this.
++DDF arrays may not be able to support this.
+ If the array was created with a size smaller than the currently
+ active drives, the extra space can be accessed using
+ .BR \-\-grow .
+@@ -2759,9 +2757,7 @@ container format.  The number of devices in a container can be
+ increased - which affects all arrays in the container - or an array
+ in a container can be converted between levels where those levels are
+ supported by the container, and the conversion is on of those listed
+-above.  Resizing arrays in an IMSM container with
+-.B "--grow --size"
+-is not yet supported.
++above.
+ 
+ .PP
+ Notes:
+-- 
+2.7.5
+
diff --git a/SOURCES/0060-Add-support-for-Tebibytes.patch b/SOURCES/0060-Add-support-for-Tebibytes.patch
new file mode 100644
index 0000000..45d288e
--- /dev/null
+++ b/SOURCES/0060-Add-support-for-Tebibytes.patch
@@ -0,0 +1,192 @@
+From 42e641abeb312a91b841f1b1ea73661e4bd5a31c Mon Sep 17 00:00:00 2001
+From: Kinga Tanska <kinga.tanska@intel.com>
+Date: Tue, 21 Jan 2020 10:38:52 +0100
+Subject: [RHEL8.2 PATCH 60/61] Add support for Tebibytes
+
+Adding support for Tebibytes enables display size of
+volumes in Tebibytes and Terabytes when they are
+bigger than 2048 GiB (or GB).
+
+Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 20 ++++++++++----------
+ util.c     | 47 +++++++++++++++++++++++++++++++++--------------
+ 2 files changed, 43 insertions(+), 24 deletions(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index ca02a33..5d00faf 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -467,8 +467,8 @@ If this is not specified
+ size, though if there is a variance among the drives of greater than 1%, a warning is
+ issued.
+ 
+-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
+-Gigabytes respectively.
++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
++Megabytes, Gigabytes or Terabytes respectively.
+ 
+ Sometimes a replacement drive can be a little smaller than the
+ original drives though this should be minimised by IDEMA standards.
+@@ -532,8 +532,8 @@ problems the array can be made bigger again with no loss with another
+ .B "\-\-grow \-\-array\-size="
+ command.
+ 
+-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
+-Gigabytes respectively.
++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
++Megabytes, Gigabytes or Terabytes respectively.
+ A value of
+ .B max
+ restores the apparent size of the array to be whatever the real
+@@ -551,8 +551,8 @@ This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10.
+ RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power
+ of 2.  In any case it must be a multiple of 4KB.
+ 
+-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
+-Gigabytes respectively.
++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
++Megabytes, Gigabytes or Terabytes respectively.
+ 
+ .TP
+ .BR \-\-rounding=
+@@ -767,8 +767,8 @@ When using an
+ bitmap, the chunksize defaults to 64Meg, or larger if necessary to
+ fit the bitmap into the available space.
+ 
+-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
+-Gigabytes respectively.
++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
++Megabytes, Gigabytes or Terabytes respectively.
+ 
+ .TP
+ .BR \-W ", " \-\-write\-mostly
+@@ -857,8 +857,8 @@ an array which was originally created using a different version of
+ which computed a different offset.
+ 
+ Setting the offset explicitly over-rides the default.  The value given
+-is in Kilobytes unless a suffix of 'K', 'M' or 'G' is used to explicitly
+-indicate Kilobytes, Megabytes or Gigabytes respectively.
++is in Kilobytes unless a suffix of 'K', 'M', 'G' or 'T' is used to explicitly
++indicate Kilobytes, Megabytes, Gigabytes or Terabytes respectively.
+ 
+ Since Linux 3.4,
+ .B \-\-data\-offset
+diff --git a/util.c b/util.c
+index 64dd409..07f9dc3 100644
+--- a/util.c
++++ b/util.c
+@@ -389,7 +389,7 @@ int mdadm_version(char *version)
+ unsigned long long parse_size(char *size)
+ {
+ 	/* parse 'size' which should be a number optionally
+-	 * followed by 'K', 'M', or 'G'.
++	 * followed by 'K', 'M'. 'G' or 'T'.
+ 	 * Without a suffix, K is assumed.
+ 	 * Number returned is in sectors (half-K)
+ 	 * INVALID_SECTORS returned on error.
+@@ -411,6 +411,10 @@ unsigned long long parse_size(char *size)
+ 			c++;
+ 			s *= 1024 * 1024 * 2;
+ 			break;
++		case 'T':
++			c++;
++			s *= 1024 * 1024 * 1024 * 2LL;
++			break;
+ 		case 's': /* sectors */
+ 			c++;
+ 			break;
+@@ -893,13 +897,14 @@ char *human_size(long long bytes)
+ {
+ 	static char buf[47];
+ 
+-	/* We convert bytes to either centi-M{ega,ibi}bytes or
+-	 * centi-G{igi,ibi}bytes, with appropriate rounding,
+-	 * and then print 1/100th of those as a decimal.
++	/* We convert bytes to either centi-M{ega,ibi}bytes,
++	 * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes
++	 * with appropriate rounding, and then print
++	 * 1/100th of those as a decimal.
+ 	 * We allow upto 2048Megabytes before converting to
+-	 * gigabytes, as that shows more precision and isn't
++	 * gigabytes and 2048Gigabytes before converting to
++	 * terabytes, as that shows more precision and isn't
+ 	 * too large a number.
+-	 * Terabytes are not yet handled.
+ 	 */
+ 
+ 	if (bytes < 5000*1024)
+@@ -909,11 +914,16 @@ char *human_size(long long bytes)
+ 		long cMB  = (bytes / ( 1000000LL / 200LL ) +1) /2;
+ 		snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)",
+ 			cMiB/100, cMiB % 100, cMB/100, cMB % 100);
+-	} else {
++	} else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
+ 		long cGiB = (bytes * 200LL / (1LL<<30) +1) / 2;
+ 		long cGB  = (bytes / (1000000000LL/200LL ) +1) /2;
+ 		snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)",
+ 			cGiB/100, cGiB % 100, cGB/100, cGB % 100);
++	} else {
++		long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2;
++		long cTB  = (bytes / (1000000000000LL / 200LL) + 1) / 2;
++		snprintf(buf, sizeof(buf), " (%ld.%02ld TiB %ld.%02ld TB)",
++			cTiB/100, cTiB % 100, cTB/100, cTB % 100);
+ 	}
+ 	return buf;
+ }
+@@ -922,13 +932,14 @@ char *human_size_brief(long long bytes, int prefix)
+ {
+ 	static char buf[30];
+ 
+-	/* We convert bytes to either centi-M{ega,ibi}bytes or
+-	 * centi-G{igi,ibi}bytes, with appropriate rounding,
+-	 * and then print 1/100th of those as a decimal.
++	/* We convert bytes to either centi-M{ega,ibi}bytes,
++	 * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes
++	 * with appropriate rounding, and then print
++	 * 1/100th of those as a decimal.
+ 	 * We allow upto 2048Megabytes before converting to
+-	 * gigabytes, as that shows more precision and isn't
++	 * gigabytes and 2048Gigabytes before converting to
++	 * terabytes, as that shows more precision and isn't
+ 	 * too large a number.
+-	 * Terabytes are not yet handled.
+ 	 *
+ 	 * If prefix == IEC, we mean prefixes like kibi,mebi,gibi etc.
+ 	 * If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc.
+@@ -941,10 +952,14 @@ char *human_size_brief(long long bytes, int prefix)
+ 			long cMiB = (bytes * 200LL / (1LL<<20) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldMiB",
+ 				 cMiB/100, cMiB % 100);
+-		} else {
++		} else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
+ 			long cGiB = (bytes * 200LL / (1LL<<30) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldGiB",
+ 				 cGiB/100, cGiB % 100);
++		} else {
++			long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2;
++			snprintf(buf, sizeof(buf), "%ld.%02ldTiB",
++				 cTiB/100, cTiB % 100);
+ 		}
+ 	}
+ 	else if (prefix == JEDEC) {
+@@ -952,10 +967,14 @@ char *human_size_brief(long long bytes, int prefix)
+ 			long cMB  = (bytes / ( 1000000LL / 200LL ) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldMB",
+ 				 cMB/100, cMB % 100);
+-		} else {
++		} else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
+ 			long cGB  = (bytes / (1000000000LL/200LL ) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldGB",
+ 				 cGB/100, cGB % 100);
++		} else {
++			long cTB  = (bytes / (1000000000000LL / 200LL) + 1) / 2;
++			snprintf(buf, sizeof(buf), "%ld.%02ldTB",
++				 cTB/100, cTB % 100);
+ 		}
+ 	}
+ 	else
+-- 
+2.7.5
+
diff --git a/SOURCES/0061-imsm-fill-working_disks-according-to-metadata.patch b/SOURCES/0061-imsm-fill-working_disks-according-to-metadata.patch
new file mode 100644
index 0000000..8171435
--- /dev/null
+++ b/SOURCES/0061-imsm-fill-working_disks-according-to-metadata.patch
@@ -0,0 +1,65 @@
+From 1e93d0d15913c3fa6d0de5af3fb5e4e3b3f068da Mon Sep 17 00:00:00 2001
+From: Blazej Kucman <blazej.kucman@intel.com>
+Date: Fri, 17 Jan 2020 15:24:04 +0100
+Subject: [RHEL8.2 PATCH 61/61] imsm: fill working_disks according to metadata.
+
+Imsm tracks as "working_disk" each visible drive.
+Assemble routine expects that the value will return count
+of active member drives recorded in metadata.
+As a side effect "--no-degraded" doesn't work correctly for imsm.
+Align this field to others.
+Added check, if the option --no-degraded is called with --scan.
+
+Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.c       | 9 ++++++---
+ super-intel.c | 5 ++---
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 256a97e..13dc24e 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1485,9 +1485,12 @@ int main(int argc, char *argv[])
+ 			rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
+ 		break;
+ 	case ASSEMBLE:
+-		if (devs_found == 1 && ident.uuid_set == 0 &&
+-		    ident.super_minor == UnSet && ident.name[0] == 0 &&
+-		    !c.scan ) {
++		if (!c.scan && c.runstop == -1) {
++			pr_err("--no-degraded not meaningful without a --scan assembly.\n");
++			exit(1);
++		} else if (devs_found == 1 && ident.uuid_set == 0 &&
++			   ident.super_minor == UnSet && ident.name[0] == 0 &&
++			   !c.scan) {
+ 			/* Only a device has been given, so get details from config file */
+ 			struct mddev_ident *array_ident = conf_get_ident(devlist->devname);
+ 			if (array_ident == NULL) {
+diff --git a/super-intel.c b/super-intel.c
+index 5c1f759..47809bc 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7946,7 +7946,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 				skip = 1;
+ 			if (!skip && (ord & IMSM_ORD_REBUILD))
+ 				recovery_start = 0;
+-
++			if (!(ord & IMSM_ORD_REBUILD))
++				this->array.working_disks++;
+ 			/*
+ 			 * if we skip some disks the array will be assmebled degraded;
+ 			 * reset resync start to avoid a dirty-degraded
+@@ -7988,8 +7989,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 				else
+ 					this->array.spare_disks++;
+ 			}
+-			if (info_d->recovery_start == MaxSector)
+-				this->array.working_disks++;
+ 
+ 			info_d->events = __le32_to_cpu(mpb->generation_num);
+ 			info_d->data_offset = pba_of_lba0(map);
+-- 
+2.7.5
+
diff --git a/SOURCES/0062-Remove-the-legacy-whitespace.patch b/SOURCES/0062-Remove-the-legacy-whitespace.patch
new file mode 100644
index 0000000..31c764a
--- /dev/null
+++ b/SOURCES/0062-Remove-the-legacy-whitespace.patch
@@ -0,0 +1,52 @@
+commit fd38b8ea80ff8e0317e12d1d70431148ceedd5fd
+Author: Xiao Ni <xni@redhat.com>
+Date:   Tue Feb 11 21:44:15 2020 +0800
+
+    Remove the legacy whitespace
+    
+    The whitespace between Environment= and the true value causes confusion.
+    To avoid confusing other people in future, remove the whitespace to keep
+    it a simple, unambiguous syntax
+    
+    Signed-off-by: Xiao Ni <xni@redhat.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
+index aa02dde..854317f 100644
+--- a/systemd/mdcheck_continue.service
++++ b/systemd/mdcheck_continue.service
+@@ -11,7 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_*
+ 
+ [Service]
+ Type=oneshot
+-Environment= "MDADM_CHECK_DURATION=6 hours"
++Environment="MDADM_CHECK_DURATION=6 hours"
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+ ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
+diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
+index da62d5f..3bb3d13 100644
+--- a/systemd/mdcheck_start.service
++++ b/systemd/mdcheck_start.service
+@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer
+ 
+ [Service]
+ Type=oneshot
+-Environment= "MDADM_CHECK_DURATION=6 hours"
++Environment="MDADM_CHECK_DURATION=6 hours"
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+ ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
+diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service
+index fd469b1..373955a 100644
+--- a/systemd/mdmonitor-oneshot.service
++++ b/systemd/mdmonitor-oneshot.service
+@@ -9,7 +9,7 @@
+ Description=Reminder for degraded MD arrays
+ 
+ [Service]
+-Environment=  MDADM_MONITOR_ARGS=--scan
++Environment=MDADM_MONITOR_ARGS=--scan
+ EnvironmentFile=-/run/sysconfig/mdadm
+ ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
+ ExecStart=BINDIR/mdadm --monitor --oneshot $MDADM_MONITOR_ARGS
diff --git a/SOURCES/mdadm-2.5.2-static.patch b/SOURCES/mdadm-2.5.2-static.patch
new file mode 100644
index 0000000..1eb335a
--- /dev/null
+++ b/SOURCES/mdadm-2.5.2-static.patch
@@ -0,0 +1,23 @@
+--- 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
+ 
+ install-static : mdadm.static install-man
+-	$(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm
++	$(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm.static
+ 
+ install-tcc : mdadm.tcc install-man
+-	$(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm
++	$(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm.tcc
+ 
+ install-uclibc : mdadm.uclibc install-man
+-	$(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm
++	$(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm.uclibc
+ 
+ install-klibc : mdadm.klibc install-man
+-	$(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm
++	$(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm.klibc
+ 
+ install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8
+ 	$(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8
diff --git a/SOURCES/mdadm-3.3-udev.patch b/SOURCES/mdadm-3.3-udev.patch
new file mode 100644
index 0000000..50c0074
--- /dev/null
+++ b/SOURCES/mdadm-3.3-udev.patch
@@ -0,0 +1,13 @@
+--- mdadm-4.1_rc1/udev-md-raid-assembly.rules~	2018-06-22 13:10:58.196250086 +0800
++++ mdadm-4.1_rc1/udev-md-raid-assembly.rules	2018-06-22 13:11:37.761241080 +0800
+@@ -5,6 +5,10 @@
+ ENV{ANACONDA}=="?*", GOTO="md_inc_end"
+ # assemble md arrays
+ 
++# In Fedora we handle the raid components in 65-md-incremental.rules so that
++# we can do things like honor anaconda command line options and such
++GOTO="md_inc_end"
++
+ SUBSYSTEM!="block", GOTO="md_inc_end"
+ 
+ # skip non-initialized devices
diff --git a/SOURCES/mdadm-cron b/SOURCES/mdadm-cron
new file mode 100644
index 0000000..4e05d68
--- /dev/null
+++ b/SOURCES/mdadm-cron
@@ -0,0 +1,3 @@
+# Run system wide raid-check once a week on Sunday at 1am by default
+0 1 * * Sun root /usr/sbin/raid-check
+
diff --git a/SOURCES/mdadm-raid-check-sysconfig b/SOURCES/mdadm-raid-check-sysconfig
new file mode 100644
index 0000000..8e82270
--- /dev/null
+++ b/SOURCES/mdadm-raid-check-sysconfig
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+# Configuration file for /etc/cron.weekly/raid-check
+#
+# options:
+#	ENABLED - must be yes in order for the raid check to proceed
+#	CHECK - can be either check or repair depending on the type of
+#		operation the user desires.  A check operation will scan
+#		the drives looking for bad sectors and automatically
+#		repairing only bad sectors.  If it finds good sectors that
+#		contain bad data (meaning that the data in a sector does
+#		not agree with what the data from another disk indicates
+#		the data should be, for example the parity block + the other
+#		data blocks would cause us to think that this data block
+#		is incorrect), then it does nothing but increments the
+#		counter in the file /sys/block/$dev/md/mismatch_count.
+#		This allows the sysadmin to inspect the data in the sector
+#		and the data that would be produced by rebuilding the
+#		sector from redundant information and pick the correct
+#		data to keep.  The repair option does the same thing, but
+#		when it encounters a mismatch in the data, it automatically
+#		updates the data to be consistent.  However, since we really
+#		don't know whether it's the parity or the data block that's
+#		correct (or which data block in the case of raid1), it's
+#		luck of the draw whether or not the user gets the right
+#		data instead of the bad data.  This option is the default
+#		option for devices not listed in either CHECK_DEVS or
+#		REPAIR_DEVS.
+#	CHECK_DEVS - a space delimited list of devs that the user specifically
+#		wants to run a check operation on.
+#	REPAIR_DEVS - a space delimited list of devs that the user
+#		specifically wants to run a repair on.
+#	SKIP_DEVS - a space delimited list of devs that should be skipped
+#	NICE - Change the raid check CPU and IO priority in order to make
+#		the system more responsive during lengthy checks.  Valid
+#		values are high, normal, low, idle.
+#	MAXCONCURENT - Limit the number of devices to be checked at a time.
+#		By default all devices will be checked at the same time.
+#
+# Note: the raid-check script intentionaly runs last in the cron.weekly
+# sequence.  This is so we can wait for all the resync operations to complete
+# and then check the mismatch_count on each array without unduly delaying
+# other weekly cron jobs.  If any arrays have a non-0 mismatch_count after
+# the check completes, we echo a warning to stdout which will then me emailed
+# to the admin as long as mails from cron jobs have not been redirected to
+# /dev/null.  We do not wait for repair operations to complete as the
+# md stack will correct any mismatch_cnts automatically.
+#
+# Note2: you can not use symbolic names for the raid devices, such as you
+# /dev/md/root.  The names used in this file must match the names seen in
+# /proc/mdstat and in /sys/block.
+
+ENABLED=yes
+CHECK=check
+NICE=low
+# To check devs /dev/md0 and /dev/md3, use "md0 md3"
+CHECK_DEVS=""
+REPAIR_DEVS=""
+SKIP_DEVS=""
+MAXCONCURRENT=
diff --git a/SOURCES/mdadm.conf b/SOURCES/mdadm.conf
new file mode 100644
index 0000000..3207dda
--- /dev/null
+++ b/SOURCES/mdadm.conf
@@ -0,0 +1 @@
+d /run/mdadm 0710 root root -
diff --git a/SOURCES/mdadm.rules b/SOURCES/mdadm.rules
new file mode 100644
index 0000000..b622c6b
--- /dev/null
+++ b/SOURCES/mdadm.rules
@@ -0,0 +1,69 @@
+# This file causes block devices with Linux RAID (mdadm) signatures to
+# automatically cause mdadm to be run.
+# See udev(8) for syntax
+
+# Don't process any events if anaconda is running as anaconda brings up
+# raid devices manually
+ENV{ANACONDA}=="?*", GOTO="md_end"
+
+# Also don't process disks that are slated to be a multipath device
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_end"
+
+# We process add events on block devices (since they are ready as soon as
+# they are added to the system), but we must process change events as well
+# on any dm devices (like LUKS partitions or LVM logical volumes) and on
+# md devices because both of these first get added, then get brought live
+# and trigger a change event.  The reason we don't process change events
+# on bare hard disks is because if you stop all arrays on a disk, then
+# run fdisk on the disk to change the partitions, when fdisk exits it
+# triggers a change event, and we want to wait until all the fdisks on
+# all member disks are done before we do anything.  Unfortunately, we have
+# no way of knowing that, so we just have to let those arrays be brought
+# up manually after fdisk has been run on all of the disks.
+
+# First, process all add events (md and dm devices will not really do
+# anything here, just regular disks, and this also won't get any imsm
+# array members either)
+SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \
+	IMPORT{program}="/sbin/mdadm -I $env{DEVNAME} --export $devnode --offroot ${DEVLINKS}"
+SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \
+	ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
+SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \
+	ENV{ID_FS_TYPE}=="linux_raid_member", \
+	RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
+SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \
+	ENV{ID_FS_TYPE}=="linux_raid_member", \
+	RUN+="/sbin/mdadm -If $name"
+
+# Next, check to make sure the BIOS raid stuff wasn't turned off via cmdline
+IMPORT{cmdline}="noiswmd"
+IMPORT{cmdline}="nodmraid"
+ENV{noiswmd}=="?*", GOTO="md_imsm_inc_end"
+ENV{nodmraid}=="?*", GOTO="md_imsm_inc_end"
+SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="isw_raid_member", \
+	RUN+="/sbin/mdadm -I $env{DEVNAME}"
+SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="ddf_raid_member", \
+	RUN+="/sbin/mdadm -I $env{DEVNAME}"
+SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \
+	ENV{ID_FS_TYPE}=="isw_raid_member", \
+	RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
+SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \
+	ENV{ID_FS_TYPE}=="isw_raid_member", \
+	RUN+="/sbin/mdadm -If $name"
+LABEL="md_imsm_inc_end"
+
+# Next make sure that this isn't a dm device we should skip for some reason
+ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="dm_change_end"
+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="dm_change_end"
+ENV{DM_SUSPENDED}=="1", GOTO="dm_change_end"
+KERNEL=="dm-*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \
+	ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}"
+LABEL="dm_change_end"
+
+# Finally catch any nested md raid arrays.  If we brought up an md raid
+# array that's part of another md raid array, it won't be ready to be used
+# until the change event that occurs when it becomes live
+KERNEL=="md*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \
+	ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}"
+
+LABEL="md_end"
diff --git a/SOURCES/mdadm_env.sh b/SOURCES/mdadm_env.sh
new file mode 100644
index 0000000..c13b48a
--- /dev/null
+++ b/SOURCES/mdadm_env.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# extract configuration from /etc/sysconfig/mdadm and write
+# environment to /run/sysconfig/mdadm to be used by
+# systemd unit files.
+
+MDADM_SCAN="yes"
+
+# Following adapted from /etc/init.d/mdadmd on openSUSE
+
+mdadmd_CONFIG=/etc/sysconfig/mdadm
+if test -r $mdadmd_CONFIG; then
+   . $mdadmd_CONFIG
+fi
+
+if [ x$MDADM_DELAY != x"" ]; then
+  MDADM_DELAY="-d "$MDADM_DELAY;
+fi
+
+if [ x$MDADM_MAIL != x"" ]; then
+  MDADM_MAIL="-m \"$MDADM_MAIL\""
+fi
+
+if [ x$MDADM_PROGRAM != x"" ]; then
+  MDADM_PROGRAM="-p \"$MDADM_PROGRAM\""
+fi
+
+if [ x$MDADM_SCAN = x"yes" ]; then
+  MDADM_SCAN="--scan"
+else
+  MDADM_SCAN=""
+fi
+
+if [ x$MDADM_SEND_MAIL_ON_START = x"yes" ]; then
+  MDADM_SEND_MAIL="-t"
+else
+  MDADM_SEND_MAIL=""
+fi
+
+if [ x$MDADM_CONFIG != x"" ]; then
+  MDADM_CONFIG="-c \"$MDADM_CONFIG\""
+fi
+
+mkdir -p /run/sysconfig
+echo "MDADM_MONITOR_ARGS=$MDADM_RAIDDEVICES $MDADM_DELAY $MDADM_MAIL $MDADM_PROGRAM $MDADM_SCAN $MDADM_SEND_MAIL $MDADM_CONFIG" > /run/sysconfig/mdadm
+if [ -n "$MDADM_CHECK_DURATION" ]; then
+ echo "MDADM_CHECK_DURATION=$MDADM_CHECK_DURATION" >> /run/sysconfig/mdadm
+fi
diff --git a/SOURCES/mdadm_event.conf b/SOURCES/mdadm_event.conf
new file mode 100644
index 0000000..1a6c479
--- /dev/null
+++ b/SOURCES/mdadm_event.conf
@@ -0,0 +1,5 @@
+# Save /proc/mdstat in case of crash in mdadm/mdmon
+
+EVENT=post-create component=mdadm
+	cat /proc/mdstat >> mdstat_data
+	echo "Saved output of /proc/mdstat"
diff --git a/SOURCES/mdcheck b/SOURCES/mdcheck
new file mode 100644
index 0000000..42d4094
--- /dev/null
+++ b/SOURCES/mdcheck
@@ -0,0 +1,164 @@
+#!/bin/bash
+
+# Copyright (C) 2014-2017 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.
+#
+#    Author: Neil Brown
+#    Email: <neilb@suse.com>
+
+# This script should be run periodically to automatically
+# perform a 'check' on any md arrays.
+#
+# It supports a 'time budget' such that any incomplete 'check'
+# will be checkpointed when that time has expired.
+# A subsequent invocation can allow the 'check' to continue.
+#
+# Options are:
+#   --continue    Don't start new checks, only continue old ones.
+#   --duration    This is passed to "date --date=$duration" to find out
+#		  when to finish
+#
+# To support '--continue', arrays are identified by UUID and the 'sync_completed'
+# value is stored  in /var/lib/mdcheck/$UUID
+
+# convert a /dev/md name into /sys/.../md equivalent
+sysname() {
+	set `ls -lLd $1`
+	maj=${5%,}
+	min=$6
+	readlink -f /sys/dev/block/$maj:$min
+}
+
+args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@")
+rv=$?
+if [ $rv -ne 0 ]; then exit $rv; fi
+
+eval set -- $args
+
+cont=
+endtime=
+while [ " $1" != " --" ]
+do
+    case $1 in
+	--help )
+		echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]'
+		echo >&2 '  time-offset must be understood by "date --date"'
+		exit 0
+		;;
+	--continue ) cont=yes ;;
+	--duration ) shift; dur=$1
+		endtime=$(date --date "$dur" "+%s")
+		;;
+    esac
+    shift
+done
+shift
+
+# We need a temp file occasionally...
+tmp=/var/lib/mdcheck/.md-check-$$
+trap 'rm -f "$tmp"' 0 2 3 15
+
+
+# firstly, clean out really old state files
+mkdir -p /var/lib/mdcheck
+find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \;
+
+# Now look at each md device.
+cnt=0
+for dev in /dev/md?*
+do
+	[ -e "$dev" ] || continue
+	sys=`sysname $dev`
+	if [ ! -f "$sys/md/sync_action" ]
+	then # cannot check this array
+		continue
+	fi
+	if [ "`cat $sys/md/sync_action`" != 'idle' ]
+	then # This array is busy
+		continue
+	fi
+
+	mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue
+	source $tmp
+	fl="/var/lib/mdcheck/MD_UUID_$MD_UUID"
+	if [ -z "$cont" ]
+	then
+		start=0
+		logger -p daemon.info mdcheck start checking $dev
+	elif [ -z "$MD_UUID" -o ! -f "$fl" ]
+	then
+		# Nothing to continue here
+		continue
+	else
+		start=`cat "$fl"`
+		logger -p daemon.info mdcheck continue checking $dev from $start
+	fi
+
+	cnt=$[cnt+1]
+	eval MD_${cnt}_fl=\$fl
+	eval MD_${cnt}_sys=\$sys
+	eval MD_${cnt}_dev=\$dev
+	echo $start > $fl
+	echo $start > $sys/md/sync_min
+	echo check > $sys/md/sync_action
+done
+
+if [ -z "$endtime" ]
+then
+	exit 0
+fi
+
+while [ `date +%s` -lt $endtime ]
+do
+	any=
+	for i in `eval echo {1..$cnt}`
+	do
+		eval fl=\$MD_${i}_fl
+		eval sys=\$MD_${i}_sys
+
+		if [ -z "$fl" ]; then continue; fi
+
+		if [ "`cat $sys/md/sync_action`" != 'check' ]
+		then
+			eval MD_${i}_fl=
+			rm -f $fl
+			continue;
+		fi
+		read a rest < $sys/md/sync_completed
+		echo $a > $fl
+		any=yes
+	done
+	if [ -z "$any" ]; then exit 0; fi
+	sleep 120
+done
+
+# We've waited, and there are still checks running.
+# Time to stop them.
+for i in `eval echo {1..$cnt}`
+do
+	eval fl=\$MD_${i}_fl
+	eval sys=\$MD_${i}_sys
+	eval dev=\$MD_${i}_dev
+
+	if [ -z "$fl" ]; then continue; fi
+
+	if [ "`cat $sys/md/sync_action`" != 'check' ]
+	then
+		eval MD_${i}_fl=
+		rm -f $fl
+		continue;
+	fi
+	echo idle > $sys/md/sync_action
+	cat $sys/md/sync_min > $fl
+	logger -p daemon.info pause checking $dev at `cat $fl`
+done
diff --git a/SOURCES/mdmonitor.init b/SOURCES/mdmonitor.init
new file mode 100755
index 0000000..03f3e95
--- /dev/null
+++ b/SOURCES/mdmonitor.init
@@ -0,0 +1,118 @@
+#!/bin/bash
+# 
+# mdmonitor	This starts, stops, and reloads the mdadm-based
+#		software RAID monitoring and management facility
+#
+# chkconfig: 2345 15 85
+# description: software RAID monitoring and management
+# config: /etc/mdadm.conf
+#
+# Copyright 2002 Red Hat, Inc.
+#
+### BEGIN INIT INFO
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Start and stop the MD software RAID monitor
+# Description: The mdmonitor service checks the status of all software
+#	RAID arrays on the system.  In the event that any of the arrays
+#	transition into a degraded state, it notifies the system
+#	administrator.  Other options are available, see the mdadm.conf
+#	and mdadm man pages for possible ways to configure this service.
+### END INIT INFO
+
+PIDPATH=/var/run/mdadm
+PIDFILE=/var/run/mdadm/mdadm.pid
+PATH=/sbin:/usr/sbin:$PATH
+RETVAL=0
+OPTIONS="--monitor --scan -f --pid-file=$PIDFILE"
+
+prog=mdmonitor
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+
+usage ()
+{
+    echo "Usage: service $prog {start|stop|status|restart|try-restart|force-reload}"
+    RETVAL=1
+}
+
+
+start ()
+{
+# (Re)start mdmon to take over monitoring of mdmon started from the initrd
+    for i in /dev/md/*.pid; do
+	if [ -r $i ]; then
+            origprog="$prog"; prog="mdmon"
+            action $"Starting $prog: " /sbin/mdmon --takeover --all
+            prog="$origprog"
+	    break
+        fi
+    done
+# Make sure configuration file exists and has information we can use
+# MAILADDR or PROGRAM or both must be set in order to run mdadm --monitor
+    [ -f /etc/mdadm.conf ] || return 6
+    grep '^\(MAILADDR\|PROGRAM\) .' /etc/mdadm.conf >/dev/null 2>&1 || return 6
+    # Create our directory if it isn't there yet
+    if [ ! -d $PIDPATH ]; then
+        mkdir -m 0700 $PIDPATH >&/dev/null
+	RC=$?
+	[ -x /sbin/restorecon ] && /sbin/restorecon $PIDPATH
+	if [ $RC -ne 0 ]; then
+	    echo -n "Failed to create /var/run/mdadm"
+            failure
+	    echo
+	    return 1
+	fi
+    fi
+    if [ -f "$PIDFILE" ]; then
+	checkpid `cat $PIDFILE` && return 0
+    fi
+    echo -n $"Starting $prog: "
+    cd /
+    daemon --user=root mdadm ${OPTIONS}
+    ret=$?
+    [ $ret -eq "0" ] && touch /var/lock/subsys/$prog
+    echo
+    return $ret
+}
+
+stop ()
+{
+    [ -f /var/lock/subsys/$prog ] || return 0
+    echo -n "Killing $prog: "
+    killproc mdadm
+    echo
+    rm -f $PIDFILE
+    rm -f /var/lock/subsys/$prog
+}
+
+restart ()
+{
+    stop
+    start
+}
+
+condrestart ()
+{
+    [ -e /var/lock/subsys/$prog ] && restart || return 0
+}
+
+
+case "$1" in
+    start|stop|restart|condrestart|try-restart|force-reload)
+    	[ `id -u` != "0" ] && exit 4 ;;
+esac
+
+case "$1" in
+    start) start; RETVAL=$? ;;
+    stop) stop; RETVAL=$? ;;
+    status) status -p $PIDFILE $prog ; RETVAL=$? ;;
+    restart) restart; RETVAL=$? ;;
+    reload) RETVAL=3 ;;
+    condrestart|try-restart|force-reload) condrestart; RETVAL=$? ;;
+    *) usage ; RETVAL=2 ;;
+esac
+
+exit $RETVAL
diff --git a/SOURCES/mdmonitor.service b/SOURCES/mdmonitor.service
new file mode 100644
index 0000000..123ae8a
--- /dev/null
+++ b/SOURCES/mdmonitor.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Software RAID monitoring and management
+ConditionPathExists=/etc/mdadm.conf
+
+[Service]
+Type=forking
+PIDFile=/var/run/mdadm/mdadm.pid
+EnvironmentFile=-/etc/sysconfig/mdmonitor
+ExecStart=/sbin/mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/raid-check b/SOURCES/raid-check
new file mode 100644
index 0000000..7b2fb59
--- /dev/null
+++ b/SOURCES/raid-check
@@ -0,0 +1,135 @@
+#!/bin/bash
+#
+# This script reads it's configuration from /etc/sysconfig/raid-check
+# Please use that file to enable/disable this script or to set the
+# type of check you wish performed.
+
+# We might be on a kernel with no raid support at all, exit if so
+[ -f /proc/mdstat ] || exit 0
+
+# and exit if we haven't been set up properly
+[ -f /etc/sysconfig/raid-check ] || exit 0
+. /etc/sysconfig/raid-check
+
+# Wait until no more than arg1 arrays in arg2 list are busy
+waitbusy() {
+    local threshold=$(($1 + 1))
+    local dev_list="$2"
+    while true
+    do
+	local busy=0
+	local dev=""
+	for dev in $dev_list; do
+	    local sync_action=`cat /sys/block/$dev/md/sync_action`
+	    if [ "$sync_action" != "idle" ]; then
+		let busy++
+	    fi
+	done
+        [ $busy -lt $threshold ] && break
+	sleep 60
+    done
+}
+
+[ "$ENABLED" != "yes" ] && exit 0
+
+case "$CHECK" in
+    check) ;;
+    repair) ;;
+    *) exit 0;;
+esac
+
+ionice=""
+renice=""
+case $NICE in
+    high)
+	renice="-n -5"
+	;;
+    low)
+	renice="-n 5"
+	ionice="-c2 -n7"
+	;;
+    idle)
+	renice="-n 15"
+	ionice="-c3"
+	;;
+    *)
+	;;
+esac
+
+active_list=`grep "^md.*: active" /proc/mdstat | cut -f 1 -d ' '`
+[ -z "$active_list" ] && exit 0
+
+declare -A check
+dev_list=""
+check_list=""
+for dev in $active_list; do
+    echo $SKIP_DEVS | grep -w $dev >&/dev/null && continue
+    if [ -f /sys/block/$dev/md/sync_action ]; then
+	# Only perform the checks on idle, healthy arrays, but delay
+	# actually writing the check field until the next loop so we
+	# don't switch currently idle arrays to active, which happens
+	# when two or more arrays are on the same physical disk
+	array_state=`cat /sys/block/$dev/md/array_state`
+	if [ "$array_state" != "clean" -a "$array_state" != "active" ]; then
+	    continue
+	fi
+	sync_action=`cat /sys/block/$dev/md/sync_action`
+	if [ "$sync_action" != idle ]; then
+	    continue
+	fi
+	ck=""
+	echo $REPAIR_DEVS | grep -w $dev >&/dev/null && ck="repair"
+	echo $CHECK_DEVS | grep -w $dev >&/dev/null && ck="check"
+	[ -z "$ck" ] && ck=$CHECK
+	dev_list="$dev_list $dev"
+	check[$dev]=$ck
+	[ "$ck" = "check" ] && check_list="$check_list $dev"
+    fi
+done
+[ -z "$dev_list" ] && exit 0
+
+for dev in $dev_list; do
+    #Only run $MAXCONCURRENT checks at a time
+    if [ -n "$MAXCONCURRENT" ]; then
+	waitbusy $((MAXCONCURRENT - 1)) "$dev_list"
+    fi
+    echo "${check[$dev]}" > /sys/block/$dev/md/sync_action
+
+    resync_pid=""
+    wait=10
+    while [ $wait -gt 0 -a -z "$resync_pid" ]; do
+	sleep 6
+	let wait--
+	resync_pid=$(ps -ef | awk -v mddev=$dev 'BEGIN { pattern = "^\\[" mddev "_resync]$" } $8 ~ pattern { print $2 }')
+    done
+    [ -n "$resync_pid" -a -n "$renice" ] &&
+    	renice $renice -p $resync_pid >&/dev/null
+    [ -n "$resync_pid" -a -n "$ionice" ] &&
+    	ionice $ionice -p $resync_pid >&/dev/null
+done
+[ -z "$check_list" ] && exit 0
+
+waitbusy 0 "$check_list"
+
+for dev in $check_list; do
+	mismatch_cnt=`cat /sys/block/$dev/md/mismatch_cnt`
+	# Due to the fact that raid1/10 writes in the kernel are unbuffered,
+	# a raid1 array can have non-0 mismatch counts even when the
+	# array is healthy.  These non-0 counts will only exist in
+	# transient data areas where they don't pose a problem.  However,
+	# since we can't tell the difference between a non-0 count that
+	# is just in transient data or a non-0 count that signifies a
+	# real problem, simply don't check the mismatch_cnt on raid1
+	# devices as it's providing far too many false positives.  But by
+	# leaving the raid1 device in the check list and performing the
+	# check, we still catch and correct any bad sectors there might
+	# be in the device.
+	raid_lvl=`cat /sys/block/$dev/md/level`
+	if [ "$raid_lvl" = "raid1" -o "$raid_lvl" = "raid10" ]; then
+	    continue
+	fi
+	if [ "$mismatch_cnt" -ne 0 ]; then
+		echo "WARNING: mismatch_cnt is not 0 on /dev/$dev"
+	fi
+done
+
diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec
new file mode 100644
index 0000000..98733d2
--- /dev/null
+++ b/SPECS/mdadm.spec
@@ -0,0 +1,1232 @@
+Summary:     The mdadm program controls Linux md devices (software RAID arrays)
+Name:        mdadm
+Version:     4.1
+Release:     13%{?dist}
+Source:      http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz
+Source1:     mdmonitor.init
+Source2:     raid-check
+Source3:     mdadm.rules
+Source4:     mdadm-raid-check-sysconfig
+Source5:     mdadm-cron
+Source6:     mdmonitor.service
+Source7:     mdadm.conf
+Source8:     mdadm_event.conf
+Source9:     mdcheck
+Source10:    mdadm_env.sh
+
+Patch1:      0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch
+Patch2:      0002-Document-PART-POLICY-lines.patch
+Patch3:      0003-policy-support-devices-with-multiple-paths.patch
+Patch4:      0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch
+Patch5:      0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch
+Patch6:      0006-imsm-update-metadata-correctly-while-raid10-double-d.patch
+Patch7:      0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch
+Patch8:      0008-Grow-avoid-overflow-in-compute_backup_blocks.patch
+Patch9:      0009-Grow-report-correct-new-chunk-size.patch
+Patch10:     0010-policy.c-prevent-NULL-pointer-referencing.patch
+Patch11:     0011-policy.c-Fix-for-compiler-error.patch
+Patch12:     0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch
+Patch13:     0013-imsm-fix-reshape-for-2TB-drives.patch
+Patch14:     0014-Fix-spelling-typos.patch
+Patch15:     0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch
+Patch16:     0016-Fix-reshape-for-decreasing-data-offset.patch
+Patch17:     0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch
+Patch18:     0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch
+Patch19:     0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch
+Patch20:     0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch
+Patch21:     0021-add-missing-units-to-examine.patch
+Patch22:     0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch
+Patch23:     0023-Create-Block-rounding-size-to-max.patch
+Patch24:     0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch
+Patch25:     0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch
+Patch26:     0026-Enable-probe_roms-to-scan-more-than-6-roms.patch
+Patch27:     0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch
+Patch28:     0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch
+Patch29:     0029-super-intel-Use-put_unaligned-in-split_ull.patch
+Patch30:     0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch
+Patch31:     0031-mdadm.h-include-sysmacros.h-unconditionally.patch
+Patch32:     0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch
+Patch33:     0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch
+Patch34:     0034-imsm-close-removed-drive-fd.patch
+Patch35:     0035-mdadm-check-value-returned-by-snprintf-against-error.patch
+Patch36:     0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch
+Patch37:     0037-mdadm-force-a-uuid-swap-on-big-endian.patch
+Patch38:     0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch
+Patch39:     0039-Init-devlist-as-an-array.patch
+Patch40:     0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch
+Patch41:     0041-udev-allow-for-udev-attribute-reading-bug.patch
+Patch42:     0042-imsm-save-current_vol-number.patch
+Patch43:     0043-imsm-allow-to-specify-second-volume-size.patch
+Patch44:     0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch
+Patch45:     0045-mdcheck-use-to-pass-variable-to-mdcheck.patch
+Patch46:     0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch
+Patch47:     0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch
+Patch48:     0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch
+Patch49:     0049-Remove-last-traces-of-HOT_ADD_DISK.patch
+Patch50:     0050-Fix-up-a-few-formatting-issues.patch
+Patch51:     0051-Remove-unused-code.patch
+Patch52:     0052-imsm-return-correct-uuid-for-volume-in-detail.patch
+Patch53:     0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch
+Patch54:     0054-Create-add-support-for-RAID0-layouts.patch
+Patch55:     0055-Assemble-add-support-for-RAID0-layouts.patch
+Patch56:     0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch
+Patch57:     0057-Change-warning-message.patch
+Patch58:     0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch
+Patch59:     0059-imsm-Update-grow-manual.patch
+Patch60:     0060-Add-support-for-Tebibytes.patch
+Patch61:     0061-imsm-fill-working_disks-according-to-metadata.patch
+Patch62:     0062-Remove-the-legacy-whitespace.patch
+
+# RHEL customization patches
+Patch97:     mdadm-3.3-udev.patch
+Patch98:     mdadm-2.5.2-static.patch
+
+URL:         http://www.kernel.org/pub/linux/utils/raid/mdadm/
+License:     GPLv2+
+Group:       System Environment/Base
+BuildRoot:   %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Obsoletes:   mdctl,raidtools
+Obsoletes:   mdadm-sysvinit
+Conflicts:   dracut < 034-1
+Requires(post): systemd-units chkconfig coreutils
+BuildRequires: systemd-units binutils-devel
+Requires(preun): systemd-units
+Requires(postun): systemd-units coreutils
+Requires: libreport-filesystem
+
+%define _hardened_build 1
+
+%description 
+The mdadm program is used to create, manage, and monitor Linux MD (software
+RAID) devices.  As such, it provides similar functionality to the raidtools
+package.  However, mdadm is a single program, and it can perform
+almost all functions without a configuration file, though a configuration
+file can be used to help with some common tasks.
+
+%prep
+%setup -q
+
+%patch1 -p1 -b .0001
+%patch2 -p1 -b .0002
+%patch3 -p1 -b .0003
+%patch4 -p1 -b .0004
+%patch5 -p1 -b .0005
+%patch6 -p1 -b .0006
+%patch7 -p1 -b .0007
+%patch8 -p1 -b .0008
+%patch9 -p1 -b .0009
+%patch10 -p1 -b .0010
+%patch11 -p1 -b .0011
+%patch12 -p1 -b .0012
+%patch13 -p1 -b .0013
+%patch14 -p1 -b .0014
+%patch15 -p1 -b .0015
+%patch16 -p1 -b .0016
+%patch17 -p1 -b .0017
+%patch18 -p1 -b .0018
+%patch19 -p1 -b .0019
+%patch20 -p1 -b .0020
+%patch21 -p1 -b .0021
+%patch22 -p1 -b .0022
+%patch23 -p1 -b .0023
+%patch24 -p1 -b .0024
+%patch25 -p1 -b .0025
+%patch26 -p1 -b .0026
+%patch27 -p1 -b .0027
+%patch28 -p1 -b .0028
+%patch29 -p1 -b .0029
+%patch30 -p1 -b .0030
+%patch31 -p1 -b .0031
+%patch32 -p1 -b .0032
+%patch33 -p1 -b .0033
+%patch34 -p1 -b .0034
+%patch35 -p1 -b .0035
+%patch36 -p1 -b .0036
+%patch37 -p1 -b .0037
+%patch38 -p1 -b .0038
+%patch39 -p1 -b .0039
+%patch40 -p1 -b .0040
+%patch41 -p1 -b .0041
+%patch42 -p1 -b .0042
+%patch43 -p1 -b .0043
+%patch44 -p1 -b .0044
+%patch45 -p1 -b .0045
+%patch46 -p1 -b .0046
+%patch47 -p1 -b .0047
+%patch48 -p1 -b .0048
+%patch49 -p1 -b .0049
+%patch50 -p1 -b .0050
+%patch51 -p1 -b .0051
+%patch52 -p1 -b .0052
+%patch53 -p1 -b .0053
+%patch54 -p1 -b .0054
+%patch55 -p1 -b .0055
+%patch56 -p1 -b .0056
+%patch57 -p1 -b .0057
+%patch58 -p1 -b .0058
+%patch59 -p1 -b .0059
+%patch60 -p1 -b .0060
+%patch61 -p1 -b .0061
+%patch62 -p1 -b .0062
+
+# RHEL customization patches
+%patch97 -p1 -b .udev
+%patch98 -p1 -b .static
+
+%build
+make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon
+
+%install
+rm -rf %{buildroot}
+make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} install install-systemd
+install -Dp -m 755 %{SOURCE2} %{buildroot}%{_sbindir}/raid-check
+install -Dp -m 644 %{SOURCE3} %{buildroot}%{_udevrulesdir}/65-md-incremental.rules
+install -Dp -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/raid-check
+install -Dp -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/raid-check
+mkdir -p -m 710 %{buildroot}/var/run/mdadm
+mkdir -p -m 700 %{buildroot}/usr/share/mdadm
+mkdir -p -m 700 %{buildroot}/usr/lib/mdadm
+install -Dp -m 755 %{SOURCE9} %{buildroot}/usr/share/mdadm/mdcheck
+install -Dp -m 755 %{SOURCE10} %{buildroot}/usr/lib/mdadm/mdadm_env.sh
+
+# systemd
+mkdir -p %{buildroot}%{_unitdir}
+install -m644 %{SOURCE6} %{buildroot}%{_unitdir}
+
+# tmpfile
+mkdir -p %{buildroot}%{_tmpfilesdir}
+install -m 0644 %{SOURCE7} %{buildroot}%{_tmpfilesdir}/%{name}.conf
+mkdir -p %{buildroot}%{_localstatedir}/run/
+install -d -m 0710 %{buildroot}%{_localstatedir}/run/%{name}/
+
+# abrt
+mkdir -p %{buildroot}/etc/libreport/events.d
+install -m644 %{SOURCE8} %{buildroot}/etc/libreport/events.d
+
+%clean
+rm -rf %{buildroot}
+
+%post
+%systemd_post mdmonitor.service
+/usr/bin/systemctl disable mdmonitor-takeover.service  >/dev/null 2>&1 || :
+
+%preun
+%systemd_preun mdmonitor.service
+
+%postun
+%systemd_postun_with_restart mdmonitor.service
+
+%triggerun --  %{name} < 3.2.2-3
+%{_bindir}/systemd-sysv-convert --save mdmonitor >/dev/null 2>&1 || :
+/bin/systemctl --no-reload enable mdmonitor.service  >/dev/null 2>&1 || :
+/sbin/chkconfig --del mdmonitor >/dev/null 2>&1 || :
+/bin/systemctl try-restart mdmonitor.service >/dev/null 2>&1 || :
+
+%files
+%defattr(-,root,root,-)
+%doc TODO ChangeLog mdadm.conf-example COPYING misc/*
+%{_udevrulesdir}/*
+%{_sbindir}/*
+%{_unitdir}/*
+%{_mandir}/man*/md*
+/usr/lib/systemd/system-shutdown/*
+%config(noreplace) %{_sysconfdir}/cron.d/*
+%config(noreplace) %{_sysconfdir}/sysconfig/*
+%dir %{_localstatedir}/run/%{name}/
+%config(noreplace) %{_tmpfilesdir}/%{name}.conf
+/etc/libreport/events.d/*
+/usr/share/mdadm/mdcheck
+/usr/lib/mdadm/mdadm_env.sh
+
+%changelog
+* Fri Feb 28 2020 Xiao Ni <xni@redhat.com> - 4.1.13
+- Remove the unnecessary whitespace in .service file
+- Resolves rhbz#1803470
+
+* Tue Feb 11 2020 Xiao Ni <xni@redhat.com> - 4.1.12
+- Update mdadm to latest upstream && change tmpfiles directory && correct changelog date
+- Resolves rhbz#1800521 and rhbz#1657265
+
+* Sun Feb 09 2020 Xiao Ni <xni@redhat.com> - 4.1.11
+- mdcheck start service can't start
+- Resolves rhbz#1769823
+
+* Fri Nov 15 2019 Xiao Ni <xni@redhat.com> - 4.1.10
+- Update mdadm to latest upstream
+- Resolves rhbz#1721937
+
+* Wed Jul 10 2019 Xiao Ni <xni@redhat.com> - 4.1.9
+- Add --incremental for ddf member disk in udev rule
+- Resolves rhbz#1693583
+
+* Thu Jun 13 2019 Xiao Ni <xni@redhat.com> - 4.1.8
+- Update to latest upstream
+- Resolves rhbz#1661203
+
+* Wed Jun 12 2019 Xiao Ni <xni@redhat.com> - 4.1.7
+- Fix gating test error
+- Resolves rhbz#1682396
+
+* Thu May 23 2019 Xiao Ni <xni@redhat.com> - 4.1.6
+- Enable raid5 journal
+- Resolves rhbz#1691202
+
+* Fri Apr 12 2019 Xiao Ni <xni@redhat.com> - 4.1.5
+- add gating tests
+- Resolves rhbz#1682396
+
+* Fri Jan 11 2019 Xiao Ni <xni@redhat.com> - 4.1.4
+- Disable raid5 journal
+- Resolves rhbz#1664961
+
+* Fri Dec 21 2018 Xiao Ni <xni@redhat.com> - 4.1.3
+- Recovery isn't noticed while raid10 double degradation
+- Resolves rhbz#1654482
+
+* Wed Dec 12 2018 Xiao Ni <xni@redhat.com> - 4.1.2
+- Add warning message for using raid1 cluster
+- Resolves rhbz#1654482
+
+* Fri Oct 26 2018 Xiao Ni <xni@redhat.com> - 4.1.1
+- Update to upstream 4.1
+- Resolves rhbz#1642206
+
+* Wed Oct 24 2018 Xiao Ni <xni@redhat.com> - 4.1-rc1-3
+- Can't find md device when install rhel8
+- Resolves rhbz#1628774
+
+* Thu Aug 16 2018 Xiao Ni <xni@redhat.com> - 4.1-rc1-2
+- Fix two IMSM bugs
+- Resolves rhbz#1602420 and rhbz#1602422
+
+* Fri Jun 22 2018 Xiao Ni <xni@redhat.com> - 4.1-rc1-1
+- Upgrade to upstream mdadm-4.1-rc1
+- Resolves rhbz#1493605 and rhbz#1494477 and rhbz#1502118
+
+* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 4.0-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 4.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Wed Apr 26 2017 Xiao Ni <xni@redhat.com> - 4.0-3
+- Fix building errors against newer gcc (>=7.0)
+- Resolves bz1444756
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 4.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Jan 12 2017 Xiao Ni <xni@redhat.com> - 4.0-1
+- Upgrade to mdadm-4.0 
+- Resolves bz1411555
+
+* Mon Aug 15 2016 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.4-3
+- Fix build against newer glibc (Fedora 26+)
+
+* Fri Aug 12 2016 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.4-2
+- Fix i686 build error
+- Fix problem where it was not possible to stop an IMSM array during reshape
+- Fix Degraded Raid1 array becomes inactive after rebooting
+- Fix problem with raid0 arrays not being detected by Anaconda due to it
+  setting MALLOC_PERTURB_
+- Fix problem with reshaping IMSM arrays, where a new reshape could be
+  launched before the first reshape had fully completed, leading to
+  unpected results.
+- Fix problem with mdadm large device names overflowing an internal buffer
+- Fix problem about reshape stuck at beginning
+- Resolves bz1303380
+
+* Fri Aug 12 2016 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.4-1
+- Upgrade to mdadm-3.4
+- Resolves bz1303380
+
+* Mon May 30 2016 Xiao Ni <xni@redhat.com> - 3.3.4-4
+- Fix Degraded Raid1 array becomes inactive after rebooting
+- Resolves bz1337004
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 3.3.4-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Mon Oct 5 2015 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.4-2
+- Fix race when assembling or stopping IMSM RAID arrays
+- Resolves bz1268955
+
+* Mon Oct 5 2015 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.4-1
+- Upgrade to mdadm-3.3.4
+- Resolves bz1246474
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Tue Aug 26 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.2-1
+- Upgrade to mdadm-3.3.2
+- Resolves bz1132847
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3.1-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Tue Aug 5 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.1-6
+- Apply proper fix for bz1125883, clean up after rogue patch application
+- Resolves bz1125883
+
+* Mon Aug 04 2014 Dan Horák <dan[at]danny.cz> - 3.3.1-5
+- revert the previous fix, not upstream yet
+
+* Mon Aug 04 2014 Dan Horák <dan[at]danny.cz> - 3.3.1-4
+- fix FTBFS on ppc64 (#1125883)
+
+* Tue Jul 29 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.1-3
+- Improve error message for "--grow -n2" when used on Linear arrays
+- Fix problem where explicitly specified arrays were not assembled if
+  they were disabled in /etc/mdadm.conf
+- Resolves bz1122146, bz1124310
+
+* Thu Jun 12 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.1-2
+- Revert 'change' event support fix from 3.3.1-1 - this requires a lot
+  more testing if we are to go there.
+
+* Tue Jun 10 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3.1-1
+- Update to mdadm-3.3.1
+- Fixup mdadm.rules to honor 'change' events
+- Resolvez bz1105136
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.3-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Fri Mar 14 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-7
+- Don't depend on syslog.target in mdmonitor.service
+- Resolves bz1055202
+
+* Fri Jan 31 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-6
+- Revert changes introduced in 3.3-5, they were based on incorrect
+  recommendations.
+- Resolves bz1053176
+
+* Thu Jan 30 2014 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-5
+- Do not create /var/run/mdadm in the rpm file, since this is sitting on
+  tmpfs and is created by tmpfiles during boot.
+- Resolves bz1053176
+
+* Thu Oct 10 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-4
+- Fix byteswap macros return types to allow for building on big endian
+  architectures again.
+- Resolves bz1015494
+
+* Wed Oct 9 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-3
+- Check for DM_UDEV_DISABLE_OTHER_RULES_FLAG instead of
+  DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules 
+- Resolves bz1015521
+
+* Tue Oct 8 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-2
+- Fix dracut requirement, minimum version 034-1
+
+* Thu Sep 5 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.3-1
+- Update to mdadm-3.3
+- Resolves bz977826
+
+* Tue Aug 13 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-21
+- Fix pointless rpmbuild noise over mismatching date info
+- Remove Fedora 17 support
+- Fix problem where first stop command doesn't stop container during
+  IMSM volume's reshape bz956053 (f18), bz956056 (f19)
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.6-20
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Wed Apr 24 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-19
+- Fix problem where  rebuild of IMSM RAID5 volume started in OROM,
+  does not proceed in OS 
+- Resolves bz956021 (f18), bz956026 (f17), bz956031 (f19)
+
+* Tue Apr 23 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-18
+- Fix problem with IMSM metadata where resync progress would be lost
+  if an array was stopped during ongoing expansion of a RAID1/5 volume.
+- Resolves bz948745
+
+* Tue Apr 23 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-17
+- Reorder patches to allow for udev query patch to be applied on
+  Fedora 17 as well.
+
+* Mon Apr 22 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-16
+- Rely on rpm macros to place files in correct directories, and match /usr
+  move
+- Resolves bz955248
+
+* Thu Mar 7 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-15
+- Cleanup .spec file handling of different Fedora versions
+- Resolves bz914629
+
+* Tue Feb 5 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-14
+- Resync with final version of upstream patches for launching mdmon
+  via systemctl. Require dracut 024-025 or later to match.
+- Resolves bz879327
+
+* Fri Feb 1 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-13
+- Update to upstream solution for launching mdmon via systemctl
+- Resolves bz879327
+
+* Mon Jan 21 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-12
+- Launch mdmon via systemctl to avoid it ending up in the wrong cgroup
+  and getting killed in the boot process when switching from the
+  initrd to the real root.
+- Resolves bz879327
+
+* Tue Jan 8 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-11
+- Move code to leave udev cgroup into mdmon and excute it after we
+  work, to make sure it actually does the right thing.
+
+* Mon Jan 7 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-10
+- Fix mdmonitor-takeover.service dangling symlink problem for real
+
+* Mon Jan 7 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-9
+- Reintroduce fix for removing dangling symlink of
+  mdmonitor-takeover.service which got lost in the fix introduced in
+  3.2.6-8
+
+* Fri Jan 4 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-8
+- mdmonitor-takeover.service is obsolete with the --offroot support,
+  and it is harmful as of 3.2.6
+- Resolves bz834245
+
+* Mon Dec 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-7
+- Fix issue with udev scripts where if an raid volume with one of
+  the disks failing, the failed disk is still present in the volume
+  and container. The raid volume stays is in normal state (should be
+  degraded) and the rebuild cannot start.
+- Resolves bz886123
+
+* Mon Dec 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-5
+- mdadm-sysvinit is obsolete given that we no longer support booting
+  using sysvinit scripts
+- Resolves bz884993
+
+* Mon Dec 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-4
+- Fix typo in error message in fix for 880972. No functional changes
+
+* Fri Nov 30 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-3
+- Disallow creating a second IMSM RAID array size 0 (bz880972)
+- Disallow creating IMSM RAIDs that spans multiple controllers (bz880974)
+- Resolves bz880972, bz880974
+
+* Thu Nov 15 2012 Doug Ledford <dledford@redhat.com> - 3.2.6-2
+- Modify mdadm to set the cgroup of mdmon to systemd if it's available
+- Related bz873576 (and others)
+
+* Thu Oct 25 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-1
+- Upgrade to mdadm-3.2.6
+- Resolves bz869930
+
+* Fri Oct 19 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-14
+- Dummy update to work around bodhi breakage. No actual code changes.
+
+* Fri Oct 19 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-13
+- Relax installation requirements for abrt script to only depend on
+  libreport-filesystem rather than the full abrt package
+
+* Thu Oct 18 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-12
+- Add abrt script to retrieve /proc/mdstat output in case of crash
+- Resolves bz867842
+
+* Wed Oct 17 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-11
+- Remove package requirements for udev and initscripts for F18+
+- Resolves bz864562
+
+* Wed Oct 3 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-9
+- Resolve issue with ambiguous licenses
+- Resolves bz862761
+
+* Mon Sep 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-8
+- Switch to using new systemd macros for F18+
+- Resolves bz850202
+
+* Thu Aug 2 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-7
+- Remove bogus rogue patch applied in 3.2.5-5 with justification and
+  without following the structure of the mdadm package.
+
+* Fri Jul 27 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.5-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Wed Jul 18 2012 Karsten Hopp <karsten@redhat.com> 3.2.5-5
+- include <linux/types.h> in some to avoid type clashes.
+  same problem as rhbz #840902  
+
+* Mon Jul 16 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-4
+- Move /etc/tmpfiles.d/mdadm.conf to /lib/tmpfiles.d/ to comply with
+  Fedora tmpfile rules
+- Resolves bz840187
+
+* Mon Jun 25 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-3
+- Fix problem where reshape of RAID volume is broken after trying to
+  stop all MD devices.
+- Enhance raid-check to allow the adming to specify the max number of
+  concurrent arrays to be checked at any given time.
+- Resolves bz830177, bz820124
+
+* Wed Jun 13 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-2
+- Fix uninstall script to remove dangling symlink to
+  mdmonitor-takeover.service, if the mdadm package is uninstalled from
+  the system.
+- Resolves bz828354
+
+* Mon May 21 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.5-1
+- Upgrade to mdadm-3.2.5
+- Resolves bz822850
+
+* Tue May 15 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.4-3
+- Fix mdadm-3.2.4 introduced bug where --add fails in common cases
+- Resolves bz821717 (f17) bz821718 (f16) bz821719 (f15)
+
+* Thu May 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.4-2
+- Fix mdadm.conf to use 'd' for /var/run/mdadm creation, to avoid the
+  map file getting deleted during boot.
+
+* Thu May 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.4-1
+- Upgrade to mdadm-3.2.4
+- Resolves bz820534 (rawhide) bz820527 (f17) bz820531 (f16) bz820532 (f15)
+
+* Mon Apr 30 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-9
+- Fix Monitor mode sometimes crashes when a resync completes
+- Fix missing symlink for mdadm container device when incremental creates
+  the array
+- Make sure when creating a second array in a container that the second
+  array uses all available space since leaving space for a third array
+  is invalid
+- Validate the number of imsm volumes per controller
+- Fix issues with imsm arrays and disks larger than 2TB
+- Add support for expanding imsm arrays/containers
+- The support for expanding imsm arrays/containers was accepted upstream,
+  update to the official patches from there
+- Fix for the issue of --add not being very smart
+- Fix an issue causing rebuilds to fail to restart on reboot (data
+  corrupter level problem)
+- Reset the bad flag on map file updates
+- Correctly fix failure when trying to add internal bitmap to 1.0 arrays
+- Resolves: bz817023 (f17) bz817024 (f17) bz817026 (f17) bz817028 (f17)
+- Resolves: bz817029 (f17) bz817032 (f17) bz817038 (f17) bz808774 (f17)
+- Resolves: bz817039 (f17) bz817042 (f17)
+
+* Mon Apr 30 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-8
+- Fix bug where IMSM arrays stay inactive in case a reboot is
+- performed during the reshape process.
+- Resolves: bz817522 (f17) bz817535 (f16) bz817537 (f15)
+
+* Wed Mar 28 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-7
+- Fix issue when re-adding drive to a raid1 array with bitmap
+- Resolves: bz807743 (f17) bz769323 (f16) bz791159 (f15)
+
+* Thu Feb 23 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-6
+- Fix double free on buggy old kernel sysfs read
+- Fix segfault if trying to write superblock to non existing device
+- Resolves: bz795707 (f17) bz795747 (f16) bz795748 (f15)
+- Resolves: bz795461 (f17) bz795749 (f16) bz795750 (f15)
+
+* Thu Feb 16 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-5
+- Fix issue with devices failing to be added to a raid using bitmaps,
+  due to trying to write the bitmap with mis-aligned buffers using
+  O_DIRECT 
+- Resolves: bz789898 (f16) bz791189 (f15)
+
+* Mon Jan 30 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-4
+- Add support for --offroot to mdadm/mdmon
+- Resolves: bz785739 (rawhide) bz785737 (f16) bz771405 (f15)
+
+* Thu Jan 12 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-3
+- Fix case where we have to retry in case a remove fails due to an array
+  being busy
+- Resolves: bz773337 (rawhide) bz773340 (f16) bz773341 (f15)
+
+* Thu Jan 5 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-2
+- Workaround for gcc-4.7 strict aliasing breaking the build
+
+* Wed Jan 4 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-1
+- Update to upstream 3.2.3
+- Resolves: bz770110 (rawhide) bz771413 (f16) bz759014 (rawhide)
+- Resolves: bz759015 (f16) bz759035 (rawhide) bz759036 (f16)
+- Resolves: bz771608 (f15) bz759016 (f15) bz759039 (f15)
+
+* Mon Nov 21 2011 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.2-15
+- Backport upstream fix for memory leak that can prevent migration to
+  RAID5 from completing.
+- Backport upstream fix preventing mounting a device while it is in
+  process of reshaping
+- Resolves: bz755005 bz755009
+
+* Wed Nov 9 2011 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.2-14
+- Backport upstream fixes to prevent growing v0.90 metadata raid out
+  of supported size.
+- Add missing 'disable' argument to systemctl in preun script
+- Resolves: bz735306 (Fedora 15) bz748731 (Fedora 16) bz748732 (rawhide),
+  Resolves: bz751716
+
+* Wed Oct 26 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.2.2-13
+- Rebuilt for glibc bug#747377
+
+* Sat Oct 22 2011 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.2-12
+- Backport upstream version of fix for IMSM RAID assembly problem,
+  which resolves issues when booting off sysvinit based system.
+- Resolves: bz736387 (Fedora 15) bz744217 (Fedora 16)
+
+* Wed Oct 19 2011 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.2-11
+- Fix systemd dependency problem
+- Resolves: bz741115 (F16) bz744226 (rawhide)
+
+* Wed Oct 19 2011 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.2-10
+- Fix problem where a dirty IMSM RAID isn't assembled correctly during
+  boot, preventing booting from this RAID device.
+- Resolves: bz736387 (Fedora 15) bz744217 (Fedora 16)
+- Fix race between udev and mdadm when assembling md device using
+  mdadm -I, where udev would spawn an additional mdadm command to
+  perform the assembly in parallel.
+
+* Wed Aug 31 2011 Doug Ledford <dledford@redhat.com> - 3.2.2-9
+- Fix boot with older imsm arrays that have an unused attribute set
+- Resolves: bz729205
+
+* Thu Aug 25 2011 Doug Ledford <dledford@redhat.com> - 3.2.2-8
+- Rework the 65-md-incremental.rules file to add the following support:
+  Nested md raid arrays should now work
+  MD on top of LUKS or other lvm based devices should now work
+  We should no longer grab multipath paths before multipath can
+
+* Wed Jul 27 2011 Doug Ledford <dledford@redhat.com> - 3.2.2-7
+- Fix a bug with readding a device
+- Fix a bug with writemostly flag handling
+
+* Mon Jul 18 2011 Doug Ledford <dledford@redhat.com> - 3.2.2-6
+- Bump and rebuild again
+
+* Fri Jul 15 2011 Doug Ledford <dledford@redhat.com> - 3.2.2-5
+- Bump and rebuild to keep version ahead of f15 version
+
+* Thu Jul 14 2011 Doug Ledford <dledford@redhat.com> - 3.2.2-4
+- Fix minor issue in man page
+- Resolves: bz717795
+
+* Thu Jul 07 2011 Milan Broz <mbroz@redhat.com> - 3.2.2-3
+- Use unit files with systemd. (johannbg)
+- Add sub-package sysvinit for SysV init script.
+- Resolves: bz713573
+
+* Wed Jul 06 2011 Milan Broz <mbroz@redhat.com> - 3.2.2-2
+- Fix build on PPC.
+- Resolves: bz719380
+
+* Tue Jun 28 2011 Milan Broz <mbroz@redhat.com> - 3.2.2-1
+- Update to latest upstream version
+- Resolves: bz714083
+
+* Tue Jun 14 2011 Doug Ledford <dledford@redhat.com> - 3.2.1-5
+- Fix for bz710646
+
+* Thu Mar 31 2011 Doug Ledford <dledford@redhat.com> - 3.2.1-4
+- Somehow the 64-md-raid.rules file went missing.  Put it back.
+- Resolves: bz692248
+
+* Thu Mar 31 2011 Doug Ledford <dledford@redhat.com> - 3.2.1-3
+- Fix mdmonitor init script setup of SELinux on PIDPATH
+- Resolves: bz692559
+
+* Mon Mar 28 2011 Doug Ledford <dledford@redhat.com> - 3.2.1-2
+- Restore build command to sane command instead of test command
+
+* Mon Mar 28 2011 Doug Ledford <dledford@redhat.com> - 3.2.1-1
+- Update to latest upstream version
+- Resolves: 691353
+
+* Fri Mar 25 2011 Doug Ledford <dledford@redhat.com> - 3.1.5-1
+- Update to latest upstream stable release
+- Update mdadm.rules file to honor noiswmd and nodmraid command line options
+- Ghost the directory in /var/run, create /var/run/mdadm in mdmonitor init
+  script
+- Don't report mismatch counts on either raid1 or raid10
+- Check both active and idle arrays during raid check runs
+- Move the raid-check script from cron.weekly to /usr/sbin, add a crontab
+  file to /etc/cron.d and mark it config(noreplace).  This way users can
+  select their own raid-check frequency and have it honored through
+  upgrades.
+- Allow the raid-check script to set the process and io priority of the
+  thread performing the check in order to preserve responsiveness of the
+  machine during the check.
+- Resolves: 633229, 656620. 679843, 671076, 659933
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.1.3-0.git20100804.2.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Wed Aug 04 2010 Doug Ledford <dledford@redhat.com> - 3.1.3-0.git20100804.2
+- Add udev patch to not have incremental assembly in two rules files
+
+* Wed Aug 04 2010 Doug Ledford <dledford@redhat.com> - 3.1.3-0.git20100804.1
+- Update to latest upstream release (resolves an issue with stale lock
+  files on the md device map file)
+
+* Thu Jul 22 2010 Doug Ledford <dledford@redhat.com> - 3.1.3-0.git20100722.2
+- Remove the glibc-static buildreq and don't build the static mdadm since
+  we don't install it anyway
+- Remove the udev file since adding it was supposed to be a rawhide only change
+
+* Thu Jul 22 2010 Doug Ledford <dledford@redhat.com> - 3.1.3-0.git20100722.1
+- Change git date format to the correct format (YYYYMMDD)
+- Update to latest upstream push (fixes bz604023)
+
+* Tue Jul 20 2010 Doug Ledford <dledford@redhat.com> - 3.1.3-0.git07202010.2
+- Fix racy locking of mapfile (bz616596)
+
+* Tue Jul 20 2010 Doug Ledford <dledford@redhat.com> - 3.1.3-0.git07202010.1
+- Update to latest git repo (3.1.2 plus pending changes, fixes bz602457)
+- Add in 64-md-raid.rules to compensate for it no longer being in udev
+  (bz581905)
+- Remove mdadm.static as its no longer used in initrd creation
+
+* Tue Apr 13 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-10
+- Minor update to mdadm.rules to make anaconda happy
+
+* Thu Apr 08 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-9
+- Slight fix on container patch
+
+* Thu Apr 08 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-8
+- Updated container patch that also enables mdadm -IRs for imsm devices
+
+* Tue Apr 06 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-7
+- Fix up directory in mdmonitor init script so that we restart mdmon like we
+  are supposed to
+- Add a rule to run incremental assembly on containers in case there are
+  multiple volumes in a container and we only started some of them in the
+  initramfs
+- Make -If work with imsm arrays.  We had too restrictive of a test in
+  sysfs_unique_holder.
+- Make incremental assembly of containers act like incremental assembly of
+  regular devices (aka, --run is needed to start a degraded array)
+
+* Tue Apr 06 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-6
+- Typo in new rules file
+
+* Tue Apr 06 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-5
+- Enable incremental support for imsm devices
+
+* Tue Apr 06 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-4
+- One line fix for ppc64 compiles
+
+* Tue Apr 06 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-3
+- Clean up directory mess once and for all
+- Add incremental remove support
+
+* Wed Mar 17 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-2
+- Add a little more paranoia checking to the RebuildMap code to avoid ever
+  having the same infinite loop as in bz569019 again even if we change file
+  locations to somewhere where we can't create a mapfile
+
+* Tue Mar 16 2010 Doug Ledford <dledford@redhat.com> - 3.1.2-1
+- Grab latest upstream release instead of git repo snapshot (bz552344, bz572561)
+- The lack of /dev/md is causing problems, so add code to mapfile.c to cause
+  us to create /dev/md if it doesn't exist (bz569019)
+
+* Tue Feb 23 2010 Doug Ledford <dledford@redhat.com> - 3.1.1-0.gcd9a8b5.6
+- Newer version of imsm patch that leaves warning, but only when there
+  actually are too many devices on the command line (bz554974)
+
+* Sun Feb 21 2010 Doug Ledford <dledford@redhat.com> - 3.1.1-0.gcd9a8b5.5
+- The uuid patch cause a different problem during assembly, so use a gross
+  hack to work around the uuid issue that won't break assembly until fixed
+  properly upstream (bz567132)
+
+* Sun Feb 21 2010 Doug Ledford <dledford@redhat.com> - 3.1.1-0.gcd9a8b5.4
+- Fix problem with booting multiple imsm containers when they aren't listed
+  "just so" in the mdadm.conf file (bz554974)
+
+* Fri Feb 19 2010 Doug Ledford <dledford@redhat.com> - 3.1.1-0.gcd9a8b5.3
+- Don't run the raid-check script if the kernel doesn't support
+  md devices (bz557053)
+- Don't report any mismatch_cnt issues on raid1 devices as there are
+  legitimate reasons why the count may not be 0 and we are getting enough
+  false positives that it renders the check useless (bz554217, bz547128)
+
+* Thu Feb 18 2010 Doug Ledford <dledford@redhat.com> - 3.1.1-0.gcd9a8b5.2
+- Fix s390/ppc64 UUID byte swap issue
+
+* Wed Feb 17 2010 Doug Ledford <dledford@redhat.com> - 3.1.1-0.gcd9a8b5.1
+- Update to head of upstream git repo, which contains a significant number
+  of bug fixes we need (bz543746)
+
+* Fri Jan 15 2010 Doug Ledford <dledford@redhat.com> - 3.0.3-3
+- Fix crash when AUTO keyword is in mdadm.conf (bz552342)
+
+* Tue Dec 01 2009 Doug Ledford <dledford@redhat.com> - 3.0.3-2
+- Minor tweak to init script for LSB compliance (bz527957)
+
+* Wed Nov 04 2009 Doug Ledford <dledford@redhat.com> - 3.0.3-1
+- New upstream release 3.0.3 (bz523320, bz527281)
+- Update a couple internal patches
+- Drop a patch in that was in Neil's tree for 3.0.3 that we had pulled for
+  immediate use to resolve a bug
+- Drop the endian patch because it no longer applied cleanly and all attempts
+  to reproduce the original problem as reported in bz510605 failed, even up
+  to and including downloading the specific package that was reported as
+  failing in that bug and trying to reproduce with it on both ppc and ppc64
+  hardware and with both ppc and ppc64 versions on the 64bit hardware.
+  Without a reproducer, it is impossible to determine if a rehashed patch
+  to apply to this code would actually solve the problem, so remove the patch
+  entirely since the original problem, as reported, was an easy to detect DOA
+  issue where installing to a raid array was bound to fail on reboot and so
+  we should be able to quickly and definitively tell if the problem resurfaces.
+- Update the mdmonitor init script for LSB compliance (bz527957)
+- Link from mdadm.static man page to mdadm man page (bz529314)
+- Fix a problem in the raid-check script (bz523000)
+- Fix the intel superblock handler so we can test on non-scsi block devices
+
+* Fri Oct  2 2009 Hans de Goede <hdegoede@redhat.com> - 3.0.2-1
+- New upstream release 3.0.2
+- Add a patch fixing mdadm --detail -export segfaults (bz526761, bz523862)
+- Add a patch making mdmon store its state under /dev/.mdadm for initrd
+  mdmon, rootfs mdmon handover
+- Restart mdmon from initscript (when running) for rootfs mdmon handover
+
+* Thu Sep 17 2009 Doug Ledford <dledford@redhat.com> - 3.0-4
+- Stop some mdmon segfaults (bz523860)
+
+* Tue Sep 15 2009 Doug Ledford <dledford@redhat.com> - 3.0-3
+- Update to current head of upstream git repo for various imsm related fixes
+  (fixes bz523262)
+- Fix display of metadata version in output of Detail mode
+- Add UUID output to --detail --export (bz523314)
+
+* Fri Jul 24 2009 Doug Ledford <dledford@redhat.com> - 3.0-2
+- Improved raid-check script as well as the ability to configure what devices
+  get checked
+- Endian patch for uuid generation
+
+* Mon Jun 29 2009 Doug Ledford <dledford@redhat.com> - 3.0-1
+- Remove stale patches already accepted by upstream
+- Fix the raid-check script to only try and check a device if it is
+  checkable
+- Update to official mdadm-3.0 version
+- Resolves: bz505587, bz505552
+
+* Tue May 19 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.7
+- Move the mdadm.map file from /dev/md/ to /dev/ so the installer doesn't
+  need to precreate the /dev/md/ directory in order for incremental
+  assembly to work
+
+* Tue May 19 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.6
+- Only check raid devices automatically, do not attempt to repair them
+  during the weekly data scrubbing
+
+* Fri Mar 20 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.5
+- Fix a few issues with the new code to determine when a device gets to
+  keep its name and when it doesn't
+
+* Fri Mar 20 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.4
+- Change the perms on the udev rules file, it doesn't need to be +x
+
+* Fri Mar 20 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.3
+- Slightly tweak the udev rules to make sure we don't start arrays
+  while running in rc.sysinit...leave array starting to it instead
+- Modify mdadm to put its mapfile in /dev/md instead of /var/run/mdadm
+  since at startup /var/run/mdadm is read-only by default and this
+  breaks incremental assembly
+- Change how mdadm decides to assemble incremental devices using their 
+  preferred name or a random name to avoid possible conflicts when plugging
+  a foreign array into a host
+
+* Wed Mar 18 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.2
+- Change around the mdadm udev rules we ship to avoid a udev file conflict
+
+* Tue Mar 17 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel3.1
+- Update to latest devel release
+- Remove the no longer necessary udev patch
+- Remove the no longer necessary warn patch
+- Remove the no longer necessary alias patch
+- Update the mdadm.rules file to only pay attention to device adds, not
+  changes and to enable incremental assembly
+- Add a cron job to run a weekly repair of the array to correct bad sectors
+- Resolves: bz474436, bz490972
+
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 3.0-0.devel2.2.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Thu Feb 19 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel2.2
+- Readd our old mdadm rules file that does incremental assembly
+- Remove the new mdadm rules file from upstream as we already have this in
+  our udev package (and the one in the udev package already has a bug fixed)
+
+* Thu Feb 12 2009 Doug Ledford <dledford@redhat.com> - 3.0-0.devel2.1
+- Update to latest upstream devel release
+- Use the udev rules file included with mdadm instead of our own
+- Drop all the no longer relevant patches
+- Fix a build error in mdopen.c
+- Fix the udev rules path in Makefile
+- Fix a compile issue with the __le32_to_cpu() macro usage (bad juju to
+  to operations on the target of the macro as it could get executed
+  multiple times, and gcc now throws an error on that)
+- Add some casts to some print statements to keep gcc from complaining
+
+* Fri Oct 24 2008 Doug Ledford <dledford@redhat.com> - 2.6.7.1-1
+- Updated to latest upstream stable release (#466803)
+- Change udev rule to not assemble degraded arrays (#453314)
+- Fix metadata matching in config file (#466078)
+- Fix assembly of raid10 devices (#444237)
+- Fix incremental assembly of partitioned raid devices (#447818)
+
+* Thu Jun 26 2008 Doug Ledford <dledford@redhat.com> - 2.6.7-1
+- Update to latest upstream version (should resolve #444237)
+- Drop incremental patch as it's now part of upstream
+- Clean up all the open() calls in the code (#437145)
+- Fix the build process to actually generate mdassemble (#446988)
+- Update the udev rules to get additional info about arrays being assembled
+  from the /etc/mdadm.conf file (--scan option) (#447818)
+- Update the udev rules to run degraded arrays (--run option) (#452459)
+
+* Thu Apr 17 2008 Bill Nottingham <notting@redhat.com> - 2.6.4-4
+- make /dev/md if necessary in incremental mode (#429604)
+- open RAID devices with O_EXCL to avoid racing against other --incremental processes (#433932)
+ 
+* Fri Feb  1 2008 Bill Nottingham <notting@redhat.com> - 2.6.4-3
+- add a udev rules file for device assembly (#429604)
+
+* Fri Jan 18 2008 Doug Ledford <dledford@redhat.com> - 2.6.4-2
+- Bump version and rebuild
+
+* Fri Oct 19 2007 Doug Ledford <dledford@redhat.com> - 2.6.4-1
+- Update to latest upstream and remove patches upstream has taken
+
+* Tue Aug 28 2007 Fedora Release Engineering <rel-eng at fedoraproject dot org> - 2.6.2-5
+- Rebuild for selinux ppc32 issue.
+
+* Mon Jul 09 2007 Doug Ledford <dledford@redhat.com> - 2.6.2-4
+- Oops, if we call -C -e1, minor_version is no longer properly set, fix that
+  up
+- Related: bz230207
+
+* Fri Jul 06 2007 Doug Ledford <dledford@redhat.com> - 2.6.2-3
+- Oops, had to update the file leak patch, missed one thing
+- Minor tweak to return codes in init script and add LSB header
+- Resolves: bz244582, bz246980
+
+* Mon Jul 02 2007 Doug Ledford <dledford@redhat.com> - 2.6.2-2
+- Fix a file leak issue when mdadm is in monitor mode
+- Update mdadm init script so that status will always run and so
+  return codes are standards compliant
+- Fix assembly of version 1 superblock devices
+- Make the attempt to create an already running device have a clearer
+  error message
+- Allow the creation of a degraded raid4 array like we allow for raid5
+- Make mdadm actually pay attention to raid4 devices when in monitor mode
+- Make the mdmonitor script use daemon() correctly
+- Fix a bug where manage mode would not add disks correctly under certain
+  conditions
+- Resolves: bz244582, bz242688, bz230207, bz169516, bz171862, bz171938
+- Resolves: bz174642, bz224272, bz186524
+
+* Mon Jul 02 2007 Doug Ledford <dledford@redhat.com> - 2.6.2-1
+- Update to latest upstream
+- Remove requirement for /usr/sbin/sendmail - it's optional and not on by
+  default, and sendmail isn't *required* for mdadm itself to work, and isn't
+  even required for the monitoring capability to work, just if you want to
+  have the monitoring capability do the automatic email thing instead of
+  run your own program (and if you use the program option of the monitor
+  capability, your program could email you in a different manner entirely)
+
+* Mon Apr 16 2007 Doug Ledford <dledford@redhat.com> - 2.6.1-4
+- More cleanups for merge review process
+- Related: bz226134
+
+* Wed Apr 11 2007 Doug Ledford <dledford@redhat.com> - 2.6.1-3
+- Various cleanups as part of merge review process
+- Related: bz226134
+
+* Sat Mar 31 2007 Doug Ledford <dledford@redhat.com> - 2.6.1-2
+- Oops, missing a dependency in the Makefile
+
+* Sat Mar 31 2007 Doug Ledford <dledford@redhat.com> - 2.6.1-1
+- Update to latest upstream version
+- Resolves: bz233422
+
+* Fri Jan 26 2007 Doug Ledford <dledford@redhat.com> - 2.6-1
+- Update to latest upstream version
+- Remove the mdmpd daemon entirely.  Now that multipath tools from the lvm/dm
+  packages handles multipath devices well, this is no longer needed.
+- Various cleanups in the spec file
+
+* Thu Nov 09 2006 Doug Ledford <dledford@redhat.com> - 2.5.4-3
+- Add a fix for the broken printout of array GUID when using the -E --brief
+  flags
+
+* Fri Oct 13 2006 Doug Ledford <dledford@redhat.com> - 2.5.4-2
+- tag present on another branch and can't be forcibly moved
+  required number bump
+
+* Fri Oct 13 2006 Doug Ledford <dledford@redhat.com> - 2.5.4-1
+- Update to 2.5.4 (listed as a bugfix update by upstream)
+- Remove previous bitmap patch that's now part of 2.5.4
+
+* Sun Oct  8 2006 Doug Ledford <dledford@redhat.com> - 2.5.3-2
+- Fix a big-endian machine error in the bitmap code (Paul Clements)
+
+* Mon Aug  7 2006 Doug Ledford <dledford@redhat.com> - 2.5.3-1
+- Update to 2.5.3 which upstream calls a "bug fix" release
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 2.5.2-1.1
+- rebuild
+
+* Fri Jul  7 2006 Doug Ledford <dledford@redhat.com> - 2.5.2-1
+- Update to 2.5.2
+- Remove auto default patch as upstream now has a preferred default auto method
+
+* Wed Mar  8 2006 Peter Jones <pjones@redhat.com> - 2.3.1-3
+- fix build on ppc64
+
+* Wed Mar  8 2006 Jeremy Katz <katzj@redhat.com> - 2.3.1-2
+- fix build on ppc
+
+* Wed Mar  8 2006 Jeremy Katz <katzj@redhat.com> - 2.3.1-1
+- update to 2.3.1 to fix raid5 (#184284)
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 2.2-1.fc5.2.1
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 2.2-1.fc5.2
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Mon Dec 05 2005 Warren Togami <wtogami@redhat.com> 2.2-1
+- 2.2 upgrade (#167897)
+- disable diet because we don't ship it anymore
+  and we don't actually use mdassemble now
+
+* Mon May 16 2005 Doug Ledford <dledford@redhat.com> 1.11.0-4.fc4
+- Make the mdmonitor init script use the pid-file option, major cleanup
+  of the script now possible (#134459)
+
+* Mon May 16 2005 Doug Ledford <dledford@redhat.com> 1.11.0-3.fc4
+- Put back the obsoletes: raidtools that was present in 1.11.0-1.fc4
+
+* Mon May 16 2005 Doug Ledford <dledford@redhat.com> 1.11.0-2.fc4
+- Change the default auto= mode so it need not be on the command line to
+  work with udev, however it is still supported on the command line (#132706)
+- Add a man page (from Luca Berra) for mdassemble
+
+* Wed May 11 2005 Doug Ledford <dledford@redhat.com> - 1.11.0-1.fc4
+- Upgrade to 1.11.0
+
+* Wed Apr 27 2005 Jeremy Katz <katzj@redhat.com> - 1.9.0-3.fc4
+- fix mdmonitor initscript (#144717)
+
+* Mon Mar 21 2005 Doug Ledford <dledford@redhat.com> 1.9.0-2
+- Build mdadm.static and mdassemble (static as well) to be used in initrd
+  images
+
+* Wed Mar 09 2005 Doug Ledford <dledford@redhat.com> 1.9.0-1
+- Initial upgrade to 1.9.0 and update of doc files
+- Fix an s390 build error
+
+* Mon Oct 04 2004 Doug Ledford <dledford@redhat.com> 1.6.0-2
+- Remove /etc/mdadm.conf from the file list.  Anaconda will write one out
+  if it's needed.
+
+* Fri Oct 01 2004 Doug Ledford <dledford@redhat.com> 1.6.0-1
+- Update to newer upstream version
+- Make mdmpd work on kernels that don't have the event interface patch
+
+* Fri Jul 30 2004 Dan Walsh <dwalsh@redhat.com> 1.5.0-11
+- Create a directory /var/run/mdadm to contain mdadm.pid
+- This cleans up SELinux problem
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Sat May 22 2004 Doug Ledford <dledford@redhat.com> - 1.5.0-9
+- Fix Makefile and build method to satisfy bz #123769
+- Add mdmpd man page, update mdmpd version to 0.3 - bz #117160
+- Make sure mdadm --monitor closes all md device files so that md devices
+  can be stopped while mdadm is still running - bz #119532
+
+* Thu May 20 2004 Jeremy Katz <katzj@redhat.com> - 1.5.0-8
+- remove unneeded patch, can use --run instead
+
+* Wed May 19 2004 Jeremy Katz <katzj@redhat.com> - 1.5.0-7
+- add patch with reallyforce mode on creation to be used by anaconda
+
+* Wed May 12 2004 Doug Ledford <dledford@redhat.com> 2.5.0-6
+- Fix a bug in the postun scriptlet related to downgrading to a version
+  of mdadm that doesn't include the mdmpd daemon.
+
+* Fri May 07 2004 Doug Ledford <dledford@redhat.com> 1.5.0-5
+- Disable service mdmpd by default to avoid [Failed] messages on
+  current 2.6 kernels.  Possibly re-enable it by default once the
+  2.6 kernels have the md event interface.
+
+* Thu Apr 22 2004 Doug Ledford <dledford@redhat.com> 1.5.0-4
+- Update mdmonitor script to start daemon more cleanly
+- Repackage mdmpd tarball to include gcc-3.4 changes and to make
+  mdmpd properly daemonize at startup instead of forking and leaving
+  the child attached to the terminal.
+
+* Thu Mar  4 2004 Bill Nottingham <notting@redhat.com> 1.5.0-3
+- ship /var/run/mpmpd (#117497)
+
+* Thu Feb 26 2004 Doug Ledford <dledford@redhat.com> 1.5.0-2
+- Add a default MAILADDR line to the mdadm.conf file installed by default
+  (Bugzilla #92447)
+- Make it build with gcc-3.4
+
+* Mon Feb 23 2004 Doug Ledford <dledford@redhat.com> 1.5.0-1
+- Update to 1.5.0 (from Matthew J. Galgoci <mgalgoci@redhat.com>)
+
+* Sun Nov 16 2003 Doug Ledford <dledford@redhat.com> 1.4.0-1
+- fix problem with recovery thread sleeping in mdmpd
+
+* Fri Nov 14 2003 Doug Ledford <dledford@redhat.com>
+- sync upstream
+- add mdmpd package into mdadm package
+
+* Wed Sep 10 2003 Michael K. Johnson <johnsonm@redhat.com> 1.3.0-1
+- sync upstream
+
+* Tue Mar 11 2003 Michael K. Johnson <johnsonm@redhat.com> 1.1.0-1
+- sync upstream
+
+* Tue Jan 28 2003 Michael K. Johnson <johnsonm@redhat.com> 1.0.1-1
+- update for rebuild
+
+* Wed Dec 25 2002 Tim Powers <timp@redhat.com> 1.0.0-8
+- fix references to %%install in the changelog so that it will build
+
+* Fri Dec 13 2002 Elliot Lee <sopwith@redhat.com> 1.0.0-7
+- Rebuild
+
+* Fri Jul 12 2002 Michael K. Johnson <johnsonm@redhat.com>
+- Changed RPM Group to System Environment/Base
+
+* Wed May 15 2002 Michael K. Johnson <johnsonm@redhat.com>
+- minor cleanups to the text, conditionalize rm -rf
+- added mdmonitor init script
+
+* Fri May 10 2002  <neilb@cse.unsw.edu.au>
+- update to 1.0.0
+- Set CXFLAGS instead of CFLAGS
+
+* Sat Apr  6 2002  <neilb@cse.unsw.edu.au>
+- change %%install to use "make install"
+
+* Fri Mar 15 2002  <gleblanc@localhost.localdomain>
+- beautification
+- made mdadm.conf non-replaceable config
+- renamed Copyright to License in the header
+- added missing license file
+- used macros for file paths
+
+* Fri Mar 15 2002 Luca Berra <bluca@comedia.it>
+- Added Obsoletes: mdctl
+- missingok for configfile
+
+* Tue Mar 12 2002 NeilBrown <neilb@cse.unsw.edu.au>
+- Add md.4 and mdadm.conf.5 man pages
+
+* Fri Mar 08 2002 Chris Siebenmann <cks@cquest.utoronto.ca>
+- builds properly as non-root.
+
+* Fri Mar 08 2002 Derek Vadala <derek@cynicism.com>
+- updated for 0.7, fixed /usr/share/doc and added manpage
+
+* Tue Aug 07 2001 Danilo Godec <danci@agenda.si>
+- initial RPM build