diff --git a/SOURCES/Add-force-flag1-to-hot_remove_disk.patch b/SOURCES/Add-force-flag1-to-hot_remove_disk.patch
new file mode 100644
index 0000000..b351498
--- /dev/null
+++ b/SOURCES/Add-force-flag1-to-hot_remove_disk.patch
@@ -0,0 +1,136 @@
+From 1ab9ed2afb7ca50c4f922a0b85c4e6631becde02 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Mon, 27 Mar 2017 14:36:56 +1100
+Subject: [RHEL7.5 PATCH 023/169] Add 'force' flag to *hot_remove_disk().
+
+In rare circumstances, the short period that *hot_remove_disk()
+waits isn't long enough to IO to complete.  This particularly happens
+when a device is failing and many retries are still happening.
+
+We don't want to increase the normal wait time for "mdadm --remove"
+as that might be use just to test if a device is active or not, and a
+delay would be problematic.
+So allow "--force" to mean that mdadm should try extra hard for a
+--remove to complete, waiting up to 5 seconds.
+
+Note that this patch fixes a comment which claim the previous
+wait time was half a second, where it was really 50msec.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Grow.c   |  2 +-
+ Manage.c | 10 +++++-----
+ mdadm.h  |  4 ++--
+ util.c   | 10 +++++-----
+ 4 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index 218a706..e22661c 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -2749,7 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 				continue;
+ 			ioctl(fd, SET_DISK_FAULTY,
+ 			      makedev(disk.major, disk.minor));
+-			hot_remove_disk(fd, makedev(disk.major, disk.minor));
++			hot_remove_disk(fd, makedev(disk.major, disk.minor), 1);
+ 		}
+ 	}
+ 	c = map_num(pers, level);
+diff --git a/Manage.c b/Manage.c
+index edf5798..55218d9 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1110,7 +1110,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ }
+ 
+ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
+-		  int sysfd, unsigned long rdev, int verbose, char *devname)
++		  int sysfd, unsigned long rdev, int force, int verbose, char *devname)
+ {
+ 	int lfd = -1;
+ 	int err;
+@@ -1177,9 +1177,9 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
+ 		/* device has been removed and we don't know
+ 		 * the major:minor number
+ 		 */
+-		err = sys_hot_remove_disk(sysfd);
++		err = sys_hot_remove_disk(sysfd, force);
+ 	} else {
+-		err = hot_remove_disk(fd, rdev);
++		err = hot_remove_disk(fd, rdev, force);
+ 		if (err && errno == ENODEV) {
+ 			/* Old kernels rejected this if no personality
+ 			 * is registered */
+@@ -1603,7 +1603,7 @@ int Manage_subdevs(char *devname, int fd,
+ 
+ 			if (dv->disposition == 'F')
+ 				/* Need to remove first */
+-				hot_remove_disk(fd, rdev);
++				hot_remove_disk(fd, rdev, force);
+ 			/* Make sure it isn't in use (in 2.6 or later) */
+ 			tfd = dev_open(dv->devname, O_RDONLY|O_EXCL);
+ 			if (tfd >= 0) {
+@@ -1645,7 +1645,7 @@ int Manage_subdevs(char *devname, int fd,
+ 				rv = -1;
+ 			} else
+ 				rv = Manage_remove(tst, fd, dv, sysfd,
+-						   rdev, verbose,
++						   rdev, verbose, force,
+ 						   devname);
+ 			if (sysfd >= 0)
+ 				close(sysfd);
+diff --git a/mdadm.h b/mdadm.h
+index b855d24..cebc0c0 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1476,8 +1476,8 @@ extern int add_disk(int mdfd, struct supertype *st,
+ 		    struct mdinfo *sra, struct mdinfo *info);
+ extern int remove_disk(int mdfd, struct supertype *st,
+ 		       struct mdinfo *sra, struct mdinfo *info);
+-extern int hot_remove_disk(int mdfd, unsigned long dev);
+-extern int sys_hot_remove_disk(int statefd);
++extern int hot_remove_disk(int mdfd, unsigned long dev, int force);
++extern int sys_hot_remove_disk(int statefd, int force);
+ extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
+ unsigned long long min_recovery_start(struct mdinfo *array);
+ 
+diff --git a/util.c b/util.c
+index b718531..683c869 100644
+--- a/util.c
++++ b/util.c
+@@ -1795,15 +1795,15 @@ int remove_disk(int mdfd, struct supertype *st,
+ 	return rv;
+ }
+ 
+-int hot_remove_disk(int mdfd, unsigned long dev)
++int hot_remove_disk(int mdfd, unsigned long dev, int force)
+ {
+-	int cnt = 5;
++	int cnt = force ? 500 : 5;
+ 	int ret;
+ 
+ 	/* HOT_REMOVE_DISK can fail with EBUSY if there are
+ 	 * outstanding IO requests to the device.
+ 	 * In this case, it can be helpful to wait a little while,
+-	 * up to half a second, for that IO to flush.
++	 * up to 5 seconds if 'force' is set, or 50 msec if not.
+ 	 */
+ 	while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 &&
+ 	       errno == EBUSY &&
+@@ -1813,9 +1813,9 @@ int hot_remove_disk(int mdfd, unsigned long dev)
+ 	return ret;
+ }
+ 
+-int sys_hot_remove_disk(int statefd)
++int sys_hot_remove_disk(int statefd, int force)
+ {
+-	int cnt = 5;
++	int cnt = force ? 500 : 5;
+ 	int ret;
+ 
+ 	while ((ret = write(statefd, "remove", 6)) == -1 &&
+-- 
+2.7.4
+
diff --git a/SOURCES/Allow-more-spare-selection-criteria.patch b/SOURCES/Allow-more-spare-selection-criteria.patch
index eba8997..c6f1588 100644
--- a/SOURCES/Allow-more-spare-selection-criteria.patch
+++ b/SOURCES/Allow-more-spare-selection-criteria.patch
@@ -40,9 +40,9 @@ index 680d318..fe9d644 100644
  			}
  			free(st3);
 @@ -947,7 +948,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
-					 : INVALID_SECTORS)
-		     < sra->component_size)
-		    ||
+ 					 sra->devs ? sra->devs->data_offset :
+ 					 INVALID_SECTORS) <
+ 		     sra->component_size) ||
 -		    (sra->component_size == 0 && devsize < component_size)) {
 +		    (sra->component_size == 0 && devsize < sc.min_size)) {
  			if (verbose > 1)
diff --git a/SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch b/SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch
new file mode 100644
index 0000000..1716d70
--- /dev/null
+++ b/SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch
@@ -0,0 +1,31 @@
+From b6e60be6281a2a4ec326a72de114867797a42d7f Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:47:37 -0400
+Subject: [RHEL7.5 PATCH 065/169] Assemble/Assemble: Get rid of last use of
+ md_get_version()
+
+At this point in the code, we know we have a valid array, and any
+recent kernel will return 9003, so no point in querying the kernel for
+this.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Assemble.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index fa5fdbe..0db428f 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1901,7 +1901,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
+ 		    c->readonly &&
+ 		    content->text_version[0] == '/')
+ 			content->text_version[0] = '-';
+-		if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
++		if (sysfs_set_array(content, 9003) != 0) {
+ 			sysfs_free(sra);
+ 			return 1;
+ 		}
+-- 
+2.7.4
+
diff --git a/SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch b/SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch
new file mode 100644
index 0000000..b55e6f3
--- /dev/null
+++ b/SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch
@@ -0,0 +1,31 @@
+From 6142741d144824c31b733f9d6e6e240b159effc0 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:09:18 -0400
+Subject: [RHEL7.5 PATCH 054/169] Assemble/Assemble: Stop checking kernel
+ md driver version
+
+Any kernel released during the last decade will return 9003 from
+md_get_version() so no point in checking that.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Assemble.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 672cd12..fa5fdbe 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1477,8 +1477,7 @@ try_again:
+ 		return 1;
+ 	}
+ 	mddev = chosen_name;
+-	if (get_linux_version() < 2004000 ||
+-	    md_get_version(mdfd) < 9000) {
++	if (get_linux_version() < 2004000) {
+ 		pr_err("Assemble requires Linux 2.4 or later, and\n"
+ 		       "     md driver version 0.90.0 or later.\n"
+ 		       "    Upgrade your kernel or try --build\n");
+-- 
+2.7.4
+
diff --git a/SOURCES/Assemble-Clean1-up-start_array.patch b/SOURCES/Assemble-Clean1-up-start_array.patch
new file mode 100644
index 0000000..88def93
--- /dev/null
+++ b/SOURCES/Assemble-Clean1-up-start_array.patch
@@ -0,0 +1,249 @@
+From 94b53b777e095e1bc253654acc2e459d368c5dd5 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 12 Apr 2017 14:23:45 -0400
+Subject: [RHEL7.5 PATCH 075/169] Assemble: Clean up start_array()
+
+This is purely cosmetic, no codeflow changes.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c | 97 +++++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 58 insertions(+), 39 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index b828523..22596b5 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -992,7 +992,7 @@ static int start_array(int mdfd,
+ 	}
+ 
+ 	/* First, add the raid disks, but add the chosen one last */
+-	for (i=0; i<= bestcnt; i++) {
++	for (i = 0; i <= bestcnt; i++) {
+ 		int j;
+ 		if (i < bestcnt) {
+ 			j = best[i];
+@@ -1002,8 +1002,9 @@ static int start_array(int mdfd,
+ 			j = chosen_drive;
+ 
+ 		if (j >= 0 && !devices[j].included) {
+-			int dfd = dev_open(devices[j].devname,
+-					   O_RDWR|O_EXCL);
++			int dfd;
++
++			dfd = dev_open(devices[j].devname, O_RDWR|O_EXCL);
+ 			if (dfd >= 0) {
+ 				remove_partitions(dfd);
+ 				close(dfd);
+@@ -1012,28 +1013,30 @@ static int start_array(int mdfd,
+ 
+ 			if (rv) {
+ 				pr_err("failed to add %s to %s: %s\n",
+-				       devices[j].devname,
+-				       mddev,
++				       devices[j].devname, mddev,
+ 				       strerror(errno));
+-				if (i < content->array.raid_disks * 2
+-				    || i == bestcnt)
++				if (i < content->array.raid_disks * 2 ||
++				    i == bestcnt)
+ 					okcnt--;
+ 				else
+ 					sparecnt--;
+-			} else if (c->verbose > 0)
++			} else if (c->verbose > 0) {
+ 				pr_err("added %s to %s as %d%s%s\n",
+ 				       devices[j].devname, mddev,
+ 				       devices[j].i.disk.raid_disk,
+ 				       devices[j].uptodate?"":
+ 				       " (possibly out of date)",
+-				       (devices[j].i.disk.state & (1<<MD_DISK_REPLACEMENT))?" replacement":"");
++				       (devices[j].i.disk.state &
++					(1<<MD_DISK_REPLACEMENT)) ?
++				       " replacement":"");
++			}
+ 		} else if (j >= 0) {
+ 			if (c->verbose > 0)
+ 				pr_err("%s is already in %s as %d\n",
+ 				       devices[j].devname, mddev,
+ 				       devices[j].i.disk.raid_disk);
+-		} else if (c->verbose > 0 && i < content->array.raid_disks*2
+-			   && (i&1) == 0)
++		} else if (c->verbose > 0 &&
++			   i < content->array.raid_disks * 2 && (i & 1) == 0)
+ 			pr_err("no uptodate device for slot %d of %s\n",
+ 			       i/2, mddev);
+ 	}
+@@ -1041,8 +1044,8 @@ static int start_array(int mdfd,
+ 	if (content->array.level == LEVEL_CONTAINER) {
+ 		if (c->verbose >= 0) {
+ 			pr_err("Container %s has been assembled with %d drive%s",
+-			       mddev, okcnt+sparecnt+journalcnt,
+-			       okcnt+sparecnt+journalcnt==1?"":"s");
++			       mddev, okcnt + sparecnt + journalcnt,
++			       okcnt + sparecnt + journalcnt == 1 ? "" : "s");
+ 			if (okcnt < (unsigned)content->array.raid_disks)
+ 				fprintf(stderr, " (out of %d)",
+ 					content->array.raid_disks);
+@@ -1051,10 +1054,13 @@ static int start_array(int mdfd,
+ 
+ 		if (st->ss->validate_container) {
+ 			struct mdinfo *devices_list;
+-			struct mdinfo *info_devices = xmalloc(sizeof(struct mdinfo)*(okcnt+sparecnt));
++			struct mdinfo *info_devices;
+ 			unsigned int count;
++
+ 			devices_list = NULL;
+-			for (count = 0; count < okcnt+sparecnt; count++) {
++			info_devices = xmalloc(sizeof(struct mdinfo) *
++					       (okcnt + sparecnt));
++			for (count = 0; count < okcnt + sparecnt; count++) {
+ 				info_devices[count] = devices[count].i;
+ 				info_devices[count].next = devices_list;
+ 				devices_list = &info_devices[count];
+@@ -1080,16 +1086,16 @@ static int start_array(int mdfd,
+ 
+ 	if (c->runstop == 1 ||
+ 	    (c->runstop <= 0 &&
+-	     ( enough(content->array.level, content->array.raid_disks,
+-		      content->array.layout, clean, avail) &&
+-	       (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
+-		     ))) {
++	     (enough(content->array.level, content->array.raid_disks,
++		     content->array.layout, clean, avail) &&
++	       (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)))) {
+ 		/* This array is good-to-go.
+ 		 * If a reshape is in progress then we might need to
+ 		 * continue monitoring it.  In that case we start
+ 		 * it read-only and let the grow code make it writable.
+ 		 */
+ 		int rv;
++
+ 		if (content->reshape_active &&
+ 		    !(content->reshape_active & RESHAPE_NO_BACKUP) &&
+ 		    content->delta_disks <= 0) {
+@@ -1109,8 +1115,8 @@ static int start_array(int mdfd,
+ 						   c->backup_file, 0,
+ 						   c->freeze_reshape);
+ 		} else if (c->readonly &&
+-			   sysfs_attribute_available(
+-				   content, NULL, "array_state")) {
++			   sysfs_attribute_available(content, NULL,
++						     "array_state")) {
+ 			rv = sysfs_set_str(content, NULL,
+ 					   "array_state", "readonly");
+ 		} else
+@@ -1121,13 +1127,19 @@ static int start_array(int mdfd,
+ 				pr_err("%s has been started with %d drive%s",
+ 				       mddev, okcnt, okcnt==1?"":"s");
+ 				if (okcnt < (unsigned)content->array.raid_disks)
+-					fprintf(stderr, " (out of %d)", content->array.raid_disks);
++					fprintf(stderr, " (out of %d)",
++						content->array.raid_disks);
+ 				if (rebuilding_cnt)
+-					fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
++					fprintf(stderr, "%s %d rebuilding",
++						sparecnt?",":" and",
++						rebuilding_cnt);
+ 				if (sparecnt)
+-					fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
++					fprintf(stderr, " and %d spare%s",
++						sparecnt,
++						sparecnt == 1 ? "" : "s");
+ 				if (content->journal_clean)
+-					fprintf(stderr, " and %d journal", journalcnt);
++					fprintf(stderr, " and %d journal",
++						journalcnt);
+ 				fprintf(stderr, ".\n");
+ 			}
+ 			if (content->reshape_active &&
+@@ -1137,11 +1149,14 @@ static int start_array(int mdfd,
+ 				 * of the stripe cache - default is 256
+ 				 */
+ 				int chunk_size = content->array.chunk_size;
++
+ 				if (content->reshape_active &&
+ 				    content->new_chunk > chunk_size)
+ 					chunk_size = content->new_chunk;
+ 				if (256 < 4 * ((chunk_size+4065)/4096)) {
+-					struct mdinfo *sra = sysfs_read(mdfd, NULL, 0);
++					struct mdinfo *sra;
++
++					sra = sysfs_read(mdfd, NULL, 0);
+ 					if (sra)
+ 						sysfs_set_num(sra, NULL,
+ 							      "stripe_cache_size",
+@@ -1174,7 +1189,9 @@ static int start_array(int mdfd,
+ 			if (content->array.level == 6 &&
+ 			    okcnt + 1 == (unsigned)content->array.raid_disks &&
+ 			    was_forced) {
+-				struct mdinfo *sra = sysfs_read(mdfd, NULL, 0);
++				struct mdinfo *sra;
++
++				sra = sysfs_read(mdfd, NULL, 0);
+ 				if (sra)
+ 					sysfs_set_str(sra, NULL,
+ 						      "sync_action", "repair");
+@@ -1182,45 +1199,47 @@ static int start_array(int mdfd,
+ 			}
+ 			return 0;
+ 		}
+-		pr_err("failed to RUN_ARRAY %s: %s\n",
+-		       mddev, strerror(errno));
++		pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno));
+ 
+ 		if (!enough(content->array.level, content->array.raid_disks,
+ 			    content->array.layout, 1, avail))
+ 			pr_err("Not enough devices to start the array.\n");
+ 		else if (!enough(content->array.level,
+ 				 content->array.raid_disks,
+-				 content->array.layout, clean,
+-				 avail))
++				 content->array.layout, clean, avail))
+ 			pr_err("Not enough devices to start the array while not clean - consider --force.\n");
+ 
+ 		return 1;
+ 	}
+ 	if (c->runstop == -1) {
+ 		pr_err("%s assembled from %d drive%s",
+-		       mddev, okcnt, okcnt==1?"":"s");
++		       mddev, okcnt, okcnt == 1 ? "" : "s");
+ 		if (okcnt != (unsigned)content->array.raid_disks)
+-			fprintf(stderr, " (out of %d)", content->array.raid_disks);
++			fprintf(stderr, " (out of %d)",
++				content->array.raid_disks);
+ 		fprintf(stderr, ", but not started.\n");
+ 		return 2;
+ 	}
+ 	if (c->verbose >= -1) {
+-		pr_err("%s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
++		pr_err("%s assembled from %d drive%s",
++		       mddev, okcnt, okcnt == 1 ? "" : "s");
+ 		if (rebuilding_cnt)
+-			fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt);
++			fprintf(stderr, "%s %d rebuilding",
++				sparecnt ? "," : " and", rebuilding_cnt);
+ 		if (sparecnt)
+-			fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
++			fprintf(stderr, " and %d spare%s", sparecnt,
++				sparecnt == 1 ? "" : "s");
+ 		if (!enough(content->array.level, content->array.raid_disks,
+ 			    content->array.layout, 1, avail))
+ 			fprintf(stderr, " - not enough to start the array.\n");
+ 		else if (!enough(content->array.level,
+ 				 content->array.raid_disks,
+-				 content->array.layout, clean,
+-				 avail))
++				 content->array.layout, clean, avail))
+ 			fprintf(stderr, " - not enough to start the array while not clean - consider --force.\n");
+ 		else {
+ 			if (req_cnt == (unsigned)content->array.raid_disks)
+-				fprintf(stderr, " - need all %d to start it", req_cnt);
++				fprintf(stderr, " - need all %d to start it",
++					req_cnt);
+ 			else
+ 				fprintf(stderr, " - need %d to start", req_cnt);
+ 			fprintf(stderr, " (use --run to insist).\n");
+-- 
+2.7.4
+
diff --git a/SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch b/SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch
new file mode 100644
index 0000000..c810636
--- /dev/null
+++ b/SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch
@@ -0,0 +1,34 @@
+From 0ef1043ce8dd3f36c7227aa4a260819c4c17c78d Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 12 Apr 2017 14:50:02 -0400
+Subject: [RHEL7.5 PATCH 077/169] Assemble: Remove obsolete test for
+ kernels older than 2.4
+
+We only support 2.6.15+ at this point
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 22596b5..d6beb23 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1487,13 +1487,6 @@ try_again:
+ 		return 1;
+ 	}
+ 	mddev = chosen_name;
+-	if (get_linux_version() < 2004000) {
+-		pr_err("Assemble requires Linux 2.4 or later, and\n"
+-		       "     md driver version 0.90.0 or later.\n"
+-		       "    Upgrade your kernel or try --build\n");
+-		close(mdfd);
+-		return 1;
+-	}
+ 	if (pre_exist == NULL) {
+ 		if (mddev_busy(fd2devnm(mdfd))) {
+ 			pr_err("%s already active, cannot restart it!\n",
+-- 
+2.7.4
+
diff --git a/SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch b/SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch
new file mode 100644
index 0000000..130b4b9
--- /dev/null
+++ b/SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch
@@ -0,0 +1,38 @@
+commit 3bf9495270d7cd00da942e183dc5f7c7eb68ff69
+Author: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date:   Thu Jan 11 12:39:49 2018 +0100
+
+    policy.c: Avoid to take spare without defined domain by imsm
+    
+    Only Imsm get_disk_controller_domain returns disk controller domain for
+    each disk. It causes that mdadm automatically creates disk controller
+    domain policy for imsm metadata, and imsm containers in the same disk
+    controller domain can take spare for recovery.
+    
+    Ignore spares if only one imsm domain is matched.
+    
+    Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/policy.c b/policy.c
+index b17585a..c0d18a7 100644
+--- a/policy.c
++++ b/policy.c
+@@ -661,6 +661,7 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
+ 	 *  1:  has domains, all match
+ 	 */
+ 	int found_any = -1;
++	int has_one_domain = 1;
+ 	struct dev_policy *p;
+ 
+ 	pol = pol_find(pol, pol_domain);
+@@ -670,6 +671,9 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
+ 			dom = dom->next;
+ 		if (!dom || strcmp(dom->dom, p->value) != 0)
+ 			return 0;
++		if (has_one_domain && metadata && strcmp(metadata, "imsm") == 0)
++			found_any = -1;
++		has_one_domain = 0;
+ 	}
+ 	return found_any;
+ }
diff --git a/SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch b/SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch
new file mode 100644
index 0000000..ff7ca90
--- /dev/null
+++ b/SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch
@@ -0,0 +1,266 @@
+From e6e5f8f1267de4f310415231b3434fce2d25f02a Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:20:52 -0400
+Subject: [RHEL7.5 PATCH 055/169] Build: Stop bothering about supporting md
+ driver older than 0.90.00
+
+The kernel has been stuck at md driver version 0.90.03 for at least  a
+decade. No point in continuing to support the older API.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Build.c | 187 ++++++++++++++++++++++++----------------------------------------
+ 1 file changed, 69 insertions(+), 118 deletions(-)
+
+diff --git a/Build.c b/Build.c
+index 691dd6f..11ba12f 100644
+--- a/Build.c
++++ b/Build.c
+@@ -39,13 +39,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	 * geometry is 0xpp00cc
+ 	 * where pp is personality: 1==linear, 2=raid0
+ 	 * cc = chunk size factor: 0==4k, 1==8k etc.
+-	 *
+-	 * For md_version >= 0.90.0 we call
+-	 * SET_ARRAY_INFO,  ADD_NEW_DISK, RUN_ARRAY
+-	 *
+ 	 */
+ 	int i;
+-	int vers;
+ 	struct stat stb;
+ 	int subdevs = 0, missing_disks = 0;
+ 	struct mddev_dev *dv;
+@@ -55,6 +50,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	char chosen_name[1024];
+ 	int uuid[4] = {0,0,0,0};
+ 	struct map_ent *map = NULL;
++	mdu_array_info_t array;
++	mdu_param_t param; /* not used by syscall */
+ 
+ 	if (s->level == UnSet) {
+ 		pr_err("a RAID level is needed to Build an array.\n");
+@@ -122,39 +119,30 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name);
+ 	map_unlock(&map);
+ 
+-	vers = md_get_version(mdfd);
+-
+-	/* looks Ok, go for it */
+-	if (vers >= 9000) {
+-		mdu_array_info_t array;
+-		array.level = s->level;
+-		if (s->size == MAX_SIZE)
+-			s->size = 0;
+-		array.size = s->size;
+-		array.nr_disks = s->raiddisks;
+-		array.raid_disks = s->raiddisks;
+-		array.md_minor = 0;
+-		if (fstat(mdfd, &stb)==0)
+-			array.md_minor = minor(stb.st_rdev);
+-		array.not_persistent = 1;
+-		array.state = 0; /* not clean, but no errors */
+-		if (s->assume_clean)
+-			array.state |= 1;
+-		array.active_disks = s->raiddisks - missing_disks;
+-		array.working_disks = s->raiddisks - missing_disks;
+-		array.spare_disks = 0;
+-		array.failed_disks = missing_disks;
+-		if (s->chunk == 0 && (s->level==0 || s->level==LEVEL_LINEAR))
+-			s->chunk = 64;
+-		array.chunk_size = s->chunk*1024;
+-		array.layout = s->layout;
+-		if (md_set_array_info(mdfd, &array)) {
+-			pr_err("md_set_array_info() failed for %s: %s\n",
+-				mddev, strerror(errno));
+-			goto abort;
+-		}
+-	} else if (s->bitmap_file) {
+-		pr_err("bitmaps not supported with this kernel\n");
++	array.level = s->level;
++	if (s->size == MAX_SIZE)
++		s->size = 0;
++	array.size = s->size;
++	array.nr_disks = s->raiddisks;
++	array.raid_disks = s->raiddisks;
++	array.md_minor = 0;
++	if (fstat(mdfd, &stb) == 0)
++		array.md_minor = minor(stb.st_rdev);
++	array.not_persistent = 1;
++	array.state = 0; /* not clean, but no errors */
++	if (s->assume_clean)
++		array.state |= 1;
++	array.active_disks = s->raiddisks - missing_disks;
++	array.working_disks = s->raiddisks - missing_disks;
++	array.spare_disks = 0;
++	array.failed_disks = missing_disks;
++	if (s->chunk == 0 && (s->level==0 || s->level==LEVEL_LINEAR))
++		s->chunk = 64;
++	array.chunk_size = s->chunk*1024;
++	array.layout = s->layout;
++	if (md_set_array_info(mdfd, &array)) {
++		pr_err("md_set_array_info() failed for %s: %s\n",
++		       mddev, strerror(errno));
+ 		goto abort;
+ 	}
+ 
+@@ -167,8 +155,10 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	}
+ 	/* now add the devices */
+ 	for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
++		mdu_disk_info_t disk;
+ 		unsigned long long dsize;
+ 		int fd;
++
+ 		if (strcmp("missing", dv->devname) == 0)
+ 			continue;
+ 		if (stat(dv->devname, &stb)) {
+@@ -191,94 +181,58 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 		    (s->size == 0 || s->size == MAX_SIZE || dsize < s->size))
+ 				s->size = dsize;
+ 		close(fd);
+-		if (vers >= 9000) {
+-			mdu_disk_info_t disk;
+-			disk.number = i;
+-			disk.raid_disk = i;
+-			disk.state = (1<<MD_DISK_SYNC) | (1<<MD_DISK_ACTIVE);
+-			if (dv->writemostly == FlagSet)
+-				disk.state |= 1<<MD_DISK_WRITEMOSTLY;
+-			disk.major = major(stb.st_rdev);
+-			disk.minor = minor(stb.st_rdev);
+-			if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
+-				pr_err("ADD_NEW_DISK failed for %s: %s\n",
+-					dv->devname, strerror(errno));
+-				goto abort;
+-			}
+-		} else {
+-			if (ioctl(mdfd, REGISTER_DEV, &stb.st_rdev)) {
+-				pr_err("REGISTER_DEV failed for %s: %s.\n",
+-					dv->devname, strerror(errno));
+-				goto abort;
+-			}
++		disk.number = i;
++		disk.raid_disk = i;
++		disk.state = (1<<MD_DISK_SYNC) | (1<<MD_DISK_ACTIVE);
++		if (dv->writemostly == FlagSet)
++			disk.state |= 1<<MD_DISK_WRITEMOSTLY;
++		disk.major = major(stb.st_rdev);
++		disk.minor = minor(stb.st_rdev);
++		if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
++			pr_err("ADD_NEW_DISK failed for %s: %s\n",
++			       dv->devname, strerror(errno));
++			goto abort;
+ 		}
+ 	}
+ 	/* now to start it */
+-	if (vers >= 9000) {
+-		mdu_param_t param; /* not used by syscall */
+-		if (s->bitmap_file) {
+-			bitmap_fd = open(s->bitmap_file, O_RDWR);
+-			if (bitmap_fd < 0) {
+-				int major = BITMAP_MAJOR_HI;
++	if (s->bitmap_file) {
++		bitmap_fd = open(s->bitmap_file, O_RDWR);
++		if (bitmap_fd < 0) {
++			int major = BITMAP_MAJOR_HI;
+ #if 0
+-				if (s->bitmap_chunk == UnSet) {
+-					pr_err("%s cannot be openned.",
+-						s->bitmap_file);
+-					goto abort;
+-				}
+-#endif
+-				if (vers < 9003) {
+-					major = BITMAP_MAJOR_HOSTENDIAN;
+-#ifdef __BIG_ENDIAN
+-					pr_err("Warning - bitmaps created on this kernel are not portable\n"
+-						"  between different architectures.  Consider upgrading the Linux kernel.\n");
++			if (s->bitmap_chunk == UnSet) {
++				pr_err("%s cannot be openned.", s->bitmap_file);
++				goto abort;
++			}
+ #endif
+-				}
+-				bitmapsize = s->size>>9; /* FIXME wrong for RAID10 */
+-				if (CreateBitmap(s->bitmap_file, 1, NULL, s->bitmap_chunk,
+-						 c->delay, s->write_behind, bitmapsize, major)) {
+-					goto abort;
+-				}
+-				bitmap_fd = open(s->bitmap_file, O_RDWR);
+-				if (bitmap_fd < 0) {
+-					pr_err("%s cannot be openned.",
+-						s->bitmap_file);
+-					goto abort;
+-				}
++			bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */
++			if (CreateBitmap(s->bitmap_file, 1, NULL,
++					 s->bitmap_chunk, c->delay,
++					 s->write_behind, bitmapsize, major)) {
++				goto abort;
+ 			}
+-			if (bitmap_fd >= 0) {
+-				if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
+-					pr_err("Cannot set bitmap file for %s: %s\n",
+-						mddev, strerror(errno));
+-					goto abort;
+-				}
++			bitmap_fd = open(s->bitmap_file, O_RDWR);
++			if (bitmap_fd < 0) {
++				pr_err("%s cannot be openned.", s->bitmap_file);
++				goto abort;
+ 			}
+ 		}
+-		if (ioctl(mdfd, RUN_ARRAY, &param)) {
+-			pr_err("RUN_ARRAY failed: %s\n",
+-				strerror(errno));
+-			if (s->chunk & (s->chunk-1)) {
+-				cont_err("Problem may be that chunk size is not a power of 2\n");
++		if (bitmap_fd >= 0) {
++			if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
++				pr_err("Cannot set bitmap file for %s: %s\n",
++				       mddev, strerror(errno));
++				goto abort;
+ 			}
+-			goto abort;
+-		}
+-	} else {
+-		unsigned long arg;
+-		arg=0;
+-		while (s->chunk > 4096) {
+-			arg++;
+-			s->chunk >>= 1;
+ 		}
+-		if (s->level == 0)
+-			arg |= 0x20000;
+-		else
+-			arg |= 0x10000;
+-		if (ioctl(mdfd, START_MD, arg)) {
+-			pr_err("START_MD failed: %s\n",
+-				strerror(errno));
+-			goto abort;
++	}
++	if (ioctl(mdfd, RUN_ARRAY, &param)) {
++		pr_err("RUN_ARRAY failed: %s\n", strerror(errno));
++		if (s->chunk & (s->chunk - 1)) {
++			cont_err("Problem may be that chunk size is not a power of 2\n");
+ 		}
++		goto abort;
+ 	}
++
+ 	if (c->verbose >= 0)
+ 		pr_err("array %s built and started.\n",
+ 			mddev);
+@@ -287,10 +241,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	return 0;
+ 
+  abort:
+-	if (vers >= 9000)
+-	    ioctl(mdfd, STOP_ARRAY, 0);
+-	else
+-	    ioctl(mdfd, STOP_MD, 0);
++	ioctl(mdfd, STOP_ARRAY, 0);
+ 	close(mdfd);
+ 	return 1;
+ }
+-- 
+2.7.4
+
diff --git a/SOURCES/Correct-examine-output-for-4k-disks.patch b/SOURCES/Correct-examine-output-for-4k-disks.patch
deleted file mode 100644
index b82b2f3..0000000
--- a/SOURCES/Correct-examine-output-for-4k-disks.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-commit 84918897ee8bb450ea09f7c95b9da44df8e925e4
-Author: Maksymilian Kunt <maksymilian.kunt@intel.com>
-Date:   Tue May 9 14:03:27 2017 +0200
-
-    IMSM: Correct --examine output for 4k disks
-    
-    "Array Size" and "Per Dev Size" are incorrect for disks with sector size
-    different than 512B.
-    
-    Calculate "Array Size" and "Per Dev Size" based on sector size. Additionally
-    print "Sector Size".
-    
-    Signed-off-by: Maksymilian Kunt <maksymilian.kunt@intel.com>
-    Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
-    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
-
-diff --git a/super-intel.c b/super-intel.c
-index ba6f810..8ca80d3 100644
---- a/super-intel.c
-+++ b/super-intel.c
-@@ -1482,13 +1482,16 @@ static void print_imsm_dev(struct intel_super *super,
- 		       ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : "");
- 	} else
- 		printf("      This Slot : ?\n");
-+	printf("    Sector Size : %u\n", super->sector_size);
- 	sz = __le32_to_cpu(dev->size_high);
- 	sz <<= 32;
- 	sz += __le32_to_cpu(dev->size_low);
--	printf("     Array Size : %llu%s\n", (unsigned long long)sz,
-+	printf("     Array Size : %llu%s\n",
-+		   (unsigned long long)sz * 512 / super->sector_size,
- 	       human_size(sz * 512));
- 	sz = blocks_per_member(map);
--	printf("   Per Dev Size : %llu%s\n", (unsigned long long)sz,
-+	printf("   Per Dev Size : %llu%s\n",
-+		   (unsigned long long)sz * 512 / super->sector_size,
- 	       human_size(sz * 512));
- 	printf("  Sector Offset : %llu\n",
- 		pba_of_lba0(map));
diff --git a/SOURCES/Correct-examine-output-for-4kdisks.patch b/SOURCES/Correct-examine-output-for-4kdisks.patch
new file mode 100644
index 0000000..b82b2f3
--- /dev/null
+++ b/SOURCES/Correct-examine-output-for-4kdisks.patch
@@ -0,0 +1,39 @@
+commit 84918897ee8bb450ea09f7c95b9da44df8e925e4
+Author: Maksymilian Kunt <maksymilian.kunt@intel.com>
+Date:   Tue May 9 14:03:27 2017 +0200
+
+    IMSM: Correct --examine output for 4k disks
+    
+    "Array Size" and "Per Dev Size" are incorrect for disks with sector size
+    different than 512B.
+    
+    Calculate "Array Size" and "Per Dev Size" based on sector size. Additionally
+    print "Sector Size".
+    
+    Signed-off-by: Maksymilian Kunt <maksymilian.kunt@intel.com>
+    Signed-off-by: Mariusz Dabrowski <mariusz.dabrowski@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/super-intel.c b/super-intel.c
+index ba6f810..8ca80d3 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1482,13 +1482,16 @@ static void print_imsm_dev(struct intel_super *super,
+ 		       ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : "");
+ 	} else
+ 		printf("      This Slot : ?\n");
++	printf("    Sector Size : %u\n", super->sector_size);
+ 	sz = __le32_to_cpu(dev->size_high);
+ 	sz <<= 32;
+ 	sz += __le32_to_cpu(dev->size_low);
+-	printf("     Array Size : %llu%s\n", (unsigned long long)sz,
++	printf("     Array Size : %llu%s\n",
++		   (unsigned long long)sz * 512 / super->sector_size,
+ 	       human_size(sz * 512));
+ 	sz = blocks_per_member(map);
+-	printf("   Per Dev Size : %llu%s\n", (unsigned long long)sz,
++	printf("   Per Dev Size : %llu%s\n",
++		   (unsigned long long)sz * 512 / super->sector_size,
+ 	       human_size(sz * 512));
+ 	printf("  Sector Offset : %llu\n",
+ 		pba_of_lba0(map));
diff --git a/SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch b/SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch
new file mode 100644
index 0000000..6c8e565
--- /dev/null
+++ b/SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch
@@ -0,0 +1,76 @@
+From cf622ec1d81a5bb3f882922667bac494b3a16581 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 11:53:12 -0400
+Subject: [RHEL7.5 PATCH 050/169] Create: Fixup bad placement of logical ||
+ && in multi-line if statements
+
+These always go at the end of the line, never at the front
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Create.c | 28 +++++++++++-----------------
+ 1 file changed, 11 insertions(+), 17 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index ba24606..17333ce 100644
+--- a/Create.c
++++ b/Create.c
+@@ -457,8 +457,8 @@ int Create(struct supertype *st, char *mddev,
+ 			    st->minor_version >= 1)
+ 				/* metadata at front */
+ 				warn |= check_partitions(fd, dname, 0, 0);
+-			else if (s->level == 1 || s->level == LEVEL_CONTAINER
+-				    || (s->level == 0 && s->raiddisks == 1))
++			else if (s->level == 1 || s->level == LEVEL_CONTAINER ||
++				 (s->level == 0 && s->raiddisks == 1))
+ 				/* partitions could be meaningful */
+ 				warn |= check_partitions(fd, dname, freesize*2, s->size*2);
+ 			else
+@@ -495,9 +495,8 @@ int Create(struct supertype *st, char *mddev,
+ 			pr_err("no size and no drives given - aborting create.\n");
+ 			return 1;
+ 		}
+-		if (s->level > 0 || s->level == LEVEL_MULTIPATH
+-		    || s->level == LEVEL_FAULTY
+-		    || st->ss->external ) {
++		if (s->level > 0 || s->level == LEVEL_MULTIPATH ||
++		    s->level == LEVEL_FAULTY || st->ss->external ) {
+ 			/* size is meaningful */
+ 			if (!st->ss->validate_geometry(st, s->level, s->layout,
+ 						       s->raiddisks,
+@@ -616,8 +615,8 @@ int Create(struct supertype *st, char *mddev,
+ 	 * it could be in conflict with already existing device
+ 	 * e.g. container, array
+ 	 */
+-	if (strncmp(chosen_name, "/dev/md/", 8) == 0
+-	    && map_by_name(&map, chosen_name+8) != NULL) {
++	if (strncmp(chosen_name, "/dev/md/", 8) == 0 &&
++	    map_by_name(&map, chosen_name+8) != NULL) {
+ 		pr_err("Array name %s is in use already.\n",
+ 			chosen_name);
+ 		close(mdfd);
+@@ -653,16 +652,11 @@ int Create(struct supertype *st, char *mddev,
+ 		info.array.md_minor = minor(stb.st_rdev);
+ 	info.array.not_persistent = 0;
+ 
+-	if ( ( (s->level == 4 || s->level == 5) &&
+-	       (insert_point < s->raiddisks || first_missing < s->raiddisks) )
+-	     ||
+-	     ( s->level == 6 && (insert_point < s->raiddisks
+-			      || second_missing < s->raiddisks))
+-	     ||
+-	     ( s->level <= 0 )
+-	     ||
+-	     s->assume_clean
+-		) {
++	if (((s->level == 4 || s->level == 5) &&
++	     (insert_point < s->raiddisks || first_missing < s->raiddisks)) ||
++	    (s->level == 6 && (insert_point < s->raiddisks ||
++			       second_missing < s->raiddisks)) ||
++	    (s->level <= 0) || s->assume_clean) {
+ 		info.array.state = 1; /* clean, but one+ drive will be missing*/
+ 		info.resync_start = MaxSector;
+ 	} else {
+-- 
+2.7.4
+
diff --git a/SOURCES/Create-Fixup-various-whitespace-issues1.patch b/SOURCES/Create-Fixup-various-whitespace-issues1.patch
new file mode 100644
index 0000000..dc65118
--- /dev/null
+++ b/SOURCES/Create-Fixup-various-whitespace-issues1.patch
@@ -0,0 +1,167 @@
+From 98dbf73cba81cd846f9c706f37edc22e21038cf4 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 11:57:30 -0400
+Subject: [RHEL7.5 PATCH 051/169] Create: Fixup various whitespace issues
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Create.c | 50 ++++++++++++++++++++++++--------------------------
+ 1 file changed, 24 insertions(+), 26 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 17333ce..4f98c58 100644
+--- a/Create.c
++++ b/Create.c
+@@ -84,12 +84,12 @@ int Create(struct supertype *st, char *mddev,
+ 	 * RUN_ARRAY
+ 	 */
+ 	int mdfd;
+-	unsigned long long minsize=0, maxsize=0;
++	unsigned long long minsize = 0, maxsize = 0;
+ 	char *mindisc = NULL;
+ 	char *maxdisc = NULL;
+ 	int dnum, raid_disk_num;
+ 	struct mddev_dev *dv;
+-	int fail=0, warn=0;
++	int fail = 0, warn = 0;
+ 	struct stat stb;
+ 	int first_missing = subdevs * 2;
+ 	int second_missing = subdevs * 2;
+@@ -259,7 +259,7 @@ int Create(struct supertype *st, char *mddev,
+ 					      &s->chunk, s->size*2,
+ 					      data_offset, NULL,
+ 					      &newsize, s->consistency_policy,
+-					      c->verbose>=0))
++					      c->verbose >= 0))
+ 		return 1;
+ 
+ 	if (s->chunk && s->chunk != UnSet) {
+@@ -290,7 +290,7 @@ int Create(struct supertype *st, char *mddev,
+ 	info.array.active_disks = 0;
+ 	info.array.working_disks = 0;
+ 	dnum = 0;
+-	for (dv = devlist; dv ; dv = dv->next)
++	for (dv = devlist; dv; dv = dv->next)
+ 		if (data_offset == VARIABLE_OFFSET)
+ 			dv->data_offset = INVALID_SECTORS;
+ 		else
+@@ -302,7 +302,7 @@ int Create(struct supertype *st, char *mddev,
+ 		int dfd;
+ 		char *doff;
+ 
+-		if (strcasecmp(dname, "missing")==0) {
++		if (strcasecmp(dname, "missing") == 0) {
+ 			if (first_missing > dnum)
+ 				first_missing = dnum;
+ 			if (second_missing > dnum && dnum > first_missing)
+@@ -348,7 +348,7 @@ int Create(struct supertype *st, char *mddev,
+ 			 */
+ 			int i;
+ 			char *name = "default";
+-			for(i=0; !st && superlist[i]; i++) {
++			for(i = 0; !st && superlist[i]; i++) {
+ 				st = superlist[i]->match_metadata_desc(name);
+ 				if (!st)
+ 					continue;
+@@ -444,10 +444,10 @@ int Create(struct supertype *st, char *mddev,
+ 	skip_size_check:
+ 		if (c->runstop != 1 || c->verbose >= 0) {
+ 			int fd = open(dname, O_RDONLY);
+-			if (fd <0 ) {
++			if (fd < 0) {
+ 				pr_err("Cannot open %s: %s\n",
+ 					dname, strerror(errno));
+-				fail=1;
++				fail = 1;
+ 				continue;
+ 			}
+ 			warn |= check_ext2(fd, dname);
+@@ -496,7 +496,7 @@ int Create(struct supertype *st, char *mddev,
+ 			return 1;
+ 		}
+ 		if (s->level > 0 || s->level == LEVEL_MULTIPATH ||
+-		    s->level == LEVEL_FAULTY || st->ss->external ) {
++		    s->level == LEVEL_FAULTY || st->ss->external) {
+ 			/* size is meaningful */
+ 			if (!st->ss->validate_geometry(st, s->level, s->layout,
+ 						       s->raiddisks,
+@@ -571,9 +571,9 @@ int Create(struct supertype *st, char *mddev,
+ 	 * as missing, so that a reconstruct happens (faster than re-parity)
+ 	 * FIX: Can we do this for raid6 as well?
+ 	 */
+-	if (st->ss->external == 0 &&
+-	    s->assume_clean==0 && c->force == 0 && first_missing >= s->raiddisks) {
+-		switch ( s->level ) {
++	if (st->ss->external == 0 && s->assume_clean == 0 &&
++	    c->force == 0 && first_missing >= s->raiddisks) {
++		switch (s->level) {
+ 		case 4:
+ 		case 5:
+ 			insert_point = s->raiddisks-1;
+@@ -648,7 +648,7 @@ int Create(struct supertype *st, char *mddev,
+ 	 * with, but it chooses to trust me instead. Sigh
+ 	 */
+ 	info.array.md_minor = 0;
+-	if (fstat(mdfd, &stb)==0)
++	if (fstat(mdfd, &stb) == 0)
+ 		info.array.md_minor = minor(stb.st_rdev);
+ 	info.array.not_persistent = 0;
+ 
+@@ -714,13 +714,11 @@ int Create(struct supertype *st, char *mddev,
+ 		name = strrchr(mddev, '/');
+ 		if (name) {
+ 			name++;
+-			if (strncmp(name, "md_", 3)==0 &&
+-			    strlen(name) > 3 &&
+-			    (name-mddev) == 5 /* /dev/ */)
++			if (strncmp(name, "md_", 3) == 0 &&
++			    strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */)
+ 				name += 3;
+-			else if (strncmp(name, "md", 2)==0 &&
+-				 strlen(name) > 2 &&
+-				 isdigit(name[2]) &&
++			else if (strncmp(name, "md", 2) == 0 &&
++				 strlen(name) > 2 && isdigit(name[2]) &&
+ 				 (name-mddev) == 5 /* /dev/ */)
+ 				name += 2;
+ 		}
+@@ -771,9 +769,9 @@ int Create(struct supertype *st, char *mddev,
+ #endif
+ 	}
+ 
+-	if (s->bitmap_file && (strcmp(s->bitmap_file, "internal")==0 ||
+-			       strcmp(s->bitmap_file, "clustered")==0)) {
+-		if ((vers%100) < 2) {
++	if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 ||
++			       strcmp(s->bitmap_file, "clustered") == 0)) {
++		if ((vers % 100) < 2) {
+ 			pr_err("internal bitmaps not supported by this kernel.\n");
+ 			goto abort_locked;
+ 		}
+@@ -856,11 +854,11 @@ int Create(struct supertype *st, char *mddev,
+ 
+ 	infos = xmalloc(sizeof(*infos) * total_slots);
+ 	enable_fds(total_slots);
+-	for (pass=1; pass <=2 ; pass++) {
++	for (pass = 1; pass <= 2; pass++) {
+ 		struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */
+ 
+-		for (dnum=0, raid_disk_num=0, dv = devlist ; dv ;
+-		     dv=(dv->next)?(dv->next):moved_disk, dnum++) {
++		for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
++		     dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
+ 			int fd;
+ 			struct stat stb2;
+ 			struct mdinfo *inf = &infos[dnum];
+@@ -872,7 +870,7 @@ int Create(struct supertype *st, char *mddev,
+ 				moved_disk = dv;
+ 				continue;
+ 			}
+-			if (strcasecmp(dv->devname, "missing")==0) {
++			if (strcasecmp(dv->devname, "missing") == 0) {
+ 				raid_disk_num += 1;
+ 				continue;
+ 			}
+-- 
+2.7.4
+
diff --git a/SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch b/SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch
new file mode 100644
index 0000000..9686a9f
--- /dev/null
+++ b/SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch
@@ -0,0 +1,88 @@
+From 5f4cc2392689528a9234fae1935cd442f7917738 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:32:40 -0400
+Subject: [RHEL7.5 PATCH 058/169] Create: Remove all attemps to handle md
+ driver older than 0.90.03
+
+More legacy code moved to the bit-bucket.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Create.c | 30 +++++-------------------------
+ 1 file changed, 5 insertions(+), 25 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 4f98c58..6ca0924 100644
+--- a/Create.c
++++ b/Create.c
+@@ -97,7 +97,6 @@ int Create(struct supertype *st, char *mddev,
+ 	int insert_point = subdevs * 2; /* where to insert a missing drive */
+ 	int total_slots;
+ 	int pass;
+-	int vers;
+ 	int rv;
+ 	int bitmap_fd;
+ 	int have_container = 0;
+@@ -112,6 +111,7 @@ int Create(struct supertype *st, char *mddev,
+ 	char chosen_name[1024];
+ 	struct map_ent *map = NULL;
+ 	unsigned long long newsize;
++	mdu_array_info_t inf;
+ 
+ 	int major_num = BITMAP_MAJOR_HI;
+ 	if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0) {
+@@ -150,7 +150,6 @@ int Create(struct supertype *st, char *mddev,
+ 		/* If given a single device, it might be a container, and we can
+ 		 * extract a device list from there
+ 		 */
+-		mdu_array_info_t inf;
+ 		int fd;
+ 
+ 		memset(&inf, 0, sizeof(inf));
+@@ -625,18 +624,11 @@ int Create(struct supertype *st, char *mddev,
+ 	}
+ 	mddev = chosen_name;
+ 
+-	vers = md_get_version(mdfd);
+-	if (vers < 9000) {
+-		pr_err("Create requires md driver version 0.90.0 or later\n");
++	memset(&inf, 0, sizeof(inf));
++	md_get_array_info(mdfd, &inf);
++	if (inf.working_disks != 0) {
++		pr_err("another array by this name is already running.\n");
+ 		goto abort_locked;
+-	} else {
+-		mdu_array_info_t inf;
+-		memset(&inf, 0, sizeof(inf));
+-		md_get_array_info(mdfd, &inf);
+-		if (inf.working_disks != 0) {
+-			pr_err("another array by this name is already running.\n");
+-			goto abort_locked;
+-		}
+ 	}
+ 
+ 	/* Ok, lets try some ioctls */
+@@ -761,20 +753,8 @@ int Create(struct supertype *st, char *mddev,
+ 	 * to stop another mdadm from finding and using those devices.
+ 	 */
+ 
+-	if (s->bitmap_file && vers < 9003) {
+-		major_num = BITMAP_MAJOR_HOSTENDIAN;
+-#ifdef __BIG_ENDIAN
+-		pr_err("Warning - bitmaps created on this kernel are not portable\n"
+-			"  between different architectured.  Consider upgrading the Linux kernel.\n");
+-#endif
+-	}
+-
+ 	if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 ||
+ 			       strcmp(s->bitmap_file, "clustered") == 0)) {
+-		if ((vers % 100) < 2) {
+-			pr_err("internal bitmaps not supported by this kernel.\n");
+-			goto abort_locked;
+-		}
+ 		if (!st->ss->add_internal_bitmap) {
+ 			pr_err("internal bitmaps not supported with %s metadata\n",
+ 				st->ss->name);
+-- 
+2.7.4
+
diff --git a/SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch b/SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch
new file mode 100644
index 0000000..c886229
--- /dev/null
+++ b/SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch
@@ -0,0 +1,311 @@
+From cd6cbb08c458cee07acb1d854e04532b29ec87bf Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 28 Apr 2017 15:05:50 +1000
+Subject: [RHEL7.5 PATCH 100/169] Create: tell udev md device is not ready
+ when first created.
+
+When an array is created the content is not initialized,
+so it could have remnants of an old filesystem or md array
+etc on it.
+udev will see this and might try to activate it, which is almost
+certainly not what is wanted.
+
+So create a mechanism for mdadm to communicate with udev to tell
+it that the device isn't ready.  This mechanism is the existance
+of a file /run/mdadm/created-mdXXX where mdXXX is the md device name.
+
+When creating an array, mdadm will create the file.
+A new udev rule file, 01-md-raid-creating.rules, will detect the
+precense of thst file and set ENV{SYSTEMD_READY}="0".
+This is fairly uniformly used to suppress actions based on the
+contents of the device.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c                  |  2 +-
+ Build.c                     |  2 +-
+ Create.c                    |  9 +++++++-
+ Incremental.c               |  4 ++--
+ Makefile                    |  4 ++--
+ lib.c                       | 29 +++++++++++++++++++++++++
+ mdadm.h                     |  4 +++-
+ mdopen.c                    | 52 ++++++++++++++++++++++++++++-----------------
+ udev-md-raid-creating.rules |  7 ++++++
+ 9 files changed, 86 insertions(+), 27 deletions(-)
+ create mode 100644 udev-md-raid-creating.rules
+
+diff --git a/Assemble.c b/Assemble.c
+index d6beb23..a9442c8 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1478,7 +1478,7 @@ try_again:
+ 			name = strchr(name, ':')+1;
+ 
+ 		mdfd = create_mddev(mddev, name, ident->autof, trustworthy,
+-				    chosen_name);
++				    chosen_name, 0);
+ 	}
+ 	if (mdfd < 0) {
+ 		st->ss->free_super(st);
+diff --git a/Build.c b/Build.c
+index 11ba12f..665d906 100644
+--- a/Build.c
++++ b/Build.c
+@@ -109,7 +109,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	/* We need to create the device.  It can have no name. */
+ 	map_lock(&map);
+ 	mdfd = create_mddev(mddev, NULL, c->autof, LOCAL,
+-			    chosen_name);
++			    chosen_name, 0);
+ 	if (mdfd < 0) {
+ 		map_unlock(&map);
+ 		return 1;
+diff --git a/Create.c b/Create.c
+index 6ca0924..df1bc20 100644
+--- a/Create.c
++++ b/Create.c
+@@ -605,7 +605,7 @@ int Create(struct supertype *st, char *mddev,
+ 
+ 	/* We need to create the device */
+ 	map_lock(&map);
+-	mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name);
++	mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name, 1);
+ 	if (mdfd < 0) {
+ 		map_unlock(&map);
+ 		return 1;
+@@ -620,6 +620,7 @@ int Create(struct supertype *st, char *mddev,
+ 			chosen_name);
+ 		close(mdfd);
+ 		map_unlock(&map);
++		udev_unblock();
+ 		return 1;
+ 	}
+ 	mddev = chosen_name;
+@@ -1053,9 +1054,15 @@ int Create(struct supertype *st, char *mddev,
+ 		pr_err("not starting array - not enough devices.\n");
+ 	}
+ 	close(mdfd);
++	/* Give udev a moment to process the Change event caused
++	 * by the close.
++	 */
++	usleep(100*1000);
++	udev_unblock();
+ 	return 0;
+ 
+  abort:
++	udev_unblock();
+ 	map_lock(&map);
+  abort_locked:
+ 	map_remove(&map, fd2devnm(mdfd));
+diff --git a/Incremental.c b/Incremental.c
+index 66c5b03..4789e36 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -320,7 +320,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 
+ 		/* Couldn't find an existing array, maybe make a new one */
+ 		mdfd = create_mddev(match ? match->devname : NULL,
+-				    name_to_use, c->autof, trustworthy, chosen_name);
++				    name_to_use, c->autof, trustworthy, chosen_name, 0);
+ 
+ 		if (mdfd < 0)
+ 			goto out_unlock;
+@@ -1596,7 +1596,7 @@ static int Incremental_container(struct supertype *st, char *devname,
+ 					    ra->name,
+ 					    c->autof,
+ 					    trustworthy,
+-					    chosen_name);
++					    chosen_name, 0);
+ 		}
+ 		if (only && (!mp || strcmp(mp->devnm, only) != 0))
+ 			continue;
+diff --git a/Makefile b/Makefile
+index 6850696..021d3ad 100644
+--- a/Makefile
++++ b/Makefile
+@@ -256,8 +256,8 @@ install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8
+ 	$(INSTALL) -D -m 644 md.4 $(DESTDIR)$(MAN4DIR)/md.4
+ 	$(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
+ 
+-install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules
+-	@for file in 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \
++install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid-creating.rules
++	@for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \
+ 	do sed -e 's,BINDIR,$(BINDIR),g' udev-$${file#??-} > .install.tmp.1 && \
+ 	   $(ECHO) $(INSTALL) -D -m 644 udev-$${file#??-} $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \
+ 	   $(INSTALL) -D -m 644 .install.tmp.1 $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \
+diff --git a/lib.c b/lib.c
+index b640634..7e44b1f 100644
+--- a/lib.c
++++ b/lib.c
+@@ -163,6 +163,35 @@ char *fd2devnm(int fd)
+ 	return NULL;
+ }
+ 
++/* When we create a new array, we don't want the content to
++ * be immediately examined by udev - it is probably meaningless.
++ * So create /run/mdadm/creating-FOO and expect that a udev
++ * rule will noticed this and act accordingly.
++ */
++static char block_path[] = "/run/mdadm/creating-%s";
++static char *unblock_path = NULL;
++void udev_block(char *devnm)
++{
++	int fd;
++	char *path = NULL;
++
++	xasprintf(&path, block_path, devnm);
++	fd = open(path, O_CREAT|O_RDWR, 0600);
++	if (fd >= 0) {
++		close(fd);
++		unblock_path = path;
++	} else
++		free(path);
++}
++
++void udev_unblock(void)
++{
++	if (unblock_path)
++		unlink(unblock_path);
++	free(unblock_path);
++	unblock_path = NULL;
++}
++
+ /*
+  * convert a major/minor pair for a block device into a name in /dev, if possible.
+  * On the first call, walk /dev collecting name.
+diff --git a/mdadm.h b/mdadm.h
+index 1bbacfe..6a382a7 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1533,7 +1533,7 @@ extern char *get_md_name(char *devnm);
+ extern char DefaultConfFile[];
+ 
+ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
+-			char *chosen);
++			char *chosen, int block_udev);
+ /* values for 'trustworthy' */
+ #define	LOCAL	1
+ #define	LOCAL_ANY 10
+@@ -1567,6 +1567,8 @@ extern char *stat2kname(struct stat *st);
+ extern char *fd2kname(int fd);
+ extern char *stat2devnm(struct stat *st);
+ extern char *fd2devnm(int fd);
++extern void udev_block(char *devnm);
++extern void udev_unblock(void);
+ 
+ extern int in_initrd(void);
+ 
+diff --git a/mdopen.c b/mdopen.c
+index 82b97fc..099efa0 100644
+--- a/mdopen.c
++++ b/mdopen.c
+@@ -135,7 +135,7 @@ void make_parts(char *dev, int cnt)
+  */
+ 
+ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+-		 char *chosen)
++		 char *chosen, int block_udev)
+ {
+ 	int mdfd;
+ 	struct stat stb;
+@@ -147,6 +147,10 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+ 	char devname[37];
+ 	char devnm[32];
+ 	char cbuf[400];
++
++	if (!use_udev())
++		block_udev = 0;
++
+ 	if (chosen == NULL)
+ 		chosen = cbuf;
+ 
+@@ -305,43 +309,53 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+ 		int fd;
+ 		int n = -1;
+ 		sprintf(devnm, "md_%s", cname);
++		if (block_udev)
++			udev_block(devnm);
+ 		fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
+ 		if (fd >= 0) {
+ 			n = write(fd, devnm, strlen(devnm));
+ 			close(fd);
+ 		}
+-		if (n < 0)
++		if (n < 0) {
+ 			devnm[0] = 0;
++			udev_unblock();
++		}
+ 	}
+ 	if (num >= 0) {
+ 		int fd;
+ 		int n = -1;
+ 		sprintf(devnm, "md%d", num);
++		if (block_udev)
++			udev_block(devnm);
+ 		fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
+ 		if (fd >= 0) {
+ 			n = write(fd, devnm, strlen(devnm));
+ 			close(fd);
+ 		}
+-		if (n < 0)
++		if (n < 0) {
+ 			devnm[0] = 0;
+-	}
+-	if (devnm[0])
+-		;
+-	else if (num < 0) {
+-		/* need to choose a free number. */
+-		char *_devnm = find_free_devnm(use_mdp);
+-		if (_devnm == NULL) {
+-			pr_err("No avail md devices - aborting\n");
+-			return -1;
++			udev_unblock();
+ 		}
+-		strcpy(devnm, _devnm);
+-	} else {
+-		sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
+-		if (mddev_busy(devnm)) {
+-			pr_err("%s is already in use.\n",
+-				dev);
+-			return -1;
++	}
++	if (devnm[0] == 0) {
++		if (num < 0) {
++			/* need to choose a free number. */
++			char *_devnm = find_free_devnm(use_mdp);
++			if (_devnm == NULL) {
++				pr_err("No avail md devices - aborting\n");
++				return -1;
++			}
++			strcpy(devnm, _devnm);
++		} else {
++			sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
++			if (mddev_busy(devnm)) {
++				pr_err("%s is already in use.\n",
++				       dev);
++				return -1;
++			}
+ 		}
++		if (block_udev)
++			udev_block(devnm);
+ 	}
+ 
+ 	sprintf(devname, "/dev/%s", devnm);
+diff --git a/udev-md-raid-creating.rules b/udev-md-raid-creating.rules
+new file mode 100644
+index 0000000..2be466b
+--- /dev/null
++++ b/udev-md-raid-creating.rules
+@@ -0,0 +1,7 @@
++# do not edit this file, it will be overwritten on update
++# While mdadm is creating an array, it creates a file
++# /run/mdadm/creating-mdXXX.  If that file exists, then
++# the array is not "ready" and we should make sure the
++# content is ignored.
++
++KERNEL=="md*", TEST="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0"
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch b/SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch
new file mode 100644
index 0000000..843b6a4
--- /dev/null
+++ b/SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch
@@ -0,0 +1,38 @@
+From 776b199e41d10e344efc47008366ca46715c5acc Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 12 Apr 2017 17:05:55 -0400
+Subject: [RHEL7.5 PATCH 078/169] Detail: Fixup ugly if () foo() abuse
+
+Cosmetic change only
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index 8f74832..e40cd8f 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -141,13 +141,15 @@ int Detail(char *dev, struct context *c)
+ 	}
+ 
+ 	/* try to load a superblock. Try sra->devs first, then try ioctl */
+-	if (st && !info) for (d = 0, subdev = sra ? sra->devs : NULL;
+-			      d < max_disks || subdev;
+-			      subdev ? (void)(subdev = subdev->next) : (void)(d++)){
++	if (st && !info)
++		for (d = 0, subdev = sra ? sra->devs : NULL;
++		     d < max_disks || subdev;
++		     subdev ? (void)(subdev = subdev->next) : (void)(d++)){
+ 		mdu_disk_info_t disk;
+ 		char *dv;
+ 		int fd2;
+ 		int err;
++
+ 		if (subdev)
+ 			disk = subdev->disk;
+ 		else {
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch b/SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch
new file mode 100644
index 0000000..0bc947a
--- /dev/null
+++ b/SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch
@@ -0,0 +1,37 @@
+From 0885b942b3575c7f2a8290087751d83902587371 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 25 Apr 2017 14:34:31 -0400
+Subject: [RHEL7.5 PATCH 097/169] Detail: Reinstate support for not having
+ sysfs
+
+While sysfs support will hopefully go away eventually, lets not break
+it unnecessarily for now.
+
+Fixes: 901d5ee ("Detail: Stop bothering about md drivers older than 0.90.00")
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index ceb21b1..ef2370c 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -88,9 +88,11 @@ int Detail(char *dev, struct context *c)
+ 	}
+ 	sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
+ 	if (!sra) {
+-		pr_err("%s does not appear to be an md device\n", dev);
+-		close(fd);
+-		return rv;
++		if (md_get_array_info(fd, &array)) {
++			pr_err("%s does not appear to be an md device\n", dev);
++			close(fd);
++			return rv;
++		}
+ 	}
+ 	external = (sra != NULL && sra->array.major_version == -1 &&
+ 		    sra->array.minor_version == -2);
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch b/SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch
new file mode 100644
index 0000000..52ffc3f
--- /dev/null
+++ b/SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch
@@ -0,0 +1,61 @@
+From 5e13ef714df4734c455b5e4389352c8ab7902038 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 12 Apr 2017 14:48:10 -0400
+Subject: [RHEL7.5 PATCH 076/169] Detail: Remove pre-2.6 code for printing
+ info on rebuilding
+
+Since we no longer support anything pre-2.6.15, there is no point in
+keeping this around.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 19 +++----------------
+ 1 file changed, 3 insertions(+), 16 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index d4e6204..8f74832 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -64,8 +64,6 @@ int Detail(char *dev, struct context *c)
+ 	int max_devices = 0, n_devices = 0;
+ 	int spares = 0;
+ 	struct stat stb;
+-	int is_26 = get_linux_version() >= 2006000;
+-	int is_rebuilding = 0;
+ 	int failed = 0;
+ 	struct supertype *st;
+ 	char *subarray = NULL;
+@@ -527,7 +525,6 @@ int Detail(char *dev, struct context *c)
+ 				"Reshape", "Check"};
+ 			printf("    %7s Status : %d%% complete\n",
+ 			       sync_action[e->resync], e->percent);
+-			is_rebuilding = 1;
+ 		}
+ 		free_mdstat(ms);
+ 
+@@ -676,19 +673,9 @@ This is pretty boring
+ 			      |(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)|(1<<MD_DISK_JOURNAL)))
+ 			    == 0) {
+ 				printf(" spare");
+-				if (is_26) {
+-					if (disk.raid_disk < array.raid_disks && disk.raid_disk >= 0)
+-						printf(" rebuilding");
+-				} else if (is_rebuilding && failed) {
+-					/* Taking a bit of a risk here, we remove the
+-					 * device from the array, and then put it back.
+-					 * If this fails, we are rebuilding
+-					 */
+-					int err = ioctl(fd, HOT_REMOVE_DISK, makedev(disk.major, disk.minor));
+-					if (err == 0) ioctl(fd, HOT_ADD_DISK, makedev(disk.major, disk.minor));
+-					if (err && errno ==  EBUSY)
+-						printf(" rebuilding");
+-				}
++				if (disk.raid_disk < array.raid_disks &&
++				    disk.raid_disk >= 0)
++					printf(" rebuilding");
+ 			}
+ 		}
+ 		if (disk.state == 0) spares++;
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch b/SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch
new file mode 100644
index 0000000..571e366
--- /dev/null
+++ b/SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch
@@ -0,0 +1,521 @@
+From 5737086ed7a39e4d940ed1459d1afad359c3182c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 25 Apr 2017 12:21:39 -0400
+Subject: [RHEL7.5 PATCH 096/169] Detail: Respect code lines are 80
+ character wide
+
+In addition apply spaces and don'f do 'if () action()' on the same line.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 239 ++++++++++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 138 insertions(+), 101 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index eb69276..ceb21b1 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -157,8 +157,7 @@ int Detail(char *dev, struct context *c)
+ 			if (md_get_disk_info(fd, &disk) < 0)
+ 				continue;
+ 			if (d >= array.raid_disks &&
+-			    disk.major == 0 &&
+-			    disk.minor == 0)
++			    disk.major == 0 && disk.minor == 0)
+ 				continue;
+ 		}
+ 
+@@ -236,7 +235,8 @@ int Detail(char *dev, struct context *c)
+ 				printf("MD_METADATA=%s\n", sra->text_version);
+ 			else
+ 				printf("MD_METADATA=%d.%d\n",
+-				       array.major_version, array.minor_version);
++				       array.major_version,
++				       array.minor_version);
+ 		}
+ 
+ 		if (st && st->sb && info) {
+@@ -244,12 +244,12 @@ int Detail(char *dev, struct context *c)
+ 			struct map_ent *mp, *map = NULL;
+ 
+ 			fname_from_uuid(st, info, nbuf, ':');
+-			printf("MD_UUID=%s\n", nbuf+5);
++			printf("MD_UUID=%s\n", nbuf + 5);
+ 			mp = map_by_uuid(&map, info->uuid);
+ 			if (mp && mp->path &&
+ 			    strncmp(mp->path, "/dev/md/", 8) == 0) {
+ 				printf("MD_DEVNAME=");
+-				print_escape(mp->path+8);
++				print_escape(mp->path + 8);
+ 				putchar('\n');
+ 			}
+ 
+@@ -273,11 +273,12 @@ int Detail(char *dev, struct context *c)
+ 		if (sra) {
+ 			struct mdinfo *mdi;
+ 			for (mdi  = sra->devs; mdi; mdi = mdi->next) {
+-				char *path =
+-					map_dev(mdi->disk.major,
+-						mdi->disk.minor, 0);
++				char *path;
+ 				char *sysdev = xstrdup(mdi->sys_name + 1);
+ 				char *cp;
++
++				path = map_dev(mdi->disk.major,
++					       mdi->disk.minor, 0);
+ 				for (cp = sysdev; *cp; cp++)
+ 					if (!isalnum(*cp))
+ 						*cp = '_';
+@@ -299,19 +300,19 @@ int Detail(char *dev, struct context *c)
+ 
+ 	disks = xmalloc(max_disks * 2 * sizeof(mdu_disk_info_t));
+ 	for (d = 0; d < max_disks * 2; d++) {
+-		disks[d].state = (1<<MD_DISK_REMOVED);
++		disks[d].state = (1 << MD_DISK_REMOVED);
+ 		disks[d].major = disks[d].minor = 0;
+ 		disks[d].number = -1;
+-		disks[d].raid_disk = d/2;
++		disks[d].raid_disk = d / 2;
+ 	}
+ 
+-	next = array.raid_disks*2;
++	next = array.raid_disks * 2;
+ 	if (inactive) {
+ 		struct mdinfo *mdi;
+ 		if (sra != NULL)
+ 			for (mdi = sra->devs; mdi; mdi = mdi->next) {
+ 				disks[next++] = mdi->disk;
+-				disks[next-1].number = -1;
++				disks[next - 1].number = -1;
+ 			}
+ 	} else for (d = 0; d < max_disks; d++) {
+ 		mdu_disk_info_t disk;
+@@ -324,21 +325,23 @@ int Detail(char *dev, struct context *c)
+ 		}
+ 		if (disk.major == 0 && disk.minor == 0)
+ 			continue;
+-		if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks
+-		    && disks[disk.raid_disk*2].state == (1<<MD_DISK_REMOVED)
+-		    && ((disk.state & (1<<MD_DISK_JOURNAL)) == 0))
+-			disks[disk.raid_disk*2] = disk;
+-		else if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks
+-			 && disks[disk.raid_disk*2+1].state == (1<<MD_DISK_REMOVED)
+-			 && !(disk.state & (1<<MD_DISK_JOURNAL)))
+-			disks[disk.raid_disk*2+1] = disk;
+-		else if (next < max_disks*2)
++		if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks &&
++		    disks[disk.raid_disk * 2].state == (1 << MD_DISK_REMOVED) &&
++		    ((disk.state & (1 << MD_DISK_JOURNAL)) == 0))
++			disks[disk.raid_disk * 2] = disk;
++		else if (disk.raid_disk >= 0 &&
++			 disk.raid_disk < array.raid_disks &&
++			 disks[disk.raid_disk * 2 + 1].state ==
++			 (1 << MD_DISK_REMOVED) &&
++			 !(disk.state & (1 << MD_DISK_JOURNAL)))
++			disks[disk.raid_disk * 2 + 1] = disk;
++		else if (next < max_disks * 2)
+ 			disks[next++] = disk;
+ 	}
+ 
+ 	avail = xcalloc(array.raid_disks, 1);
+ 
+-	for (d= 0; d < array.raid_disks; d++) {
++	for (d = 0; d < array.raid_disks; d++) {
+ 
+ 		if ((disks[d*2].state & (1<<MD_DISK_SYNC)) ||
+ 		    (disks[d*2+1].state & (1<<MD_DISK_SYNC))) {
+@@ -354,8 +357,8 @@ int Detail(char *dev, struct context *c)
+ 		if (c->verbose > 0) {
+ 			if (array.raid_disks)
+ 				printf(" level=%s num-devices=%d",
+-				       str?str:"-unknown-",
+-				       array.raid_disks );
++				       str ? str : "-unknown-",
++				       array.raid_disks);
+ 			else if (!inactive)
+ 				printf(" level=container num-devices=%d",
+ 				       array.nr_disks);
+@@ -369,8 +372,8 @@ int Detail(char *dev, struct context *c)
+ 			if (sra && sra->array.major_version < 0)
+ 				printf(" metadata=%s", sra->text_version);
+ 			else
+-				printf(" metadata=%d.%d",
+-				       array.major_version, array.minor_version);
++				printf(" metadata=%d.%d", array.major_version,
++				       array.minor_version);
+ 		}
+ 
+ 		/* Only try GET_BITMAP_FILE for 0.90.01 and later */
+@@ -385,7 +388,7 @@ int Detail(char *dev, struct context *c)
+ 		char *devnm;
+ 
+ 		devnm = stat2devnm(&stb);
+-		for (e=ms; e; e=e->next)
++		for (e = ms; e; e = e->next)
+ 			if (strcmp(e->devnm, devnm) == 0)
+ 				break;
+ 		if (!get_dev_size(fd, NULL, &larray_size))
+@@ -394,14 +397,16 @@ int Detail(char *dev, struct context *c)
+ 		printf("%s:\n", dev);
+ 
+ 		if (container)
+-			printf("         Container : %s, member %s\n", container,
+-			       member);
++			printf("         Container : %s, member %s\n",
++			       container, member);
+ 		else {
+-		if (sra && sra->array.major_version < 0)
+-			printf("           Version : %s\n", sra->text_version);
+-		else
+-			printf("           Version : %d.%d\n",
+-			       array.major_version, array.minor_version);
++			if (sra && sra->array.major_version < 0)
++				printf("           Version : %s\n",
++				       sra->text_version);
++			else
++				printf("           Version : %d.%d\n",
++				       array.major_version,
++				       array.minor_version);
+ 		}
+ 
+ 		atime = array.ctime;
+@@ -412,14 +417,17 @@ int Detail(char *dev, struct context *c)
+ 		if (str)
+ 			printf("        Raid Level : %s\n", str);
+ 		if (larray_size)
+-			printf("        Array Size : %llu%s\n", (larray_size>>10),
++			printf("        Array Size : %llu%s\n",
++			       (larray_size >> 10),
+ 			       human_size(larray_size));
+ 		if (array.level >= 1) {
+ 			if (sra)
+ 				array.major_version = sra->array.major_version;
+ 			if (array.major_version != 0 &&
+ 			    (larray_size >= 0xFFFFFFFFULL|| array.size == 0)) {
+-				unsigned long long dsize = get_component_size(fd);
++				unsigned long long dsize;
++
++				dsize = get_component_size(fd);
+ 				if (dsize > 0)
+ 					printf("     Used Dev Size : %llu%s\n",
+ 					       dsize/2,
+@@ -429,7 +437,8 @@ int Detail(char *dev, struct context *c)
+ 			} else
+ 				printf("     Used Dev Size : %lu%s\n",
+ 				       (unsigned long)array.size,
+-				       human_size((unsigned long long)array.size<<10));
++				       human_size((unsigned long long)
++						  array.size << 10));
+ 		}
+ 		if (array.raid_disks)
+ 			printf("      Raid Devices : %d\n", array.raid_disks);
+@@ -440,7 +449,7 @@ int Detail(char *dev, struct context *c)
+ 			printf("   Preferred Minor : %d\n", array.md_minor);
+ 		if (sra == NULL || sra->array.major_version >= 0)
+ 			printf("       Persistence : Superblock is %spersistent\n",
+-			       array.not_persistent?"not ":"");
++			       array.not_persistent ? "not " : "");
+ 		printf("\n");
+ 		/* Only try GET_BITMAP_FILE for 0.90.01 and later */
+ 		if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
+@@ -465,19 +474,25 @@ int Detail(char *dev, struct context *c)
+ 				st = ", degraded";
+ 
+ 			printf("             State : %s%s%s%s%s%s \n",
+-			       (array.state&(1<<MD_SB_CLEAN))?"clean":"active", st,
+-			       (!e || (e->percent < 0 && e->percent != RESYNC_PENDING &&
+-			       e->percent != RESYNC_DELAYED)) ? "" : sync_action[e->resync],
++			       (array.state & (1 << MD_SB_CLEAN)) ?
++			       "clean" : "active", st,
++			       (!e || (e->percent < 0 &&
++				       e->percent != RESYNC_PENDING &&
++				       e->percent != RESYNC_DELAYED)) ?
++			       "" : sync_action[e->resync],
+ 			       larray_size ? "": ", Not Started",
+-			       (e && e->percent == RESYNC_DELAYED) ? " (DELAYED)": "",
+-			       (e && e->percent == RESYNC_PENDING) ? " (PENDING)": "");
++			       (e && e->percent == RESYNC_DELAYED) ?
++			       " (DELAYED)": "",
++			       (e && e->percent == RESYNC_PENDING) ?
++			       " (PENDING)": "");
+ 		} else if (inactive) {
+ 			printf("             State : inactive\n");
+ 		}
+ 		if (array.raid_disks)
+ 			printf("    Active Devices : %d\n", array.active_disks);
+ 		if (array.working_disks > 0)
+-			printf("   Working Devices : %d\n", array.working_disks);
++			printf("   Working Devices : %d\n",
++			       array.working_disks);
+ 		if (array.raid_disks) {
+ 			printf("    Failed Devices : %d\n", array.failed_disks);
+ 			printf("     Spare Devices : %d\n", array.spare_disks);
+@@ -485,11 +500,13 @@ int Detail(char *dev, struct context *c)
+ 		printf("\n");
+ 		if (array.level == 5) {
+ 			str = map_num(r5layout, array.layout);
+-			printf("            Layout : %s\n", str?str:"-unknown-");
++			printf("            Layout : %s\n",
++			       str ? str : "-unknown-");
+ 		}
+ 		if (array.level == 6) {
+ 			str = map_num(r6layout, array.layout);
+-			printf("            Layout : %s\n", str?str:"-unknown-");
++			printf("            Layout : %s\n",
++			       str ? str : "-unknown-");
+ 		}
+ 		if (array.level == 10) {
+ 			printf("            Layout :");
+@@ -510,12 +527,14 @@ int Detail(char *dev, struct context *c)
+ 			printf("          Rounding : %dK\n\n",
+ 			       array.chunk_size/1024);
+ 			break;
+-		default: break;
++		default:
++			break;
+ 		}
+ 
+ 		if (array.raid_disks) {
+-			struct mdinfo *mdi = sysfs_read(fd, NULL,
+-							GET_CONSISTENCY_POLICY);
++			struct mdinfo *mdi;
++
++			mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY);
+ 			if (mdi) {
+ 				char *policy = map_num(consistency_policies,
+ 						       mdi->consistency_policy);
+@@ -528,8 +547,7 @@ int Detail(char *dev, struct context *c)
+ 
+ 		if (e && e->percent >= 0) {
+ 			static char *sync_action[] = {
+-				"Rebuild", "Resync",
+-				"Reshape", "Check"};
++				"Rebuild", "Resync", "Reshape", "Check"};
+ 			printf("    %7s Status : %d%% complete\n",
+ 			       sync_action[e->resync], e->percent);
+ 		}
+@@ -539,8 +557,9 @@ int Detail(char *dev, struct context *c)
+ #if 0
+ This is pretty boring
+ 			printf("     Reshape pos'n : %llu%s\n",
+-			       (unsigned long long) info->reshape_progress<<9,
+-			       human_size((unsigned long long)info->reshape_progress<<9));
++			       (unsigned long long) info->reshape_progress << 9,
++			       human_size((unsigned long long)
++					  info->reshape_progress << 9));
+ #endif
+ 			if (info->delta_disks != 0)
+ 				printf("     Delta Devices : %d, (%d->%d)\n",
+@@ -549,25 +568,29 @@ This is pretty boring
+ 				       array.raid_disks);
+ 			if (info->new_level != array.level) {
+ 				str = map_num(pers, info->new_level);
+-				printf("         New Level : %s\n", str?str:"-unknown-");
++				printf("         New Level : %s\n",
++				       str ? str : "-unknown-");
+ 			}
+ 			if (info->new_level != array.level ||
+ 			    info->new_layout != array.layout) {
+ 				if (info->new_level == 5) {
+-					str = map_num(r5layout, info->new_layout);
++					str = map_num(r5layout,
++						      info->new_layout);
+ 					printf("        New Layout : %s\n",
+-					       str?str:"-unknown-");
++					       str ? str : "-unknown-");
+ 				}
+ 				if (info->new_level == 6) {
+-					str = map_num(r6layout, info->new_layout);
++					str = map_num(r6layout,
++						      info->new_layout);
+ 					printf("        New Layout : %s\n",
+-					       str?str:"-unknown-");
++					       str ? str : "-unknown-");
+ 				}
+ 				if (info->new_level == 10) {
+ 					printf("        New Layout : near=%d, %s=%d\n",
+-					       info->new_layout&255,
+-					       (info->new_layout&0x10000)?"offset":"far",
+-					       (info->new_layout>>8)&255);
++					       info->new_layout & 255,
++					       (info->new_layout & 0x10000) ?
++					       "offset" : "far",
++					       (info->new_layout >> 8) & 255);
+ 				}
+ 			}
+ 			if (info->new_chunk != array.chunk_size)
+@@ -579,8 +602,10 @@ This is pretty boring
+ 		if (st && st->sb)
+ 			st->ss->detail_super(st, c->homehost);
+ 
+-		if (array.raid_disks == 0 && sra && sra->array.major_version == -1
+-		    && sra->array.minor_version == -2 && sra->text_version[0] != '/') {
++		if (array.raid_disks == 0 && sra &&
++		    sra->array.major_version == -1 &&
++		    sra->array.minor_version == -2 &&
++		    sra->text_version[0] != '/') {
+ 			/* This looks like a container.  Find any active arrays
+ 			 * That claim to be a member.
+ 			 */
+@@ -596,19 +621,21 @@ This is pretty boring
+ 				dev_t devid;
+ 				if (de->d_name[0] == '.')
+ 					continue;
+-				sprintf(path, "/sys/block/%s/md/metadata_version",
++				sprintf(path,
++					"/sys/block/%s/md/metadata_version",
+ 					de->d_name);
+ 				if (load_sys(path, vbuf, sizeof(vbuf)) < 0)
+ 					continue;
+-				if (strncmp(vbuf, "external:", 9) != 0 ||
+-				    !is_subarray(vbuf+9) ||
+-				    strncmp(vbuf+10, sra->sys_name, nlen) != 0 ||
+-				    vbuf[10+nlen] != '/')
++				if (strncmp(vbuf, "external:", 9) ||
++				    !is_subarray(vbuf + 9) ||
++				    strncmp(vbuf + 10, sra->sys_name, nlen) ||
++				    vbuf[10 + nlen] != '/')
+ 					continue;
+ 				devid = devnm2devid(de->d_name);
+-				printf(" %s", map_dev_preferred(
+-					       major(devid),
+-					       minor(devid), 1, c->prefer));
++				printf(" %s",
++				       map_dev_preferred(major(devid),
++							 minor(devid), 1,
++							 c->prefer));
+ 			}
+ 			if (dir)
+ 				closedir(dir);
+@@ -622,24 +649,23 @@ This is pretty boring
+ 	}
+ 	free(info);
+ 
+-	for (d= 0; d < max_disks * 2; d++) {
++	for (d = 0; d < max_disks * 2; d++) {
+ 		char *dv;
+ 		mdu_disk_info_t disk = disks[d];
+ 
+-		if (d >= array.raid_disks*2 &&
+-		    disk.major == 0 &&
+-		    disk.minor == 0)
++		if (d >= array.raid_disks * 2 &&
++		    disk.major == 0 && disk.minor == 0)
+ 			continue;
+-		if ((d & 1) &&
+-		    disk.major == 0 &&
+-		    disk.minor == 0)
++		if ((d & 1) && disk.major == 0 && disk.minor == 0)
+ 			continue;
+ 		if (!c->brief) {
+-			if (d == array.raid_disks*2) printf("\n");
++			if (d == array.raid_disks*2)
++				printf("\n");
+ 			if (disk.number < 0 && disk.raid_disk < 0)
+ 				printf("       -   %5d    %5d        -     ",
+ 				       disk.major, disk.minor);
+-			else if (disk.raid_disk < 0 || disk.state & (1<<MD_DISK_JOURNAL))
++			else if (disk.raid_disk < 0 ||
++				 disk.state & (1 << MD_DISK_JOURNAL))
+ 				printf("   %5d   %5d    %5d        -     ",
+ 				       disk.number, disk.major, disk.minor);
+ 			else if (disk.number < 0)
+@@ -647,34 +673,44 @@ This is pretty boring
+ 				       disk.major, disk.minor, disk.raid_disk);
+ 			else
+ 				printf("   %5d   %5d    %5d    %5d     ",
+-				       disk.number, disk.major, disk.minor, disk.raid_disk);
++				       disk.number, disk.major, disk.minor,
++				       disk.raid_disk);
+ 		}
+ 		if (!c->brief && array.raid_disks) {
+-
+-			if (disk.state & (1<<MD_DISK_FAULTY)) {
++			if (disk.state & (1 << MD_DISK_FAULTY)) {
+ 				printf(" faulty");
+ 				if (disk.raid_disk < array.raid_disks &&
+ 				    disk.raid_disk >= 0)
+ 					failed++;
+ 			}
+-			if (disk.state & (1<<MD_DISK_ACTIVE)) printf(" active");
+-			if (disk.state & (1<<MD_DISK_SYNC)) {
++			if (disk.state & (1 << MD_DISK_ACTIVE))
++				printf(" active");
++			if (disk.state & (1 << MD_DISK_SYNC)) {
+ 				printf(" sync");
+-				if (array.level == 10 && (array.layout & ~0x1FFFF) == 0) {
++				if (array.level == 10 &&
++				    (array.layout & ~0x1FFFF) == 0) {
+ 					int nc = array.layout & 0xff;
+ 					int fc = (array.layout >> 8) & 0xff;
+ 					int copies = nc*fc;
+-					if (fc == 1 && array.raid_disks % copies == 0 && copies <= 26) {
+-						/* We can divide the devices into 'sets' */
+-						int set = disk.raid_disk % copies;
++					if (fc == 1 &&
++					    array.raid_disks % copies == 0 &&
++					    copies <= 26) {
++						/* We can divide the devices
++						   into 'sets' */
++						int set;
++						set = disk.raid_disk % copies;
+ 						printf(" set-%c", set + 'A');
+ 					}
+ 				}
+ 			}
+-			if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
+-			if (disk.state & (1<<MD_DISK_WRITEMOSTLY)) printf(" writemostly");
+-			if (disk.state & (1<<MD_DISK_FAILFAST)) printf(" failfast");
+-			if (disk.state & (1<<MD_DISK_JOURNAL)) printf(" journal");
++			if (disk.state & (1 << MD_DISK_REMOVED))
++				printf(" removed");
++			if (disk.state & (1 << MD_DISK_WRITEMOSTLY))
++				printf(" writemostly");
++			if (disk.state & (1 << MD_DISK_FAILFAST))
++				printf(" failfast");
++			if (disk.state & (1 << MD_DISK_JOURNAL))
++				printf(" journal");
+ 			if ((disk.state &
+ 			     ((1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC)
+ 			      |(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)|(1<<MD_DISK_JOURNAL)))
+@@ -685,19 +721,21 @@ This is pretty boring
+ 					printf(" rebuilding");
+ 			}
+ 		}
+-		if (disk.state == 0) spares++;
+-		dv=map_dev_preferred(disk.major, disk.minor, 0, c->prefer);
++		if (disk.state == 0)
++			spares++;
++		dv = map_dev_preferred(disk.major, disk.minor, 0, c->prefer);
+ 		if (dv != NULL) {
+ 			if (c->brief)
+ 				n_devices = add_device(dv, &devices,
+-						       &max_devices,
+-						       n_devices);
++						       &max_devices, n_devices);
+ 			else
+ 				printf("   %s", dv);
+ 		}
+-		if (!c->brief) printf("\n");
++		if (!c->brief)
++			printf("\n");
+ 	}
+-	if (spares && c->brief && array.raid_disks) printf(" spares=%d", spares);
++	if (spares && c->brief && array.raid_disks)
++		printf(" spares=%d", spares);
+ 	if (c->brief && st && st->sb)
+ 		st->ss->brief_detail_super(st);
+ 	if (st)
+@@ -712,8 +750,7 @@ This is pretty boring
+ 	if (c->brief)
+ 		printf("\n");
+ 	if (c->test &&
+-	    !enough(array.level, array.raid_disks, array.layout,
+-		    1, avail))
++	    !enough(array.level, array.raid_disks, array.layout, 1, avail))
+ 		rv = 2;
+ 
+ 	free(disks);
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch b/SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch
new file mode 100644
index 0000000..7e8ae29
--- /dev/null
+++ b/SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch
@@ -0,0 +1,78 @@
+From 901d5ee6da145033ac30fee68f4fec0e8af9eddc Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:26:53 -0400
+Subject: [RHEL7.5 PATCH 057/169] Detail: Stop bothering about md drivers
+ older than 0.90.00
+
+Remove further handling of md driver version older than 0.90.00
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Detail.c | 27 +++++++--------------------
+ 1 file changed, 7 insertions(+), 20 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index fa6d4c7..d4e6204 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -54,7 +54,6 @@ int Detail(char *dev, struct context *c)
+ 	 * Print out details for an md array
+ 	 */
+ 	int fd = open(dev, O_RDONLY);
+-	int vers;
+ 	mdu_array_info_t array;
+ 	mdu_disk_info_t *disks;
+ 	int next;
+@@ -88,22 +87,14 @@ int Detail(char *dev, struct context *c)
+ 			dev, strerror(errno));
+ 		return rv;
+ 	}
+-	vers = md_get_version(fd);
+-	if (vers < 0) {
+-		pr_err("%s does not appear to be an md device\n",
+-			dev);
+-		close(fd);
+-		return rv;
+-	}
+-	if (vers < 9000) {
+-		pr_err("cannot get detail for md device %s: driver version too old.\n",
+-			dev);
++	sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS);
++	if (!sra) {
++		pr_err("%s does not appear to be an md device\n", dev);
+ 		close(fd);
+ 		return rv;
+ 	}
+-	sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS);
+-	external = (sra != NULL && sra->array.major_version == -1
+-		    && sra->array.minor_version == -2);
++	external = (sra != NULL && sra->array.major_version == -1 &&
++		    sra->array.minor_version == -2);
+ 	st = super_by_fd(fd, &subarray);
+ 	if (md_get_array_info(fd, &array) == 0) {
+ 		inactive = 0;
+@@ -378,9 +369,7 @@ int Detail(char *dev, struct context *c)
+ 		}
+ 
+ 		/* Only try GET_BITMAP_FILE for 0.90.01 and later */
+-		if (vers >= 9001 &&
+-		    ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 &&
+-		    bmf.pathname[0]) {
++		if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
+ 			printf(" bitmap=%s", bmf.pathname);
+ 		}
+ 	} else {
+@@ -449,9 +438,7 @@ int Detail(char *dev, struct context *c)
+ 			       array.not_persistent?"not ":"");
+ 		printf("\n");
+ 		/* Only try GET_BITMAP_FILE for 0.90.01 and later */
+-		if (vers >= 9001 &&
+-		    ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 &&
+-		    bmf.pathname[0]) {
++		if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
+ 			printf("     Intent Bitmap : %s\n", bmf.pathname);
+ 			printf("\n");
+ 		} else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-correct-outputfor-active-arrays.patch b/SOURCES/Detail-correct-outputfor-active-arrays.patch
new file mode 100644
index 0000000..081bd14
--- /dev/null
+++ b/SOURCES/Detail-correct-outputfor-active-arrays.patch
@@ -0,0 +1,111 @@
+From a822017f30e0dadc60a687900c2aa4da32e09a93 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Thu, 10 Aug 2017 11:43:48 +0200
+Subject: [RHEL7.5 PATCH 162/169] Detail: correct output for active arrays
+
+The check for inactive array is incorrect as it compares it against
+active array. Introduce a new function md_is_array_active so the check
+is consistent across the code.
+
+As the output contains list of disks in the array include this
+information in sysfs read.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 15 +++++++--------
+ mdadm.h  |  1 +
+ util.c   | 15 +++++++++------
+ 3 files changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index 2332b85..2c9fb24 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -86,7 +86,8 @@ int Detail(char *dev, struct context *c)
+ 			dev, strerror(errno));
+ 		return rv;
+ 	}
+-	sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
++	sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS |
++			GET_ARRAY_STATE | GET_STATE);
+ 	if (!sra) {
+ 		if (md_get_array_info(fd, &array)) {
+ 			pr_err("%s does not appear to be an md device\n", dev);
+@@ -96,8 +97,7 @@ int Detail(char *dev, struct context *c)
+ 	}
+ 	external = (sra != NULL && sra->array.major_version == -1 &&
+ 		    sra->array.minor_version == -2);
+-	inactive = (sra->array_state == ARRAY_ACTIVE ||
+-		    sra->array_state == ARRAY_CLEAR);
++	inactive = (sra != NULL && !md_array_is_active(sra));
+ 	st = super_by_fd(fd, &subarray);
+ 	if (md_get_array_info(fd, &array)) {
+ 		if (errno == ENODEV) {
+@@ -314,11 +314,10 @@ int Detail(char *dev, struct context *c)
+ 	next = array.raid_disks * 2;
+ 	if (inactive) {
+ 		struct mdinfo *mdi;
+-		if (sra != NULL)
+-			for (mdi = sra->devs; mdi; mdi = mdi->next) {
+-				disks[next++] = mdi->disk;
+-				disks[next - 1].number = -1;
+-			}
++		for (mdi = sra->devs; mdi; mdi = mdi->next) {
++			disks[next++] = mdi->disk;
++			disks[next - 1].number = -1;
++		}
+ 	} else for (d = 0; d < max_disks; d++) {
+ 		mdu_disk_info_t disk;
+ 		disk.number = d;
+diff --git a/mdadm.h b/mdadm.h
+index ee9b837..191ae8f 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1425,6 +1425,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 
+ int md_array_valid(int fd);
+ int md_array_active(int fd);
++int md_array_is_active(struct mdinfo *info);
+ int md_get_array_info(int fd, struct mdu_array_info_s *array);
+ int md_set_array_info(int fd, struct mdu_array_info_s *array);
+ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk);
+diff --git a/util.c b/util.c
+index 8eeb509..c1c8509 100644
+--- a/util.c
++++ b/util.c
+@@ -228,15 +228,11 @@ int md_array_active(int fd)
+ {
+ 	struct mdinfo *sra;
+ 	struct mdu_array_info_s array;
+-	int ret;
++	int ret = 0;
+ 
+ 	sra = sysfs_read(fd, NULL, GET_ARRAY_STATE);
+ 	if (sra) {
+-		if (sra->array_state != ARRAY_CLEAR &&
+-		    sra->array_state != ARRAY_INACTIVE &&
+-		    sra->array_state != ARRAY_UNKNOWN_STATE)
+-			ret = 0;
+-		else
++		if (!md_array_is_active(sra))
+ 			ret = -ENODEV;
+ 
+ 		free(sra);
+@@ -251,6 +247,13 @@ int md_array_active(int fd)
+ 	return !ret;
+ }
+ 
++int md_array_is_active(struct mdinfo *info)
++{
++	return (info->array_state != ARRAY_CLEAR &&
++		info->array_state != ARRAY_INACTIVE &&
++		info->array_state != ARRAY_UNKNOWN_STATE);
++}
++
+ /*
+  * Get array info from the kernel. Longer term we want to deprecate the
+  * ioctl and get it from sysfs.
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-determine2-array-state-from-sysfs.patch b/SOURCES/Detail-determine2-array-state-from-sysfs.patch
new file mode 100644
index 0000000..8d054f1
--- /dev/null
+++ b/SOURCES/Detail-determine2-array-state-from-sysfs.patch
@@ -0,0 +1,54 @@
+From a4dcdb23ea639d14e92d1c86336de7ad505b2f7d Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 25 Apr 2017 11:40:27 -0400
+Subject: [RHEL7.5 PATCH 095/169] Detail: determine array state from sysfs
+
+This is easily obtained from sysfs as part of the existing call to
+sysfs_read() and it simplifies the code a little too.
+
+Another small step in the process of getting rid of the GET_ARRAY_STATE
+ioctl.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index 91c5a98..eb69276 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -86,7 +86,7 @@ int Detail(char *dev, struct context *c)
+ 			dev, strerror(errno));
+ 		return rv;
+ 	}
+-	sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS);
++	sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE);
+ 	if (!sra) {
+ 		pr_err("%s does not appear to be an md device\n", dev);
+ 		close(fd);
+@@ -94,10 +94,10 @@ int Detail(char *dev, struct context *c)
+ 	}
+ 	external = (sra != NULL && sra->array.major_version == -1 &&
+ 		    sra->array.minor_version == -2);
++	inactive = (sra->array_state == ARRAY_ACTIVE ||
++		    sra->array_state == ARRAY_CLEAR);
+ 	st = super_by_fd(fd, &subarray);
+-	if (md_get_array_info(fd, &array) == 0) {
+-		inactive = 0;
+-	} else if (errno == ENODEV && sra) {
++	if (md_get_array_info(fd, &array) && errno == ENODEV) {
+ 		if (sra->array.major_version == -1 &&
+ 		    sra->array.minor_version == -1 &&
+ 		    sra->devs == NULL) {
+@@ -107,7 +107,6 @@ int Detail(char *dev, struct context *c)
+ 			return rv;
+ 		}
+ 		array = sra->array;
+-		inactive = 1;
+ 	} else {
+ 		pr_err("cannot get array detail for %s: %s\n",
+ 		       dev, strerror(errno));
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-differentiate-between-container-and-inactive-.patch b/SOURCES/Detail-differentiate-between-container-and-inactive-.patch
new file mode 100644
index 0000000..b4a0d73
--- /dev/null
+++ b/SOURCES/Detail-differentiate-between-container-and-inactive-.patch
@@ -0,0 +1,89 @@
+From bb8354598676428af01f23bfb1876c7356d61147 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Fri, 18 Aug 2017 12:00:23 +0200
+Subject: [RHEL7.5 PATCH 01/13] Detail: differentiate between container and
+ inactive arrays
+
+Containers used to be handled as active arrays because GET_ARRAY_INFO
+ioctl returns valid structure for them. As containers appear as inactive
+in sysfs, the output for detail command has changed.
+
+Stop relying on inactive state for containers. Make the output look the
+same as in mdadm 4.0.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index 2c9fb24..4dcf81d 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -80,6 +80,7 @@ int Detail(char *dev, struct context *c)
+ 	char *avail = NULL;
+ 	int external;
+ 	int inactive;
++	int is_container = 0;
+ 
+ 	if (fd < 0) {
+ 		pr_err("cannot open %s: %s\n",
+@@ -119,6 +120,8 @@ int Detail(char *dev, struct context *c)
+ 		}
+ 	}
+ 
++	if (array.raid_disks == 0 && external)
++		is_container = 1;
+ 	if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
+ 		stb.st_rdev = 0;
+ 	rv = 0;
+@@ -228,7 +231,7 @@ int Detail(char *dev, struct context *c)
+ 				printf("MD_LEVEL=%s\n", str);
+ 			printf("MD_DEVICES=%d\n", array.raid_disks);
+ 		} else {
+-			if (!inactive)
++			if (is_container)
+ 				printf("MD_LEVEL=container\n");
+ 			printf("MD_DEVICES=%d\n", array.nr_disks);
+ 		}
+@@ -357,13 +360,16 @@ int Detail(char *dev, struct context *c)
+ 
+ 	if (c->brief) {
+ 		mdu_bitmap_file_t bmf;
+-		printf("%sARRAY %s", inactive ? "INACTIVE-":"", dev);
++		if (inactive && !is_container)
++			printf("INACTIVE-ARRAY %s", dev);
++		else
++			printf("ARRAY %s", dev);
+ 		if (c->verbose > 0) {
+ 			if (array.raid_disks)
+ 				printf(" level=%s num-devices=%d",
+ 				       str ? str : "-unknown-",
+ 				       array.raid_disks);
+-			else if (!inactive)
++			else if (is_container)
+ 				printf(" level=container num-devices=%d",
+ 				       array.nr_disks);
+ 			else
+@@ -416,7 +422,7 @@ int Detail(char *dev, struct context *c)
+ 		atime = array.ctime;
+ 		if (atime)
+ 			printf("     Creation Time : %.24s\n", ctime(&atime));
+-		if (array.raid_disks == 0 && external)
++		if (is_container)
+ 			str = "container";
+ 		if (str)
+ 			printf("        Raid Level : %s\n", str);
+@@ -489,7 +495,7 @@ int Detail(char *dev, struct context *c)
+ 			       " (DELAYED)": "",
+ 			       (e && e->percent == RESYNC_PENDING) ?
+ 			       " (PENDING)": "");
+-		} else if (inactive) {
++		} else if (inactive && !is_container) {
+ 			printf("             State : inactive\n");
+ 		}
+ 		if (array.raid_disks)
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch b/SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch
new file mode 100644
index 0000000..288f9ce
--- /dev/null
+++ b/SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch
@@ -0,0 +1,76 @@
+From 9b8fea914f82281c440cdce9dee6a3775265861c Mon Sep 17 00:00:00 2001
+From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date: Wed, 24 May 2017 11:34:22 +0200
+Subject: [RHEL7.5 PATCH 147/169] Detail: don't exit if ioctl has been
+ successful
+
+When GET_ARRAY_INFO ioctl is successful, mdadm exits with an error.
+It breaks udev and no links in /dev/md are created.
+
+Also change debug print to error print in the message indicating lack
+of the link to facilitate debugging similar issues in the future.
+
+Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 27 +++++++++++++++------------
+ util.c   |  2 +-
+ 2 files changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index bf881ff..2332b85 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -99,21 +99,24 @@ int Detail(char *dev, struct context *c)
+ 	inactive = (sra->array_state == ARRAY_ACTIVE ||
+ 		    sra->array_state == ARRAY_CLEAR);
+ 	st = super_by_fd(fd, &subarray);
+-	if (md_get_array_info(fd, &array) && errno == ENODEV) {
+-		if (sra->array.major_version == -1 &&
+-		    sra->array.minor_version == -1 &&
+-		    sra->devs == NULL) {
+-			pr_err("Array associated with md device %s does not exist.\n", dev);
++	if (md_get_array_info(fd, &array)) {
++		if (errno == ENODEV) {
++			if (sra->array.major_version == -1 &&
++			    sra->array.minor_version == -1 &&
++			    sra->devs == NULL) {
++				pr_err("Array associated with md device %s does not exist.\n",
++				       dev);
++				close(fd);
++				sysfs_free(sra);
++				return rv;
++			}
++			array = sra->array;
++		} else {
++			pr_err("cannot get array detail for %s: %s\n",
++			       dev, strerror(errno));
+ 			close(fd);
+-			sysfs_free(sra);
+ 			return rv;
+ 		}
+-		array = sra->array;
+-	} else {
+-		pr_err("cannot get array detail for %s: %s\n",
+-		       dev, strerror(errno));
+-		close(fd);
+-		return rv;
+ 	}
+ 
+ 	if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
+diff --git a/util.c b/util.c
+index d89438c..8eeb509 100644
+--- a/util.c
++++ b/util.c
+@@ -1169,7 +1169,7 @@ void wait_for(char *dev, int fd)
+ 			delay *= 2;
+ 	}
+ 	if (i == 25)
+-		dprintf("timeout waiting for %s\n", dev);
++		pr_err("timeout waiting for %s\n", dev);
+ }
+ 
+ struct superswitch *superlist[] =
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch b/SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch
new file mode 100644
index 0000000..7f2f073
--- /dev/null
+++ b/SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch
@@ -0,0 +1,69 @@
+From b9c9bd9bacaab701d5b3cb3e4b6cb02ea8d36e47 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 20 Apr 2017 12:40:06 +1000
+Subject: [RHEL7.5 PATCH 089/169] Detail: ensure --export names are
+ acceptable as shell variables.
+
+If an array contains a device which has a name that
+contains something other than alphnumerics and underscores,
+then some values reported by "mdadm --detail --export" will
+not be valid as variable assignment of the shell.
+This particularly affects dm devices.
+e.g.
+   MD_DEVICE_dm-4_ROLE=1
+   MD_DEVICE_dm-4_DEV=/dev/dm-4
+
+As it is particularly useful to be able to work with these
+in a shell script, and as the precise name is not important,
+change all non-alphanumerics to '_'.
+
+   MD_DEVICE_dm_4_ROLE=1
+   MD_DEVICE_dm_4_DEV=/dev/dm-4
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index e40cd8f..91c5a98 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -25,6 +25,7 @@
+ #include	"mdadm.h"
+ #include	"md_p.h"
+ #include	"md_u.h"
++#include	<ctype.h>
+ #include	<dirent.h>
+ 
+ static int cmpstringp(const void *p1, const void *p2)
+@@ -276,17 +277,22 @@ int Detail(char *dev, struct context *c)
+ 				char *path =
+ 					map_dev(mdi->disk.major,
+ 						mdi->disk.minor, 0);
++				char *sysdev = xstrdup(mdi->sys_name + 1);
++				char *cp;
++				for (cp = sysdev; *cp; cp++)
++					if (!isalnum(*cp))
++						*cp = '_';
+ 
+ 				if (mdi->disk.raid_disk >= 0)
+ 					printf("MD_DEVICE_%s_ROLE=%d\n",
+-					       mdi->sys_name+4,
++					       sysdev,
+ 					       mdi->disk.raid_disk);
+ 				else
+ 					printf("MD_DEVICE_%s_ROLE=spare\n",
+-					       mdi->sys_name+4);
++					       sysdev);
+ 				if (path)
+ 					printf("MD_DEVICE_%s_DEV=%s\n",
+-					       mdi->sys_name+4, path);
++					       sysdev, path);
+ 			}
+ 		}
+ 		goto out;
+-- 
+2.7.4
+
diff --git a/SOURCES/Detail-handle-non-existent-arrays-better.patch b/SOURCES/Detail-handle-non-existent-arrays-better.patch
new file mode 100644
index 0000000..d5be68d
--- /dev/null
+++ b/SOURCES/Detail-handle-non-existent-arrays-better.patch
@@ -0,0 +1,45 @@
+From b4decd517d90098bc2d17d3eddfe858d8b903920 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Mon, 27 Mar 2017 14:36:56 +1100
+Subject: [RHEL7.5 PATCH 024/169] Detail: handle non-existent arrays
+ better.
+
+If you call "mdadm --detail" with a device file for an array which
+doesn't exist, such as by
+  mknod /dev/md57 b 9 57
+  mdadm --detail /dev/md57
+
+you get an unhelpful message about and inactive RAID0, and return
+status is '0'.  This is confusing.
+
+So catch this possibility and print a more useful message, and
+return a non-zero status.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Detail.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/Detail.c b/Detail.c
+index cb33794..3d92855 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -110,6 +110,14 @@ int Detail(char *dev, struct context *c)
+ 	if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) {
+ 		inactive = 0;
+ 	} else if (errno == ENODEV && sra) {
++		if (sra->array.major_version == -1 &&
++		    sra->array.minor_version == -1 &&
++		    sra->devs == NULL) {
++			pr_err("Array associated with md device %s does not exist.\n", dev);
++			close(fd);
++			sysfs_free(sra);
++			return rv;
++		}
+ 		array = sra->array;
+ 		inactive = 1;
+ 	} else {
+-- 
+2.7.4
+
diff --git a/SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch b/SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch
new file mode 100644
index 0000000..c1a3530
--- /dev/null
+++ b/SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch
@@ -0,0 +1,106 @@
+From 2c8890e926a4c7f9169b5054e3dbf84426fe1025 Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Thu, 28 Sep 2017 14:41:07 +0200
+Subject: [PATCH 01/12] Don't abort starting the array if kernel does
+ not support ppl
+
+Change the behavior of assemble and create for consistency-policy=ppl
+for external metadata arrays. If the kernel does not support ppl, don't
+abort but print a warning and start the array without ppl
+(consistency-policy=resync). No change for native md arrays because the
+kernel will not allow starting the array if it finds an unsupported
+feature bit in the superblock.
+
+In sysfs_add_disk() check consistency_policy in the mdinfo structure
+that represents the array, not the disk and read the current consistency
+policy from sysfs in mdmon's manage_member(). This is necessary to make
+sysfs_add_disk() honor the actual consistency policy and not what is in
+the metadata. Also remove all the places where consistency_policy is set
+for a disk's mdinfo - it is a property of the array, not the disk.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ managemon.c   | 11 ++++++++---
+ super-intel.c |  4 +---
+ sysfs.c       |  6 +++---
+ 3 files changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/managemon.c b/managemon.c
+index 68f0c2d..cc3c6f1 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -477,7 +477,7 @@ static void manage_member(struct mdstat_ent *mdstat,
+ 	char buf[64];
+ 	int frozen;
+ 	struct supertype *container = a->container;
+-	unsigned long long int component_size = 0;
++	struct mdinfo *mdi;
+ 
+ 	if (container == NULL)
+ 		/* Raced with something */
+@@ -489,8 +489,13 @@ static void manage_member(struct mdstat_ent *mdstat,
+ 		// MORE
+ 	}
+ 
+-	if (sysfs_get_ll(&a->info, NULL, "component_size", &component_size) >= 0)
+-		a->info.component_size = component_size << 1;
++	mdi = sysfs_read(-1, mdstat->devnm,
++			 GET_COMPONENT|GET_CONSISTENCY_POLICY);
++	if (mdi) {
++		a->info.component_size = mdi->component_size;
++		a->info.consistency_policy = mdi->consistency_policy;
++		sysfs_free(mdi);
++	}
+ 
+ 	/* honor 'frozen' */
+ 	if (sysfs_get_str(&a->info, NULL, "metadata_version", buf, sizeof(buf)) > 0)
+diff --git a/super-intel.c b/super-intel.c
+index bbe7bc7..e3dcd3d 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7669,7 +7669,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 			} else {
+ 				info_d->component_size = blocks_per_member(map);
+ 			}
+-			info_d->consistency_policy = this->consistency_policy;
+ 
+ 			info_d->bb.supported = 1;
+ 			get_volume_badblocks(super->bbm_log, ord_to_idx(ord),
+@@ -8758,8 +8757,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
+ 		di->component_size = a->info.component_size;
+ 		di->container_member = inst;
+ 		di->bb.supported = 1;
+-		if (dev->rwh_policy == RWH_DISTRIBUTED) {
+-			di->consistency_policy = CONSISTENCY_POLICY_PPL;
++		if (a->info.consistency_policy == CONSISTENCY_POLICY_PPL) {
+ 			di->ppl_sector = get_ppl_sector(super, inst);
+ 			di->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9;
+ 		}
+diff --git a/sysfs.c b/sysfs.c
+index 68ddd5f..bf5c8c5 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -709,8 +709,8 @@ int sysfs_set_array(struct mdinfo *info, int vers)
+ 		if (sysfs_set_str(info, NULL, "consistency_policy",
+ 				  map_num(consistency_policies,
+ 					  info->consistency_policy))) {
+-			pr_err("This kernel does not support PPL\n");
+-			return 1;
++			pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n");
++			info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
+ 		}
+ 	}
+ 
+@@ -745,7 +745,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
+ 	rv = sysfs_set_num(sra, sd, "offset", sd->data_offset);
+ 	rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
+ 	if (sra->array.level != LEVEL_CONTAINER) {
+-		if (sd->consistency_policy == CONSISTENCY_POLICY_PPL) {
++		if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) {
+ 			rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector);
+ 			rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size);
+ 		}
+-- 
+2.7.4
+
diff --git a/SOURCES/Don-t-use-UnSet-with-consistency_policy.patch b/SOURCES/Don-t-use-UnSet-with-consistency_policy.patch
new file mode 100644
index 0000000..aa02c1f
--- /dev/null
+++ b/SOURCES/Don-t-use-UnSet-with-consistency_policy.patch
@@ -0,0 +1,122 @@
+From b75805662e7208799207a8e5f8a61f69a44888f0 Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Mon, 24 Apr 2017 16:03:26 +0200
+Subject: [RHEL7.5 PATCH 094/169] Don't use UnSet with consistency_policy
+
+Use CONSISTENCY_POLICY_UNKNOWN instead. Simplify some checks because
+since 5e8e35fb7e17 ("maps: Use keyvalue for null terminator to indicate
+'unset' value") map_name() can return this default directly.
+
+Suggested-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+---
+ maps.c        |  2 +-
+ mdadm.c       | 12 ++++++------
+ super-intel.c |  4 +---
+ sysfs.c       | 10 ++++------
+ 4 files changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/maps.c b/maps.c
+index bb28ba6..02a0474 100644
+--- a/maps.c
++++ b/maps.c
+@@ -137,7 +137,7 @@ mapping_t consistency_policies[] = {
+ 	{ "bitmap", CONSISTENCY_POLICY_BITMAP},
+ 	{ "journal", CONSISTENCY_POLICY_JOURNAL},
+ 	{ "ppl", CONSISTENCY_POLICY_PPL},
+-	{ NULL, UnSet }
++	{ NULL, CONSISTENCY_POLICY_UNKNOWN }
+ };
+ 
+ mapping_t sysfs_array_states[] = {
+diff --git a/mdadm.c b/mdadm.c
+index 41dae1d..b689e32 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
+ 		.level		= UnSet,
+ 		.layout		= UnSet,
+ 		.bitmap_chunk	= UnSet,
+-		.consistency_policy	= UnSet,
++		.consistency_policy	= CONSISTENCY_POLICY_UNKNOWN,
+ 	};
+ 
+ 	char sys_hostname[256];
+@@ -1228,8 +1228,7 @@ int main(int argc, char *argv[])
+ 		case O(GROW, 'k'):
+ 			s.consistency_policy = map_name(consistency_policies,
+ 							optarg);
+-			if (s.consistency_policy == UnSet ||
+-			    s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
++			if (s.consistency_policy < CONSISTENCY_POLICY_RESYNC) {
+ 				pr_err("Invalid consistency policy: %s\n",
+ 				       optarg);
+ 				exit(2);
+@@ -1267,7 +1266,7 @@ int main(int argc, char *argv[])
+ 			pr_err("--write-journal is only supported for RAID level 4/5/6.\n");
+ 			exit(2);
+ 		}
+-		if (s.consistency_policy != UnSet &&
++		if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN &&
+ 		    s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
+ 			pr_err("--write-journal is not supported with consistency policy: %s\n",
+ 			       map_num(consistency_policies, s.consistency_policy));
+@@ -1275,7 +1274,8 @@ int main(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	if (mode == CREATE && s.consistency_policy != UnSet) {
++	if (mode == CREATE &&
++	    s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
+ 		if (s.level <= 0) {
+ 			pr_err("--consistency-policy not meaningful with level %s.\n",
+ 			       map_num(pers, s.level));
+@@ -1687,7 +1687,7 @@ int main(int argc, char *argv[])
+ 			rv = Grow_reshape(devlist->devname, mdfd,
+ 					  devlist->next,
+ 					  data_offset, &c, &s);
+-		} else if (s.consistency_policy != UnSet) {
++		} else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
+ 			rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
+ 		} else if (array_size == 0)
+ 			pr_err("no changes to --grow\n");
+diff --git a/super-intel.c b/super-intel.c
+index 0aed57c..fbff215 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -5369,9 +5369,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ 	}
+ 	mpb->num_raid_devs++;
+ 
+-	if (s->consistency_policy == UnSet ||
+-	    s->consistency_policy == CONSISTENCY_POLICY_RESYNC ||
+-	    s->consistency_policy == CONSISTENCY_POLICY_NONE) {
++	if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) {
+ 		dev->rwh_policy = RWH_OFF;
+ 	} else if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
+ 		dev->rwh_policy = RWH_DISTRIBUTED;
+diff --git a/sysfs.c b/sysfs.c
+index 712f8b3..aa30de5 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -254,13 +254,11 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 
+ 	if (options & GET_CONSISTENCY_POLICY) {
+ 		strcpy(base, "consistency_policy");
+-		if (load_sys(fname, buf, sizeof(buf))) {
++		if (load_sys(fname, buf, sizeof(buf)))
+ 			sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
+-		} else {
+-			sra->consistency_policy = map_name(consistency_policies, buf);
+-			if (sra->consistency_policy == UnSet)
+-				sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN;
+-		}
++		else
++			sra->consistency_policy = map_name(consistency_policies,
++							   buf);
+ 	}
+ 
+ 	if (! (options & GET_DEVS))
+-- 
+2.7.4
+
diff --git a/SOURCES/Don-t-use-exit-ERANGE.patch b/SOURCES/Don-t-use-exit-ERANGE.patch
new file mode 100644
index 0000000..12314cd
--- /dev/null
+++ b/SOURCES/Don-t-use-exit-ERANGE.patch
@@ -0,0 +1,31 @@
+From dcd24efcfab50c3c298d9b1c941edb6954c2677e Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 4 Aug 2017 15:30:02 +1000
+Subject: [RHEL7.5 PATCH 167/169] Don't use exit(ERANGE)
+
+mdadm uses smaller exit codes like 0,1,2,3,4.
+Using ERANGE is inconsistent and not helpful.
+So change it to a more consistent number.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 70b16f2..d80aab3 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -619,7 +619,7 @@ int main(int argc, char *argv[])
+ 			c.homecluster = optarg;
+ 			if (strlen(c.homecluster) > 64) {
+ 				pr_err("Cluster name too big.\n");
+-				exit(ERANGE);
++				exit(2);
+ 			}
+ 			continue;
+ 		case O(CREATE,'x'): /* number of spare (eXtra) disks */
+-- 
+2.7.4
+
diff --git a/SOURCES/Error-messages-should-end-with-a-newline-character.patch b/SOURCES/Error-messages-should-end-with-a-newline-character.patch
new file mode 100644
index 0000000..5729ef8
--- /dev/null
+++ b/SOURCES/Error-messages-should-end-with-a-newline-character.patch
@@ -0,0 +1,91 @@
+From 8e5b52cdda95965787e2a289c855a4ab7099f00d Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 4 Aug 2017 15:30:02 +1000
+Subject: [RHEL7.5 PATCH 164/169] Error messages should end with a newline
+ character.
+
+Add "\n" to the end of error messages which don't already
+have one.  Also spell "opened" correctly.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Build.c  | 4 ++--
+ Grow.c   | 4 ++--
+ Manage.c | 2 +-
+ mdopen.c | 2 +-
+ 4 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/Build.c b/Build.c
+index 70ba068..962c2e3 100644
+--- a/Build.c
++++ b/Build.c
+@@ -181,7 +181,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 			int major = BITMAP_MAJOR_HI;
+ #if 0
+ 			if (s->bitmap_chunk == UnSet) {
+-				pr_err("%s cannot be openned.", s->bitmap_file);
++				pr_err("%s cannot be opened.\n", s->bitmap_file);
+ 				goto abort;
+ 			}
+ #endif
+@@ -193,7 +193,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 			}
+ 			bitmap_fd = open(s->bitmap_file, O_RDWR);
+ 			if (bitmap_fd < 0) {
+-				pr_err("%s cannot be openned.", s->bitmap_file);
++				pr_err("%s cannot be opened.\n", s->bitmap_file);
+ 				goto abort;
+ 			}
+ 		}
+diff --git a/Grow.c b/Grow.c
+index b1cb306..534ba80 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -3202,7 +3202,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 
+ 		if (info2) {
+ 			if (sysfs_init(info2, fd, st->devnm)) {
+-				pr_err("unable to initialize sysfs for %s",
++				pr_err("unable to initialize sysfs for %s\n",
+ 				       st->devnm);
+ 				free(info2);
+ 				goto release;
+@@ -5146,7 +5146,7 @@ int Grow_continue_command(char *devname, int fd,
+ 		}
+ 
+ 		if (sysfs_init(content, fd2, mdstat->devnm)) {
+-			pr_err("Unable to initialize sysfs for %s, Grow cannot continue",
++			pr_err("Unable to initialize sysfs for %s, Grow cannot continue.\n",
+ 			       mdstat->devnm);
+ 			ret_val = 1;
+ 			close(fd2);
+diff --git a/Manage.c b/Manage.c
+index b82a729..871d342 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1417,7 +1417,7 @@ int Manage_subdevs(char *devname, int fd,
+ 			}
+ 			add_devlist = conf_get_devs();
+ 			if (add_devlist == NULL) {
+-				pr_err("no devices to scan for missing members.");
++				pr_err("no devices to scan for missing members.\n");
+ 				continue;
+ 			}
+ 			for (dp = &add_devlist; *dp; dp = & (*dp)->next)
+diff --git a/mdopen.c b/mdopen.c
+index c4f1c12..3c0052f 100644
+--- a/mdopen.c
++++ b/mdopen.c
+@@ -198,7 +198,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+ 			return -1;
+ 		}
+ 		if (cname[0] == 0) {
+-			pr_err("%s is an invalid name for an md device (empty!).", dev);
++			pr_err("%s is an invalid name for an md device (empty!).\n", dev);
+ 			return -1;
+ 		}
+ 		if (num < 0) {
+-- 
+2.7.4
+
diff --git a/SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch b/SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch
new file mode 100644
index 0000000..8f3f175
--- /dev/null
+++ b/SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch
@@ -0,0 +1,44 @@
+From bb6f40bf9c458a13b1a780006733c034105e6d36 Mon Sep 17 00:00:00 2001
+From: Wol <anthony@youngman.org.uk>
+Date: Tue, 17 Jan 2017 17:47:05 +0000
+Subject: [RHEL7.5 PATCH 003/169] Fix oddity where mdadm did not recognise
+ a relative path
+
+mdadm assumed that a pathname started with a "/", while an array
+name didn't. This alters the logic so that if the first character
+is not a "/" it tries to open an array, and if that fails it drops
+through to the pathname code rather than terminating immediately
+with an error.
+
+Signed-off-by: Wol <anthony@youngman.org.uk>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index c3a265b..b5d89e4 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1899,12 +1899,12 @@ static int misc_list(struct mddev_dev *devlist,
+ 			rv |= SetAction(dv->devname, c->action);
+ 			continue;
+ 		}
+-		if (dv->devname[0] == '/')
+-			mdfd = open_mddev(dv->devname, 1);
+-		else {
+-			mdfd = open_dev(dv->devname);
+-			if (mdfd < 0)
+-				pr_err("Cannot open %s\n", dv->devname);
++		switch(dv->devname[0] == '/') {
++			case 0:
++				mdfd = open_dev(dv->devname);
++				if (mdfd >= 0) break;
++			case 1:
++				mdfd = open_mddev(dv->devname, 1);  
+ 		}
+ 		if (mdfd>=0) {
+ 			switch(dv->disposition) {
+-- 
+2.7.4
+
diff --git a/SOURCES/Fix-typo2-in-new-udev-rule.patch b/SOURCES/Fix-typo2-in-new-udev-rule.patch
new file mode 100644
index 0000000..61198ba
--- /dev/null
+++ b/SOURCES/Fix-typo2-in-new-udev-rule.patch
@@ -0,0 +1,45 @@
+From dd180cb136d6b2193a58ea0de23b8a7942ca6f36 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 5 May 2017 15:16:15 +1000
+Subject: [RHEL7.5 PATCH 111/169] Fix typo in new udev rule.
+
+As pointed out by Peter Rajnoha, the correct usage in udev is
+TEST=="file", not TEST="file".
+
+Also improve a related comment which was a bit informal.
+
+Reported-by: Peter Rajnoha <prajnoha@redhat.com>
+Fixes: cd6cbb08c458 ("Create: tell udev md device is not ready when first created.")
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ lib.c                       | 2 +-
+ udev-md-raid-creating.rules | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib.c b/lib.c
+index 7e44b1f..be093e8 100644
+--- a/lib.c
++++ b/lib.c
+@@ -165,7 +165,7 @@ char *fd2devnm(int fd)
+ 
+ /* When we create a new array, we don't want the content to
+  * be immediately examined by udev - it is probably meaningless.
+- * So create /run/mdadm/creating-FOO and expect that a udev
++ * So create /run/mdadm/creating-mdXXX and expect that a udev
+  * rule will noticed this and act accordingly.
+  */
+ static char block_path[] = "/run/mdadm/creating-%s";
+diff --git a/udev-md-raid-creating.rules b/udev-md-raid-creating.rules
+index 2be466b..9bef8d1 100644
+--- a/udev-md-raid-creating.rules
++++ b/udev-md-raid-creating.rules
+@@ -4,4 +4,4 @@
+ # the array is not "ready" and we should make sure the
+ # content is ignored.
+ 
+-KERNEL=="md*", TEST="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0"
++KERNEL=="md*", TEST=="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0"
+-- 
+2.7.4
+
diff --git a/SOURCES/Get-failed-disk-count-fromarray-state.patch b/SOURCES/Get-failed-disk-count-fromarray-state.patch
new file mode 100644
index 0000000..54fb057
--- /dev/null
+++ b/SOURCES/Get-failed-disk-count-fromarray-state.patch
@@ -0,0 +1,163 @@
+From b13b52c80f3d9e3184ea1d6d39aa7053ef7bae49 Mon Sep 17 00:00:00 2001
+From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date: Wed, 31 May 2017 12:46:57 +0200
+Subject: [RHEL7.5 PATCH 151/169] Get failed disk count from array state
+
+Recent commit has changed the way failed disks are counted. It breaks
+recovery for external metadata arrays as failed disks are not part of
+the array and have no corresponding entries is sysfs (they are only
+reported for containers) so degraded arrays show no failed disks.
+
+Recent commit overwrites GET_DEGRADED result prior to GET_STATE and it
+is not set again if GET_STATE has not been requested. As GET_STATE
+provides the same information as GET_DEGRADED, the latter is not needed
+anymore. Remove GET_DEGRADED option and replace it with GET_STATE
+option.
+
+Don't count number of failed disks looking at sysfs entries but
+calculate it at the end. Do it only for arrays as containers report
+no disks, just spares.
+
+Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 14 ++++----------
+ Monitor.c     |  4 ++--
+ managemon.c   |  4 ++--
+ mdadm.h       |  1 -
+ raid6check.c  |  2 +-
+ sysfs.c       | 18 ++++++++----------
+ 6 files changed, 17 insertions(+), 26 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index 30dc7a2..6cf2174 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -886,16 +886,10 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 		}
+ 		sra = sysfs_read(-1, mp->devnm,
+ 				 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
+-				 GET_DEGRADED|GET_COMPONENT|GET_VERSION);
+-		if (!sra) {
+-			/* Probably a container - no degraded info */
+-			sra = sysfs_read(-1, mp->devnm,
+-					 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
+-					 GET_COMPONENT|GET_VERSION);
+-			if (sra)
+-				sra->array.failed_disks = -1;
+-		}
+-		if (!sra)
++				 GET_COMPONENT|GET_VERSION);
++		if (sra)
++			sra->array.failed_disks = -1;
++		else
+ 			continue;
+ 		if (st == NULL) {
+ 			int i;
+diff --git a/Monitor.c b/Monitor.c
+index 725f47d..bef2f1b 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -485,8 +485,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->devnm[0] == 0)
+ 		strcpy(st->devnm, fd2devnm(fd));
+ 
+-	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
+-			 GET_MISMATCH | GET_DEVS | GET_STATE);
++	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_MISMATCH |
++			 GET_DEVS | GET_STATE);
+ 	if (!sra)
+ 		goto disappeared;
+ 
+diff --git a/managemon.c b/managemon.c
+index a8df666..68f0c2d 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -685,8 +685,8 @@ static void manage_new(struct mdstat_ent *mdstat,
+ 
+ 	mdi = sysfs_read(-1, mdstat->devnm,
+ 			 GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT|
+-			 GET_DEGRADED|GET_SAFEMODE|
+-			 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|GET_LAYOUT);
++			 GET_SAFEMODE|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
++			 GET_LAYOUT);
+ 
+ 	if (!mdi)
+ 		return;
+diff --git a/mdadm.h b/mdadm.h
+index ec0a39e..ee9b837 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -637,7 +637,6 @@ enum sysfs_read_flags {
+ 	GET_MISMATCH	= (1 << 5),
+ 	GET_VERSION	= (1 << 6),
+ 	GET_DISKS	= (1 << 7),
+-	GET_DEGRADED	= (1 << 8),
+ 	GET_SAFEMODE	= (1 << 9),
+ 	GET_BITMAP_LOCATION = (1 << 10),
+ 
+diff --git a/raid6check.c b/raid6check.c
+index 551f835..a8e6005 100644
+--- a/raid6check.c
++++ b/raid6check.c
+@@ -562,7 +562,7 @@ int main(int argc, char *argv[])
+ 			  GET_LEVEL|
+ 			  GET_LAYOUT|
+ 			  GET_DISKS|
+-			  GET_DEGRADED |
++			  GET_STATE |
+ 			  GET_COMPONENT|
+ 			  GET_CHUNK|
+ 			  GET_DEVS|
+diff --git a/sysfs.c b/sysfs.c
+index e47f5e4..78d2b52 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -162,18 +162,12 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 			goto abort;
+ 		sra->array.layout = strtoul(buf, NULL, 0);
+ 	}
+-	if (options & GET_DISKS) {
++	if (options & (GET_DISKS|GET_STATE)) {
+ 		strcpy(base, "raid_disks");
+ 		if (load_sys(fname, buf, sizeof(buf)))
+ 			goto abort;
+ 		sra->array.raid_disks = strtoul(buf, NULL, 0);
+ 	}
+-	if (options & GET_DEGRADED) {
+-		strcpy(base, "degraded");
+-		if (load_sys(fname, buf, sizeof(buf)))
+-			goto abort;
+-		sra->array.failed_disks = strtoul(buf, NULL, 0);
+-	}
+ 	if (options & GET_COMPONENT) {
+ 		strcpy(base, "component_size");
+ 		if (load_sys(fname, buf, sizeof(buf)))
+@@ -359,10 +353,9 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 			strcpy(dbase, "state");
+ 			if (load_sys(fname, buf, sizeof(buf)))
+ 				goto abort;
+-			if (strstr(buf, "faulty")) {
++			if (strstr(buf, "faulty"))
+ 				dev->disk.state |= (1<<MD_DISK_FAULTY);
+-				sra->array.failed_disks++;
+-			} else {
++			else {
+ 				sra->array.working_disks++;
+ 				if (strstr(buf, "in_sync")) {
+ 					dev->disk.state |= (1<<MD_DISK_SYNC);
+@@ -379,6 +372,11 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 			dev->errors = strtoul(buf, NULL, 0);
+ 		}
+ 	}
++
++	if ((options & GET_STATE) && sra->array.raid_disks)
++		sra->array.failed_disks = sra->array.raid_disks -
++			sra->array.active_disks - sra->array.spare_disks;
++
+ 	closedir(dir);
+ 	return sra;
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-Do-not-shadow-an-existing-variable.patch b/SOURCES/Grow-Do-not-shadow-an-existing-variable.patch
new file mode 100644
index 0000000..70c76f9
--- /dev/null
+++ b/SOURCES/Grow-Do-not-shadow-an-existing-variable.patch
@@ -0,0 +1,41 @@
+From 49948a3561dcd48a94b1c5e98a6d23c9263d1ca3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Thu, 30 Mar 2017 10:46:01 -0400
+Subject: [RHEL7.5 PATCH 043/169] Grow: Do not shadow an existing variable
+
+Declaring 'int rv' twice within the same function is asking for
+trouble.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Grow.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index 0d551ce..0c16d5b 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -1834,7 +1834,7 @@ int Grow_reshape(char *devname, int fd,
+ 	 * pre-requisite spare devices (mdmon owns final validation)
+ 	 */
+ 	if (st->ss->external) {
+-		int rv;
++		int retval;
+ 
+ 		if (subarray) {
+ 			container = st->container_devnm;
+@@ -1852,9 +1852,9 @@ int Grow_reshape(char *devname, int fd,
+ 			return 1;
+ 		}
+ 
+-		rv = st->ss->load_container(st, cfd, NULL);
++		retval = st->ss->load_container(st, cfd, NULL);
+ 
+-		if (rv) {
++		if (retval) {
+ 			pr_err("Cannot read superblock for %s\n",
+ 				devname);
+ 			free(subarray);
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch b/SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch
new file mode 100644
index 0000000..87008f6
--- /dev/null
+++ b/SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch
@@ -0,0 +1,176 @@
+From 6ebf34e6bdd9e952d00ad3c2f12a130bfb68965e Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 12:15:20 -0400
+Subject: [RHEL7.5 PATCH 036/169] Grow: Fixup a pile of cosmetic issues
+
+No code change, simply cleanup ugliness.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Grow.c | 60 ++++++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 32 insertions(+), 28 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index b86b53e..6405f0e 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -1269,8 +1269,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
+ 		 * raid5 with 2 disks, or
+ 		 * raid0 with 1 disk
+ 		 */
+-		if (info->new_level > 1 &&
+-		    (info->component_size & 7))
++		if (info->new_level > 1 && (info->component_size & 7))
+ 			return "Cannot convert RAID1 of this size - reduce size to multiple of 4K first.";
+ 		if (info->new_level == 0) {
+ 			if (info->delta_disks != UnSet &&
+@@ -1288,12 +1287,9 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
+ 			re->level = 1;
+ 			return NULL;
+ 		}
+-		if (info->array.raid_disks != 2 &&
+-		    info->new_level == 5)
++		if (info->array.raid_disks != 2 && info->new_level == 5)
+ 			return "Can only convert a 2-device array to RAID5";
+-		if (info->array.raid_disks == 2 &&
+-		    info->new_level == 5) {
+-
++		if (info->array.raid_disks == 2 && info->new_level == 5) {
+ 			re->level = 5;
+ 			re->before.data_disks = 1;
+ 			if (info->delta_disks != UnSet &&
+@@ -1404,7 +1400,8 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
+ 	case 0:
+ 		/* RAID0 can be converted to RAID10, or to RAID456 */
+ 		if (info->new_level == 10) {
+-			if (info->new_layout == UnSet && info->delta_disks == UnSet) {
++			if (info->new_layout == UnSet &&
++			    info->delta_disks == UnSet) {
+ 				/* Assume near=2 layout */
+ 				info->new_layout = 0x102;
+ 				info->delta_disks = info->array.raid_disks;
+@@ -1643,16 +1640,19 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
+ 	if (info->delta_disks == UnSet)
+ 		info->delta_disks = delta_parity;
+ 
+-	re->after.data_disks = (re->before.data_disks
+-				+ info->delta_disks
+-				- delta_parity);
++	re->after.data_disks =
++		(re->before.data_disks + info->delta_disks - delta_parity);
++
+ 	switch (re->level) {
+-	case 6: re->parity = 2;
++	case 6:
++		re->parity = 2;
+ 		break;
+ 	case 4:
+-	case 5: re->parity = 1;
++	case 5:
++		re->parity = 1;
+ 		break;
+-	default: re->parity = 0;
++	default:
++		re->parity = 0;
+ 		break;
+ 	}
+ 	/* So we have a restripe operation, we need to calculate the number
+@@ -1706,7 +1706,7 @@ static int set_array_size(struct supertype *st, struct mdinfo *sra,
+ 
+ 	if (text_version == NULL)
+ 		text_version = sra->text_version;
+-	subarray = strchr(text_version+1, '/')+1;
++	subarray = strchr(text_version + 1, '/')+1;
+ 	info = st->ss->container_content(st, subarray);
+ 	if (info) {
+ 		unsigned long long current_size = 0;
+@@ -1789,8 +1789,8 @@ int Grow_reshape(char *devname, int fd,
+ 			devname);
+ 		return 1;
+ 	}
+-	if (data_offset != INVALID_SECTORS && array.level != 10
+-	    && (array.level < 4 || array.level > 6)) {
++	if (data_offset != INVALID_SECTORS && array.level != 10 &&
++	    (array.level < 4 || array.level > 6)) {
+ 		pr_err("--grow --data-offset not yet supported\n");
+ 		return 1;
+ 	}
+@@ -1802,8 +1802,8 @@ int Grow_reshape(char *devname, int fd,
+ 		return 1;
+ 	}
+ 
+-	if (s->raiddisks && s->raiddisks < array.raid_disks && array.level > 1 &&
+-	    get_linux_version() < 2006032 &&
++	if (s->raiddisks && s->raiddisks < array.raid_disks &&
++	    array.level > 1 && get_linux_version() < 2006032 &&
+ 	    !check_env("MDADM_FORCE_FEWER")) {
+ 		pr_err("reducing the number of devices is not safe before Linux 2.6.32\n"
+ 			"       Please use a newer kernel\n");
+@@ -1873,10 +1873,11 @@ int Grow_reshape(char *devname, int fd,
+ 				/* check if reshape is allowed based on metadata
+ 				 * indications stored in content.array.status
+ 				 */
+-				if (content->array.state & (1<<MD_SB_BLOCK_VOLUME))
++				if (content->array.state &
++				    (1 << MD_SB_BLOCK_VOLUME))
+ 					allow_reshape = 0;
+-				if (content->array.state
+-				    & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))
++				if (content->array.state &
++				    (1 << MD_SB_BLOCK_CONTAINER_RESHAPE))
+ 					allow_reshape = 0;
+ 				if (!allow_reshape) {
+ 					pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
+@@ -1896,7 +1897,7 @@ int Grow_reshape(char *devname, int fd,
+ 	for (dv = devlist; dv; dv = dv->next)
+ 		added_disks++;
+ 	if (s->raiddisks > array.raid_disks &&
+-	    array.spare_disks +added_disks < (s->raiddisks - array.raid_disks) &&
++	    array.spare_disks + added_disks < (s->raiddisks - array.raid_disks) &&
+ 	    !c->force) {
+ 		pr_err("Need %d spare%s to avoid degraded array, and only have %d.\n"
+ 		       "       Use --force to over-ride this check.\n",
+@@ -1906,8 +1907,8 @@ int Grow_reshape(char *devname, int fd,
+ 		return 1;
+ 	}
+ 
+-	sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS
+-			 | GET_STATE | GET_VERSION);
++	sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS |
++			 GET_STATE | GET_VERSION);
+ 	if (sra) {
+ 		if (st->ss->external && subarray == NULL) {
+ 			array.level = LEVEL_CONTAINER;
+@@ -1930,7 +1931,8 @@ int Grow_reshape(char *devname, int fd,
+ 	}
+ 
+ 	/* ========= set size =============== */
+-	if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
++	if (s->size > 0 &&
++	    (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
+ 		unsigned long long orig_size = get_component_size(fd)/2;
+ 		unsigned long long min_csize;
+ 		struct mdinfo *mdi;
+@@ -1946,7 +1948,8 @@ int Grow_reshape(char *devname, int fd,
+ 		}
+ 
+ 		if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL,
+-				  devname, APPLY_METADATA_CHANGES, c->verbose > 0)) {
++				  devname, APPLY_METADATA_CHANGES,
++				  c->verbose > 0)) {
+ 			rv = 1;
+ 			goto release;
+ 		}
+@@ -1965,7 +1968,8 @@ int Grow_reshape(char *devname, int fd,
+ 						sizeinfo->array.layout,
+ 						sizeinfo->array.raid_disks);
+ 				new_size /= data_disks;
+-				dprintf("Metadata size correction from %llu to %llu (%llu)\n", orig_size, new_size,
++				dprintf("Metadata size correction from %llu to %llu (%llu)\n",
++					orig_size, new_size,
+ 					new_size * data_disks);
+ 				s->size = new_size;
+ 				sysfs_free(sizeinfo);
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch b/SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch
new file mode 100644
index 0000000..44c25bb
--- /dev/null
+++ b/SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch
@@ -0,0 +1,41 @@
+From 9e4524df1c6c85c362278a08fd4425888d27581f Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 2 May 2017 11:46:49 -0400
+Subject: [RHEL7.5 PATCH 104/169] Grow: Grow_continue_command: Avoid
+ aliasing array variable
+
+While this would cause a warning since the two are different types,
+lets avoid aliasing an existing variable.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index c6967ed..f4bd301 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -5075,7 +5075,7 @@ int Grow_continue_command(char *devname, int fd,
+ 
+ 		cc = st->ss->container_content(st, subarray);
+ 		for (content = cc; content ; content = content->next) {
+-			char *array;
++			char *array_name;
+ 			int allow_reshape = 1;
+ 
+ 			if (content->reshape_active == 0)
+@@ -5100,8 +5100,8 @@ int Grow_continue_command(char *devname, int fd,
+ 				goto Grow_continue_command_exit;
+ 			}
+ 
+-			array = strchr(content->text_version+1, '/')+1;
+-			mdstat = mdstat_by_subdev(array, container);
++			array_name = strchr(content->text_version+1, '/')+1;
++			mdstat = mdstat_by_subdev(array_name, container);
+ 			if (!mdstat)
+ 				continue;
+ 			if (mdstat->active == 0) {
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-Remove-unnecessary-optimization.patch b/SOURCES/Grow-Remove-unnecessary-optimization.patch
new file mode 100644
index 0000000..ad0b3cc
--- /dev/null
+++ b/SOURCES/Grow-Remove-unnecessary-optimization.patch
@@ -0,0 +1,51 @@
+From 758b327cf5a7aab50ae5c70ecbc371dc4f715bb6 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jes@wobbly.dhcp.thefacebook.com>
+Date: Thu, 30 Mar 2017 10:39:29 -0400
+Subject: [RHEL7.5 PATCH 042/169] Grow: Remove unnecessary optimization
+
+Per explanation by Neil, this optimization of writing "size" to the
+attribute of each device, however when reducing the size of devices,
+the size change isn't permitted until the array has been shrunk, so
+this will fail anyway.
+
+This effectively reverts 65a9798b58b4e4de0157043e2b30a738c27eff43
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Grow.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index af8d520..0d551ce 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -1982,15 +1982,7 @@ int Grow_reshape(char *devname, int fd,
+ 		 * understands '0' to mean 'max'.
+ 		 */
+ 		min_csize = 0;
+-		rv = 0;
+ 		for (mdi = sra->devs; mdi; mdi = mdi->next) {
+-			if (sysfs_set_num(sra, mdi, "size",
+-					  s->size == MAX_SIZE ? 0 : s->size) < 0) {
+-				/* Probably kernel refusing to let us
+-				 * reduce the size - not an error.
+-				 */
+-				break;
+-			}
+ 			if (array.not_persistent == 0 &&
+ 			    array.major_version == 0 &&
+ 			    get_linux_version() < 3001000) {
+@@ -2005,10 +1997,6 @@ int Grow_reshape(char *devname, int fd,
+ 				}
+ 			}
+ 		}
+-		if (rv) {
+-			pr_err("Cannot set size on array members.\n");
+-			goto size_change_error;
+-		}
+ 		if (min_csize && s->size > min_csize) {
+ 			pr_err("Cannot safely make this array use more than 2TB per device on this kernel.\n");
+ 			rv = 1;
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch b/SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch
new file mode 100644
index 0000000..dc90a94
--- /dev/null
+++ b/SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch
@@ -0,0 +1,35 @@
+From 6ae8b2b3140475b1a70485052454210aba4065a6 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:22:36 -0400
+Subject: [RHEL7.5 PATCH 056/169] Grow: Stop bothering about md driver
+ versions older than 0.90.00
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Grow.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index 78a3474..15f4ed1 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -288,16 +288,9 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 	struct supertype *st;
+ 	char *subarray = NULL;
+ 	int major = BITMAP_MAJOR_HI;
+-	int vers = md_get_version(fd);
+ 	unsigned long long bitmapsize, array_size;
+ 	struct mdinfo *mdi;
+ 
+-	if (vers < 9003) {
+-		major = BITMAP_MAJOR_HOSTENDIAN;
+-		pr_err("Warning - bitmaps created on this kernel are not portable\n"
+-			"  between different architectures.  Consider upgrading the Linux kernel.\n");
+-	}
+-
+ 	/*
+ 	 * We only ever get called if s->bitmap_file is != NULL, so this check
+ 	 * is just here to quiet down static code checkers.
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch b/SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch
new file mode 100644
index 0000000..4249916
--- /dev/null
+++ b/SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch
@@ -0,0 +1,34 @@
+From 41b25549f080ebac1269689f942f722368ed28b1 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:13 +0200
+Subject: [PATCH 07/12] Grow: fix switching on PPL during recovery
+
+If raid memeber is not in sync - it is skipped during
+enablement of PPL. This is not correct, since the drive that
+we are currently recovering to does not have ppl_size and ppl_sector
+properly set in sysfs.
+Remove this skipping, so all drives are updated during turning on the PPL.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index bab1eec..1149753 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -637,9 +637,6 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
+ 			int dfd;
+ 			char *devpath;
+ 
+-			if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0)
+-				continue;
+-
+ 			devpath = map_dev(sd->disk.major, sd->disk.minor, 0);
+ 			dfd = dev_open(devpath, O_RDWR);
+ 			if (dfd < 0) {
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow-set-component-size-prior-to-array-size.patch b/SOURCES/Grow-set-component-size-prior-to-array-size.patch
new file mode 100644
index 0000000..ce27272
--- /dev/null
+++ b/SOURCES/Grow-set-component-size-prior-to-array-size.patch
@@ -0,0 +1,34 @@
+From 07c45a1871df0a70beb8da80d11601d33c7a5de2 Mon Sep 17 00:00:00 2001
+From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date: Mon, 5 Jun 2017 16:09:44 +0200
+Subject: [RHEL7.5 PATCH 150/169] Grow: set component size prior to array
+ size
+
+It is a partial revert of commit 758b327cf5a7 ("Grow: Remove unnecessary
+optimization"). For native metadata component size is set in kernel for
+entire disk space. As external metadata supports multiple arrays within
+one disk, the component size is set to array size. If component size is
+not updated prior to array size update, the grow operation fails.
+
+Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Grow.c b/Grow.c
+index ecf5ca0..4ecb1d8 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -1977,6 +1977,8 @@ int Grow_reshape(char *devname, int fd,
+ 		 */
+ 		min_csize = 0;
+ 		for (mdi = sra->devs; mdi; mdi = mdi->next) {
++			sysfs_set_num(sra, mdi, "size", s->size == MAX_SIZE ? 0
++				      : s->size);
+ 			if (array.not_persistent == 0 &&
+ 			    array.major_version == 0 &&
+ 			    get_linux_version() < 3001000) {
+-- 
+2.7.4
+
diff --git a/SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch b/SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch
new file mode 100644
index 0000000..f103451
--- /dev/null
+++ b/SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch
@@ -0,0 +1,36 @@
+From a250ce240f245df594570a5e25398680d403af67 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 20 Apr 2017 12:40:05 +1000
+Subject: [RHEL7.5 PATCH 087/169] Grow_continue_command: ensure 'content'
+ is properly initialised.
+
+Grow_continue_command() call verify_reshape_position(), which assumes
+that info->sys_name is initialised.
+'info' in verify_reshape_position() is 'content' in Grow_continue_command().
+
+In the st->ss->external != 0 branch of that function, sysfs_init() is called
+to initialize content->sys_name.
+In the st->ss->external == 0 branch, ->sys_name is not initialized so
+verify_reshape_position() will not do the right thing.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Grow.c b/Grow.c
+index 15f4ed1..c6967ed 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -5002,6 +5002,7 @@ int Grow_continue_command(char *devname, int fd,
+ 			goto Grow_continue_command_exit;
+ 		}
+ 		content = &array;
++		sysfs_init(content, fd, NULL);
+ 		/* Need to load a superblock.
+ 		 * FIXME we should really get what we need from
+ 		 * sysfs
+-- 
+2.7.4
+
diff --git a/SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch b/SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch
new file mode 100644
index 0000000..f2ba47d
--- /dev/null
+++ b/SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch
@@ -0,0 +1,47 @@
+From 2a24dc1b0988a7d924de6339754d4160762a61f7 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Wed, 26 Apr 2017 11:08:07 +0200
+Subject: [RHEL7.5 PATCH 103/169] IMSM: Initialize my_vol_raid_dev_num
+ during vol creation
+
+This field was not initialized so far. This ID needs to be unique
+for every newly created array in container.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index fbff215..36f77d3 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -232,8 +232,13 @@ struct imsm_super {
+ 	__u32 orig_family_num;		/* 0x40 - 0x43 original family num */
+ 	__u32 pwr_cycle_count;		/* 0x44 - 0x47 simulated power cycle count for array */
+ 	__u32 bbm_log_size;		/* 0x48 - 0x4B - size of bad Block Mgmt Log in bytes */
+-#define IMSM_FILLERS 35
+-	__u32 filler[IMSM_FILLERS];	/* 0x4C - 0xD7 RAID_MPB_FILLERS */
++	__u16 num_raid_devs_created;	/* 0x4C - 0x4D Used for generating unique
++					 * volume IDs for raid_dev created in this array
++					 * (starts at 1)
++					 */
++	__u16 filler1;			/* 0x4E - 0x4F */
++#define IMSM_FILLERS 34
++	__u32 filler[IMSM_FILLERS];	/* 0x50 - 0xD7 RAID_MPB_FILLERS */
+ 	struct imsm_disk disk[1];	/* 0xD8 diskTbl[numDisks] */
+ 	/* here comes imsm_dev[num_raid_devs] */
+ 	/* here comes BBM logs */
+@@ -5368,6 +5373,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ 		set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD);
+ 	}
+ 	mpb->num_raid_devs++;
++	mpb->num_raid_devs_created++;
++	dev->my_vol_raid_dev_num = mpb->num_raid_devs_created;
+ 
+ 	if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) {
+ 		dev->rwh_policy = RWH_OFF;
+-- 
+2.7.4
+
diff --git a/SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch b/SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch
new file mode 100644
index 0000000..931e32e
--- /dev/null
+++ b/SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch
@@ -0,0 +1,152 @@
+From f8c432bfc9929dbbcb659b2d11552dc9fc76ad24 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 25 Apr 2017 15:01:43 -0400
+Subject: [RHEL7.5 PATCH 099/169] Incremental: Cleanup some if() statement
+ spaghetti
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 50 +++++++++++++++++++++-----------------------------
+ 1 file changed, 21 insertions(+), 29 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index a351151..66c5b03 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -225,8 +225,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	if (!match && rv == 2)
+ 		goto out;
+ 
+-	if (match && match->devname
+-	    && strcasecmp(match->devname, "<ignore>") == 0) {
++	if (match && match->devname &&
++	    strcasecmp(match->devname, "<ignore>") == 0) {
+ 		if (c->verbose >= 0)
+ 			pr_err("array containing %s is explicitly ignored by mdadm.conf\n",
+ 				devname);
+@@ -267,8 +267,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		c->autof = ci->autof;
+ 
+ 	name_to_use = info.name;
+-	if (name_to_use[0] == 0 &&
+-	    info.array.level == LEVEL_CONTAINER) {
++	if (name_to_use[0] == 0 && info.array.level == LEVEL_CONTAINER) {
+ 		name_to_use = info.text_version;
+ 		trustworthy = METADATA;
+ 	}
+@@ -398,11 +397,10 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		 * flag has a different meaning.  The test has to happen
+ 		 * at the device level there
+ 		 */
+-		if (!st->ss->external
+-		    && (info.disk.state & (1<<MD_DISK_SYNC)) != 0
+-		    && ! policy_action_allows(policy, st->ss->name,
+-					      act_re_add)
+-		    && c->runstop < 1) {
++		if (!st->ss->external &&
++		    (info.disk.state & (1 << MD_DISK_SYNC)) != 0 &&
++		    !policy_action_allows(policy, st->ss->name, act_re_add) &&
++		    c->runstop < 1) {
+ 			if (md_array_active(mdfd)) {
+ 				pr_err("not adding %s to active array (without --run) %s\n",
+ 				       devname, chosen_name);
+@@ -537,8 +535,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		info.array.state |= 1;
+ 
+ 	if (enough(info.array.level, info.array.raid_disks,
+-		   info.array.layout, info.array.state & 1,
+-		   avail) == 0) {
++		   info.array.layout, info.array.state & 1, avail) == 0) {
+ 		if (c->export) {
+ 			printf("MD_STARTED=no\n");
+ 		} else if (c->verbose >= 0)
+@@ -599,8 +596,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 			if (d->disk.state & (1<<MD_DISK_REMOVED))
+ 				remove_disk(mdfd, st, sra, d);
+ 
+-		if ((sra == NULL || active_disks >= info.array.working_disks)
+-		    && trustworthy != FOREIGN)
++		if ((sra == NULL || active_disks >= info.array.working_disks) &&
++		    trustworthy != FOREIGN)
+ 			rv = ioctl(mdfd, RUN_ARRAY, NULL);
+ 		else
+ 			rv = sysfs_set_str(sra, NULL,
+@@ -624,7 +621,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 			 * those devices we should re-add them now.
+ 			 */
+ 			for (dsk = sra->devs; dsk ; dsk = dsk->next) {
+-				if (disk_action_allows(dsk, st->ss->name, act_re_add) &&
++				if (disk_action_allows(dsk, st->ss->name,
++						       act_re_add) &&
+ 				    add_disk(mdfd, st, sra, dsk) == 0)
+ 					pr_err("%s re-added to %s\n",
+ 					       dsk->sys_name, chosen_name);
+@@ -688,8 +686,7 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
+ 		st->ss->free_super(st);
+ 		close(dfd);
+ 
+-		if (info.disk.number != number ||
+-		    info.events >= events)
++		if (info.disk.number != number || info.events >= events)
+ 			continue;
+ 
+ 		if (d->disk.raid_disk > -1)
+@@ -970,11 +967,9 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 		}
+ 		if ((sra->component_size > 0 &&
+ 		     st2->ss->avail_size(st2, devsize,
+-					 sra->devs
+-					 ? sra->devs->data_offset
+-					 : INVALID_SECTORS)
+-		     < sra->component_size)
+-		    ||
++					 sra->devs ? sra->devs->data_offset :
++					 INVALID_SECTORS) <
++		     sra->component_size) ||
+ 		    (sra->component_size == 0 && devsize < component_size)) {
+ 			if (verbose > 1)
+ 				pr_err("not adding %s to %s as it is too small\n",
+@@ -1107,8 +1102,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 		char *devname = NULL;
+ 		unsigned long long devsectors;
+ 
+-		if (de->d_ino == 0 ||
+-		    de->d_name[0] == '.' ||
++		if (de->d_ino == 0 || de->d_name[0] == '.' ||
+ 		    (de->d_type != DT_LNK && de->d_type != DT_UNKNOWN))
+ 			goto next;
+ 
+@@ -1146,8 +1140,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 			st2 = dup_super(st);
+ 		else
+ 			st2 = guess_super_type(fd, guess_partitions);
+-		if (st2 == NULL ||
+-		    st2->ss->load_super(st2, fd, NULL) < 0)
++		if (st2 == NULL || st2->ss->load_super(st2, fd, NULL) < 0)
+ 			goto next;
+ 		st2->ignore_hw_compat = 0;
+ 
+@@ -1175,8 +1168,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 		 * metadata which makes better use of the device can
+ 		 * be found.
+ 		 */
+-		if (chosen == NULL ||
+-		    chosen_size < info.component_size) {
++		if (chosen == NULL || chosen_size < info.component_size) {
+ 			chosen_size = info.component_size;
+ 			free(chosen);
+ 			chosen = devname;
+@@ -1399,8 +1391,8 @@ restart:
+ 		}
+ 		/* Ok, we can try this one.   Maybe it needs a bitmap */
+ 		for (mddev = devs ; mddev ; mddev = mddev->next)
+-			if (mddev->devname && me->path
+-			    && devname_matches(mddev->devname, me->path))
++			if (mddev->devname && me->path &&
++			    devname_matches(mddev->devname, me->path))
+ 				break;
+ 		if (mddev && mddev->bitmap_file) {
+ 			/*
+-- 
+2.7.4
+
diff --git a/SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch b/SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch
new file mode 100644
index 0000000..8de191e
--- /dev/null
+++ b/SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch
@@ -0,0 +1,54 @@
+From 5b13d2e1fb8abecddd4e28e67facac5d7ef2cef3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 14:40:36 -0400
+Subject: [RHEL7.5 PATCH 038/169] Incremental: Remove redundant call for
+ GET_ARRAY_INFO
+
+The code above just called md_get_array_info() and only reached this
+point if it returned an error that isn't ENODEV, so it's pointless to
+check this again here.
+
+In addition it was incorrectly retrieving ioctl data into a
+mdu_bitmap_file_t instead of mdu_array_info_t.
+
+Fixes: ("8382f19 Add new mode: --incremental")
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Incremental.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index 1f12c77..802e525 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -1345,7 +1345,6 @@ int IncrementalScan(struct context *c, char *devnm)
+ restart:
+ 	for (me = mapl ; me ; me = me->next) {
+ 		mdu_array_info_t array;
+-		mdu_bitmap_file_t bmf;
+ 		struct mdinfo *sra;
+ 		int mdfd;
+ 
+@@ -1405,13 +1404,12 @@ restart:
+ 			 * is a hint only
+ 			 */
+ 			int added = -1;
+-			if (ioctl(mdfd, GET_ARRAY_INFO, &bmf) < 0) {
+-				int bmfd = open(mddev->bitmap_file, O_RDWR);
+-				if (bmfd >= 0) {
+-					added = ioctl(mdfd, SET_BITMAP_FILE,
+-						      bmfd);
+-					close(bmfd);
+-				}
++			int bmfd;
++
++			bmfd = open(mddev->bitmap_file, O_RDWR);
++			if (bmfd >= 0) {
++				added = ioctl(mdfd, SET_BITMAP_FILE, bmfd);
++				close(bmfd);
+ 			}
+ 			if (c->verbose >= 0) {
+ 				if (added == 0)
+-- 
+2.7.4
+
diff --git a/SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch b/SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch
new file mode 100644
index 0000000..e23e883
--- /dev/null
+++ b/SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch
@@ -0,0 +1,37 @@
+From 6921010d95dbc32c812aa8ffdbfa28e78b54b342 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 2 May 2017 10:36:51 -0400
+Subject: [RHEL7.5 PATCH 101/169] Incremental: Use md_array_active() to
+ determine state of array
+
+One less call to md_get_array_info()
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index 4789e36..8909f2f 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -99,7 +99,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	int active_disks;
+ 	int trustworthy;
+ 	char *name_to_use;
+-	mdu_array_info_t ainf;
+ 	struct dev_policy *policy = NULL;
+ 	struct map_ent target_array;
+ 	int have_target;
+@@ -551,7 +550,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	/*   + add any bitmap file  */
+ 	/*   + start the array (auto-readonly). */
+ 
+-	if (md_get_array_info(mdfd, &ainf) == 0) {
++	if (md_array_active(mdfd)) {
+ 		if (c->export) {
+ 			printf("MD_STARTED=already\n");
+ 		} else if (c->verbose >= 0)
+-- 
+2.7.4
+
diff --git a/SOURCES/Incremental-Use-md_array_active-where-applicable.patch b/SOURCES/Incremental-Use-md_array_active-where-applicable.patch
new file mode 100644
index 0000000..96e43ae
--- /dev/null
+++ b/SOURCES/Incremental-Use-md_array_active-where-applicable.patch
@@ -0,0 +1,41 @@
+From ff4ad24b1c261ab4d286cbe54157d7c588191692 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 25 Apr 2017 14:57:46 -0400
+Subject: [RHEL7.5 PATCH 098/169] Incremental: Use md_array_active() where
+ applicable
+
+md_get_array_info() == 0 implies an array is active, however this is more
+correct.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index 28f1f77..a351151 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -403,7 +403,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		    && ! policy_action_allows(policy, st->ss->name,
+ 					      act_re_add)
+ 		    && c->runstop < 1) {
+-			if (md_get_array_info(mdfd, &ainf) == 0) {
++			if (md_array_active(mdfd)) {
+ 				pr_err("not adding %s to active array (without --run) %s\n",
+ 				       devname, chosen_name);
+ 				rv = 2;
+@@ -667,9 +667,8 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
+ 	 * and events less than the passed events, and remove the device.
+ 	 */
+ 	struct mdinfo *d;
+-	mdu_array_info_t ra;
+ 
+-	if (md_get_array_info(mdfd, &ra) == 0)
++	if (md_array_active(mdfd))
+ 		return; /* not safe to remove from active arrays
+ 			 * without thinking more */
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/Incremental-returnis-not-a-function.patch b/SOURCES/Incremental-returnis-not-a-function.patch
new file mode 100644
index 0000000..310431e
--- /dev/null
+++ b/SOURCES/Incremental-returnis-not-a-function.patch
@@ -0,0 +1,26 @@
+From c2d1a6ec6b94385e64e721b733bd44d1d704b530 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 5 May 2017 11:39:58 -0400
+Subject: [RHEL7.5 PATCH 112/169] Incremental: return is not a function
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index 97b2e99..c00a43d 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -823,7 +823,7 @@ static int container_members_max_degradation(struct map_ent *map, struct map_ent
+ 		}
+ 		close(afd);
+ 	}
+-	return (max_degraded);
++	return max_degraded;
+ }
+ 
+ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+-- 
+2.7.4
+
diff --git a/SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch b/SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch
new file mode 100644
index 0000000..652baeb
--- /dev/null
+++ b/SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch
@@ -0,0 +1,38 @@
+From 00e56fd9537e1f69583d8b0f60faf02026f24d1b Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 5 May 2017 12:18:29 -0400
+Subject: [RHEL7.5 PATCH 115/169] IncrementalScan: Use md_array_active()
+ instead of md_get_array_info()
+
+This eliminates yet another case where GET_ARRAY_INFO was used to
+indicate whether the array was active.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index b73eabd..680d318 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -1317,7 +1317,6 @@ int IncrementalScan(struct context *c, char *devnm)
+ 
+ restart:
+ 	for (me = mapl ; me ; me = me->next) {
+-		mdu_array_info_t array;
+ 		struct mdinfo *sra;
+ 		int mdfd;
+ 
+@@ -1362,7 +1361,7 @@ restart:
+ 				rv = 1;
+ 			continue;
+ 		}
+-		if (md_get_array_info(mdfd, &array) == 0 || errno != ENODEV) {
++		if (md_array_active(mdfd)) {
+ 			close(mdfd);
+ 			continue;
+ 		}
+-- 
+2.7.4
+
diff --git a/SOURCES/Introduce1-sys_hot_remove_disk.patch b/SOURCES/Introduce1-sys_hot_remove_disk.patch
new file mode 100644
index 0000000..8c10682
--- /dev/null
+++ b/SOURCES/Introduce1-sys_hot_remove_disk.patch
@@ -0,0 +1,74 @@
+From fdd015696c2e2a6b234a92af564aea44b62e6a0d Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Mon, 27 Mar 2017 14:36:56 +1100
+Subject: [RHEL7.5 PATCH 022/169] Introduce sys_hot_remove_disk()
+
+The new hot_remove_disk() will retry HOT_REMOVE_DISK
+several times in the face of EBUSY.
+However we sometimes remove a device by writing "remove" to the
+"state" attributed.  This should be retried as well.
+So introduce sys_hot_remove_disk() to repeat this action a few times.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Manage.c |  6 +-----
+ mdadm.h  |  1 +
+ util.c   | 12 ++++++++++++
+ 3 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index 9139f96..edf5798 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1177,11 +1177,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
+ 		/* device has been removed and we don't know
+ 		 * the major:minor number
+ 		 */
+-		int n = write(sysfd, "remove", 6);
+-		if (n != 6)
+-			err = -1;
+-		else
+-			err = 0;
++		err = sys_hot_remove_disk(sysfd);
+ 	} else {
+ 		err = hot_remove_disk(fd, rdev);
+ 		if (err && errno == ENODEV) {
+diff --git a/mdadm.h b/mdadm.h
+index 5bcfb86..b855d24 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1477,6 +1477,7 @@ extern int add_disk(int mdfd, struct supertype *st,
+ extern int remove_disk(int mdfd, struct supertype *st,
+ 		       struct mdinfo *sra, struct mdinfo *info);
+ extern int hot_remove_disk(int mdfd, unsigned long dev);
++extern int sys_hot_remove_disk(int statefd);
+ extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
+ unsigned long long min_recovery_start(struct mdinfo *array);
+ 
+diff --git a/util.c b/util.c
+index d09a7e2..b718531 100644
+--- a/util.c
++++ b/util.c
+@@ -1813,6 +1813,18 @@ int hot_remove_disk(int mdfd, unsigned long dev)
+ 	return ret;
+ }
+ 
++int sys_hot_remove_disk(int statefd)
++{
++	int cnt = 5;
++	int ret;
++
++	while ((ret = write(statefd, "remove", 6)) == -1 &&
++	       errno == EBUSY &&
++	       cnt-- > 0)
++		usleep(10000);
++	return ret == 6 ? 0 : -1;
++}
++
+ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
+ {
+ 	/* Initialise kernel's knowledge of array.
+-- 
+2.7.4
+
diff --git a/SOURCES/Makefile-Default-to-O2-optimization1.patch b/SOURCES/Makefile-Default-to-O2-optimization1.patch
new file mode 100644
index 0000000..a476f9b
--- /dev/null
+++ b/SOURCES/Makefile-Default-to-O2-optimization1.patch
@@ -0,0 +1,25 @@
+From 17d80e6eb64230593ee8d599b94005d303eb58ae Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 21 Apr 2017 12:06:35 -0400
+Subject: [RHEL7.5 PATCH 091/169] Makefile: Default to -O2 optimization
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Makefile b/Makefile
+index 5655812..6850696 100644
+--- a/Makefile
++++ b/Makefile
+@@ -30,6 +30,7 @@
+ 
+ # define "CXFLAGS" to give extra flags to CC.
+ # e.g.  make CXFLAGS=-O to optimise
++CXFLAGS ?=-O2
+ TCC = tcc
+ UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found )
+ #DIET_GCC = diet gcc
+-- 
+2.7.4
+
diff --git a/SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch b/SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch
new file mode 100644
index 0000000..5834242
--- /dev/null
+++ b/SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch
@@ -0,0 +1,31 @@
+From 53835cf50023aaad6887b647a3aaab524bd9b39e Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Tue, 10 Jan 2017 18:51:40 -0500
+Subject: [RHEL7.5 PATCH 001/169] Makefile: Fix date to be output in ISO
+ format
+
+Updated the static version in the release, but forgot to fix the
+Makefile generated version when extracting from git
+
+Reported-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 5fd7f16..a6f464c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -89,7 +89,7 @@ DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
+ CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS) $(COROSYNC) $(DLM)
+ 
+ VERSION = $(shell [ -d .git ] && git describe HEAD | sed 's/mdadm-//')
+-VERS_DATE = $(shell [ -d .git ] && date --date="`git log -n1 --format=format:%cd --date=short`" '+%0dth %B %Y' | sed -e 's/1th/1st/' -e 's/2th/2nd/' -e 's/11st/11th/' -e 's/12nd/12th/')
++VERS_DATE = $(shell [ -d .git ] && date --iso-8601 --date="`git log -n1 --format=format:%cd --date=iso --date=short`")
+ DVERS = $(if $(VERSION),-DVERSION=\"$(VERSION)\",)
+ DDATE = $(if $(VERS_DATE),-DVERS_DATE="\"$(VERS_DATE)\"",)
+ CFLAGS += $(DVERS) $(DDATE)
+-- 
+2.7.4
+
diff --git a/SOURCES/Manage-Manage-ro-Use-md_array_active.patch b/SOURCES/Manage-Manage-ro-Use-md_array_active.patch
new file mode 100644
index 0000000..77156dc
--- /dev/null
+++ b/SOURCES/Manage-Manage-ro-Use-md_array_active.patch
@@ -0,0 +1,41 @@
+From 80223cb4db3358a24c41a76414a3804c26d5ea3a Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 2 May 2017 10:40:07 -0400
+Subject: [RHEL7.5 PATCH 102/169] Manage: Manage_ro(): Use
+ md_array_active()
+
+One call less to md_get_array_info() for determining whether an array
+is active or not.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index 8966e33..230309b 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -40,7 +40,6 @@ int Manage_ro(char *devname, int fd, int readonly)
+ 	 * use RESTART_ARRAY_RW or STOP_ARRAY_RO
+ 	 *
+ 	 */
+-	mdu_array_info_t array;
+ 	struct mdinfo *mdi;
+ 	int rv = 0;
+ 
+@@ -88,9 +87,8 @@ int Manage_ro(char *devname, int fd, int readonly)
+ 		goto out;
+ 	}
+ 
+-	if (md_get_array_info(fd, &array)) {
+-		pr_err("%s does not appear to be active.\n",
+-			devname);
++	if (!md_array_active(fd)) {
++		pr_err("%s does not appear to be active.\n", devname);
+ 		rv = 1;
+ 		goto out;
+ 	}
+-- 
+2.7.4
+
diff --git a/SOURCES/Manage-Remove-all-references1-to-md_get_version.patch b/SOURCES/Manage-Remove-all-references1-to-md_get_version.patch
new file mode 100644
index 0000000..7d1e964
--- /dev/null
+++ b/SOURCES/Manage-Remove-all-references1-to-md_get_version.patch
@@ -0,0 +1,69 @@
+From 091e8e6e061a5739be68d214bbd4a25e38bec65c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:34:44 -0400
+Subject: [RHEL7.5 PATCH 059/169] Manage: Remove all references to
+ md_get_version()
+
+At this point, support for md driver prior to 0.90.03 is going to
+disappear.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Manage.c | 20 +-------------------
+ 1 file changed, 1 insertion(+), 19 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index 618c98b..9e69132 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -46,10 +46,6 @@ int Manage_ro(char *devname, int fd, int readonly)
+ #endif
+ 	int rv = 0;
+ 
+-	if (md_get_version(fd) < 9000) {
+-		pr_err("need md driver version 0.90.0 or later\n");
+-		return 1;
+-	}
+ #ifndef MDASSEMBLE
+ 	/* If this is an externally-managed array, we need to modify the
+ 	 * metadata_version so that mdmon doesn't undo our change.
+@@ -176,10 +172,6 @@ int Manage_run(char *devname, int fd, struct context *c)
+ 	 */
+ 	char nm[32], *nmp;
+ 
+-	if (md_get_version(fd) < 9000) {
+-		pr_err("need md driver version 0.90.0 or later\n");
+-		return 1;
+-	}
+ 	nmp = fd2devnm(fd);
+ 	if (!nmp) {
+ 		pr_err("Cannot find %s in sysfs!!\n", devname);
+@@ -207,14 +199,6 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
+ 	if (will_retry && verbose == 0)
+ 		verbose = -1;
+ 
+-	if (md_get_version(fd) < 9000) {
+-		if (ioctl(fd, STOP_MD, 0) == 0)
+-			return 0;
+-		pr_err("stopping device %s failed: %s\n",
+-		       devname, strerror(errno));
+-		return 1;
+-	}
+-
+ 	strcpy(devnm, fd2devnm(fd));
+ 	/* Get EXCL access first.  If this fails, then attempting
+ 	 * to stop is probably a bad idea.
+@@ -773,9 +757,7 @@ 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 &&
+-	    md_get_version(fd)%100 < 2) {
++	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",
+-- 
+2.7.4
+
diff --git a/SOURCES/Manage-subdevs-Use-a-dev_t.patch b/SOURCES/Manage-subdevs-Use-a-dev_t.patch
new file mode 100644
index 0000000..3e2607c
--- /dev/null
+++ b/SOURCES/Manage-subdevs-Use-a-dev_t.patch
@@ -0,0 +1,28 @@
+From ffaf1a7eefc6167d7457d649e628c04ccee9a4dd Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 29 Sep 2017 18:08:01 -0400
+Subject: [RHEL7.5 PATCH 12/13] Manage_subdevs(): Use a dev_t
+
+Use the correct type for rdev
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Manage.c b/Manage.c
+index 871d342..21536f5 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1367,7 +1367,7 @@ int Manage_subdevs(char *devname, int fd,
+ 	}
+ 
+ 	for (dv = devlist; dv; dv = dv->next) {
+-		unsigned long rdev = 0; /* device to add/remove etc */
++		dev_t rdev = 0; /* device to add/remove etc */
+ 		int rv;
+ 		int mj,mn;
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch b/SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch
new file mode 100644
index 0000000..0d7a8b9
--- /dev/null
+++ b/SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch
@@ -0,0 +1,32 @@
+From 4224685fe9baf1df4c42bcb950c9a593efa0585f Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Mon, 8 May 2017 09:40:09 +1000
+Subject: [RHEL7.5 PATCH 116/169] Mention "endian" in documentation for
+ --update=byte-order
+
+This makes it easier to find as "endian" is a commonly used term.
+
+Reported-by: Trevor Cordes <trevor@tecnopolis.ca>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index fb99a5c..388e0ed 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -1264,7 +1264,8 @@ is correct.
+ The
+ .B byteorder
+ option allows arrays to be moved between machines with different
+-byte-order.
++byte-order, such as from a big-endian machine like a Sparc or some
++MIPS machines, to a little-endian x86_64 machine.
+ When assembling such an array for the first time after a move, giving
+ .B "\-\-update=byteorder"
+ will cause
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-Code-is-80-characters-per-line.patch b/SOURCES/Monitor-Code-is-80-characters-per-line.patch
new file mode 100644
index 0000000..9c5ee14
--- /dev/null
+++ b/SOURCES/Monitor-Code-is-80-characters-per-line.patch
@@ -0,0 +1,151 @@
+From f27904a53b586e5507b442d7f321177e3dfb5a1a Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Mon, 8 May 2017 17:52:10 -0400
+Subject: [RHEL7.5 PATCH 118/169] Monitor: Code is 80 characters per line
+
+Fix up some lines that are too long for no reason, and some that have
+silly line breaks.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 61 +++++++++++++++++++++++++++----------------------------------
+ 1 file changed, 27 insertions(+), 34 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index b5231d2..ec643d4 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -527,13 +527,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		alert("NewArray", st->devname, NULL, ainfo);
+ 	}
+ 
+-	if (st->utime == array.utime &&
+-	    st->failed == array.failed_disks &&
++	if (st->utime == array.utime && st->failed == array.failed_disks &&
+ 	    st->working == array.working_disks &&
+ 	    st->spare == array.spare_disks &&
+-	    (mse == NULL  || (
+-		    mse->percent == st->percent
+-		    ))) {
++	    (mse == NULL  || (mse->percent == st->percent))) {
+ 		close(fd);
+ 		if ((st->active < st->raid) && st->spare == 0)
+ 			return 1;
+@@ -541,32 +538,33 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			return 0;
+ 	}
+ 	if (st->utime == 0 && /* new array */
+-	    mse->pattern && strchr(mse->pattern, '_') /* degraded */
+-		)
++	    mse->pattern && strchr(mse->pattern, '_') /* degraded */)
+ 		alert("DegradedArray", dev, NULL, ainfo);
+ 
+ 	if (st->utime == 0 && /* new array */
+-	    st->expected_spares > 0 &&
+-	    array.spare_disks < st->expected_spares)
++	    st->expected_spares > 0 && array.spare_disks < st->expected_spares)
+ 		alert("SparesMissing", dev, NULL, ainfo);
+ 	if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
+ 	    mse->percent >= 0)
+ 		alert("RebuildStarted", dev, NULL, ainfo);
+-	if (st->percent >= 0 &&
+-	    mse->percent >= 0 &&
++	if (st->percent >= 0 && mse->percent >= 0 &&
+ 	    (mse->percent / increments) > (st->percent / increments)) {
+-		char percentalert[15]; // "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
++		char percentalert[15];
++		/*
++		 * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
++		 */
+ 
+ 		if((mse->percent / increments) == 0)
+-			snprintf(percentalert, sizeof(percentalert), "RebuildStarted");
++			snprintf(percentalert, sizeof(percentalert),
++				 "RebuildStarted");
+ 		else
+-			snprintf(percentalert, sizeof(percentalert), "Rebuild%02d", mse->percent);
++			snprintf(percentalert, sizeof(percentalert),
++				 "Rebuild%02d", mse->percent);
+ 
+ 		alert(percentalert, dev, NULL, ainfo);
+ 	}
+ 
+-	if (mse->percent == RESYNC_NONE &&
+-	    st->percent >= 0) {
++	if (mse->percent == RESYNC_NONE && st->percent >= 0) {
+ 		/* Rebuild/sync/whatever just finished.
+ 		 * If there is a number in /mismatch_cnt,
+ 		 * we should report that.
+@@ -587,8 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	st->percent = mse->percent;
+ 
+ 	remaining_disks = array.nr_disks;
+-	for (i=0; i<MAX_DISKS && remaining_disks > 0;
+-	     i++) {
++	for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
+ 		mdu_disk_info_t disc;
+ 		disc.number = i;
+ 		if (md_get_disk_info(fd, &disc) >= 0) {
+@@ -606,15 +603,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	    strncmp(mse->metadata_version, "external:", 9) == 0 &&
+ 	    is_subarray(mse->metadata_version+9)) {
+ 		char *sl;
+-		strcpy(st->parent_devnm,
+-		       mse->metadata_version+10);
++		strcpy(st->parent_devnm, mse->metadata_version+10);
+ 		sl = strchr(st->parent_devnm, '/');
+ 		if (sl)
+ 			*sl = 0;
+ 	} else
+ 		st->parent_devnm[0] = 0;
+-	if (st->metadata == NULL &&
+-	    st->parent_devnm[0] == 0)
++	if (st->metadata == NULL && st->parent_devnm[0] == 0)
+ 		st->metadata = super_by_fd(fd, NULL);
+ 
+ 	close(fd);
+@@ -625,12 +620,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		int change;
+ 		char *dv = NULL;
+ 		disc.number = i;
+-		if (i < last_disk &&
+-		    (info[i].major || info[i].minor)) {
++		if (i < last_disk && (info[i].major || info[i].minor)) {
+ 			newstate = info[i].state;
+-			dv = map_dev_preferred(
+-				info[i].major, info[i].minor, 1,
+-				prefer);
++			dv = map_dev_preferred(info[i].major, info[i].minor, 1,
++					       prefer);
+ 			disc.state = newstate;
+ 			disc.major = info[i].major;
+ 			disc.minor = info[i].minor;
+@@ -638,18 +631,18 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			newstate = (1 << MD_DISK_REMOVED);
+ 
+ 		if (dv == NULL && st->devid[i])
+-			dv = map_dev_preferred(
+-				major(st->devid[i]),
+-				minor(st->devid[i]), 1, prefer);
++			dv = map_dev_preferred(major(st->devid[i]),
++					       minor(st->devid[i]), 1, prefer);
+ 		change = newstate ^ st->devstate[i];
+ 		if (st->utime && change && !st->err && !new_array) {
+-			if ((st->devstate[i]&change)&(1<<MD_DISK_SYNC))
++			if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC))
+ 				alert("Fail", dev, dv, ainfo);
+-			else if ((newstate & (1<<MD_DISK_FAULTY)) &&
++			else if ((newstate & (1 << MD_DISK_FAULTY)) &&
+ 				 (disc.major || disc.minor) &&
+-				 st->devid[i] == makedev(disc.major, disc.minor))
++				 st->devid[i] == makedev(disc.major,
++							 disc.minor))
+ 				alert("FailSpare", dev, dv, ainfo);
+-			else if ((newstate&change)&(1<<MD_DISK_SYNC))
++			else if ((newstate&change) & (1 << MD_DISK_SYNC))
+ 				alert("SpareActive", dev, dv, ainfo);
+ 		}
+ 		st->devstate[i] = newstate;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch b/SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch
new file mode 100644
index 0000000..cf86704
--- /dev/null
+++ b/SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch
@@ -0,0 +1,329 @@
+From f566ef45d356f6dcd4ec54d294be8664770d8b84 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 11 May 2017 16:56:55 -0400
+Subject: [RHEL7.5 PATCH 139/169] Monitor: Fixup a pile of whitespace
+ issues
+
+No code was hurt in this event
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 110 +++++++++++++++++++++++++++++++-------------------------------
+ 1 file changed, 55 insertions(+), 55 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 83a6d10..0198a34 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -139,7 +139,7 @@ int Monitor(struct mddev_dev *devlist,
+ 
+ 	if (!alert_cmd) {
+ 		alert_cmd = conf_get_program();
+-		if (alert_cmd && ! c->scan)
++		if (alert_cmd && !c->scan)
+ 			pr_err("Monitor using program \"%s\" from config file\n",
+ 			       alert_cmd);
+ 	}
+@@ -164,8 +164,9 @@ int Monitor(struct mddev_dev *devlist,
+ 
+ 	if (devlist == NULL) {
+ 		mdlist = conf_get_ident(NULL);
+-		for (; mdlist; mdlist=mdlist->next) {
++		for (; mdlist; mdlist = mdlist->next) {
+ 			struct state *st;
++
+ 			if (mdlist->devname == NULL)
+ 				continue;
+ 			if (strcasecmp(mdlist->devname, "<ignore>") == 0)
+@@ -189,7 +190,8 @@ int Monitor(struct mddev_dev *devlist,
+ 		}
+ 	} else {
+ 		struct mddev_dev *dv;
+-		for (dv=devlist ; dv; dv=dv->next) {
++
++		for (dv = devlist; dv; dv = dv->next) {
+ 			struct state *st = xcalloc(1, sizeof *st);
+ 			mdlist = conf_get_ident(dv->devname);
+ 			st->devname = xstrdup(dv->devname);
+@@ -206,18 +208,18 @@ int Monitor(struct mddev_dev *devlist,
+ 		}
+ 	}
+ 
+-	while (! finished) {
++	while (!finished) {
+ 		int new_found = 0;
+ 		struct state *st, **stp;
+ 		int anydegraded = 0;
+ 
+ 		if (mdstat)
+ 			free_mdstat(mdstat);
+-		mdstat = mdstat_read(oneshot?0:1, 0);
++		mdstat = mdstat_read(oneshot ? 0 : 1, 0);
+ 		if (!mdstat)
+ 			mdstat_close();
+ 
+-		for (st=statelist; st; st=st->next)
++		for (st = statelist; st; st = st->next)
+ 			if (check_array(st, mdstat, c->test, &info,
+ 					increments, c->prefer))
+ 				anydegraded = 1;
+@@ -291,8 +293,8 @@ static int make_daemon(char *pidfile)
+ 	}
+ 	close(0);
+ 	open("/dev/null", O_RDWR);
+-	dup2(0,1);
+-	dup2(0,2);
++	dup2(0, 1);
++	dup2(0, 2);
+ 	setsid();
+ 	return -1;
+ }
+@@ -323,8 +325,7 @@ static int check_one_sharer(int scan)
+ 		fclose(fp);
+ 	}
+ 	if (scan) {
+-		if (mkdir(MDMON_DIR, S_IRWXU) < 0 &&
+-		    errno != EEXIST) {
++		if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
+ 			pr_err("Can't create autorebuild.pid file\n");
+ 		} else {
+ 			fp = fopen(path, "w");
+@@ -347,7 +348,8 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
+ 	if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) {
+ 		time_t now = time(0);
+ 
+-		printf("%1.15s: %s on %s %s\n", ctime(&now)+4, event, dev, disc?disc:"unknown device");
++		printf("%1.15s: %s on %s %s\n", ctime(&now) + 4,
++		       event, dev, disc?disc:"unknown device");
+ 	}
+ 	if (info->alert_cmd) {
+ 		int pid = fork();
+@@ -363,11 +365,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
+ 			exit(2);
+ 		}
+ 	}
+-	if (info->mailaddr &&
+-	    (strncmp(event, "Fail", 4)==0 ||
+-	     strncmp(event, "Test", 4)==0 ||
+-	     strncmp(event, "Spares", 6)==0 ||
+-	     strncmp(event, "Degrade", 7)==0)) {
++	if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 ||
++			       strncmp(event, "Test", 4) == 0 ||
++			       strncmp(event, "Spares", 6) == 0 ||
++			       strncmp(event, "Degrade", 7) == 0)) {
+ 		FILE *mp = popen(Sendmail, "w");
+ 		if (mp) {
+ 			FILE *mdstat;
+@@ -377,7 +378,8 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
+ 			if (info->mailfrom)
+ 				fprintf(mp, "From: %s\n", info->mailfrom);
+ 			else
+-				fprintf(mp, "From: %s monitoring <root>\n", Name);
++				fprintf(mp, "From: %s monitoring <root>\n",
++					Name);
+ 			fprintf(mp, "To: %s\n", info->mailaddr);
+ 			fprintf(mp, "Subject: %s event on %s:%s\n\n",
+ 				event, dev, hname);
+@@ -403,8 +405,9 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
+ 				int n;
+ 				fprintf(mp,
+ 					"\nP.S. The /proc/mdstat file currently contains the following:\n\n");
+-				while ( (n=fread(buf, 1, sizeof(buf), mdstat)) > 0)
+-					n=fwrite(buf, 1, n, mp);
++				while ((n = fread(buf, 1, sizeof(buf),
++						  mdstat)) > 0)
++					n = fwrite(buf, 1, n, mp);
+ 				fclose(mdstat);
+ 			}
+ 			pclose(mp);
+@@ -416,13 +419,13 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
+ 		/* Log at a different severity depending on the event.
+ 		 *
+ 		 * These are the critical events:  */
+-		if (strncmp(event, "Fail", 4)==0 ||
+-		    strncmp(event, "Degrade", 7)==0 ||
+-		    strncmp(event, "DeviceDisappeared", 17)==0)
++		if (strncmp(event, "Fail", 4) == 0 ||
++		    strncmp(event, "Degrade", 7) == 0 ||
++		    strncmp(event, "DeviceDisappeared", 17) == 0)
+ 			priority = LOG_CRIT;
+ 		/* Good to know about, but are not failures: */
+-		else if (strncmp(event, "Rebuild", 7)==0 ||
+-			 strncmp(event, "MoveSpare", 9)==0 ||
++		else if (strncmp(event, "Rebuild", 7) == 0 ||
++			 strncmp(event, "MoveSpare", 9) == 0 ||
+ 			 strncmp(event, "Spares", 6) != 0)
+ 			priority = LOG_WARNING;
+ 		/* Everything else: */
+@@ -497,7 +500,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		goto out;
+ 	}
+ 
+-	for (mse2 = mdstat ; mse2 ; mse2=mse2->next)
++	for (mse2 = mdstat; mse2; mse2 = mse2->next)
+ 		if (strcmp(mse2->devnm, st->devnm) == 0) {
+ 			mse2->devnm[0] = 0; /* flag it as "used" */
+ 			mse = mse2;
+@@ -568,7 +571,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			char cnt[80];
+ 			snprintf(cnt, sizeof(cnt),
+ 				 " mismatches found: %d (on raid level %d)",
+-				sra->mismatch_cnt, sra->array.level);
++				 sra->mismatch_cnt, sra->array.level);
+ 			alert("RebuildFinished", dev, cnt, ainfo);
+ 		} else
+ 			alert("RebuildFinished", dev, NULL, ainfo);
+@@ -594,7 +597,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	    strncmp(mse->metadata_version, "external:", 9) == 0 &&
+ 	    is_subarray(mse->metadata_version+9)) {
+ 		char *sl;
+-		strcpy(st->parent_devnm, mse->metadata_version+10);
++		strcpy(st->parent_devnm, mse->metadata_version + 10);
+ 		sl = strchr(st->parent_devnm, '/');
+ 		if (sl)
+ 			*sl = 0;
+@@ -603,9 +606,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->metadata == NULL && st->parent_devnm[0] == 0)
+ 		st->metadata = super_by_fd(fd, NULL);
+ 
+-	for (i=0; i<MAX_DISKS; i++) {
+-		mdu_disk_info_t disc = {0,0,0,0,0};
+-		int newstate=0;
++	for (i = 0; i < MAX_DISKS; i++) {
++		mdu_disk_info_t disc = {0, 0, 0, 0, 0};
++		int newstate = 0;
+ 		int change;
+ 		char *dv = NULL;
+ 		disc.number = i;
+@@ -668,12 +671,10 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
+ 	int new_found = 0;
+ 	char *name;
+ 
+-	for (mse=mdstat; mse; mse=mse->next)
+-		if (mse->devnm[0] &&
+-		    (!mse->level  || /* retrieve containers */
+-		     (strcmp(mse->level, "raid0") != 0 &&
+-		      strcmp(mse->level, "linear") != 0))
+-			) {
++	for (mse = mdstat; mse; mse = mse->next)
++		if (mse->devnm[0] && (!mse->level  || /* retrieve containers */
++				      (strcmp(mse->level, "raid0") != 0 &&
++				       strcmp(mse->level, "linear") != 0))) {
+ 			struct state *st = xcalloc(1, sizeof *st);
+ 			mdu_array_info_t array;
+ 			int fd;
+@@ -707,7 +708,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
+ 			st->percent = RESYNC_UNKNOWN;
+ 			st->expected_spares = -1;
+ 			if (mse->metadata_version &&
+-			    strncmp(mse->metadata_version, "external:", 9) == 0 &&
++			    strncmp(mse->metadata_version,
++				    "external:", 9) == 0 &&
+ 			    is_subarray(mse->metadata_version+9)) {
+ 				char *sl;
+ 				strcpy(st->parent_devnm,
+@@ -729,8 +731,7 @@ static int get_required_spare_criteria(struct state *st,
+ {
+ 	int fd;
+ 
+-	if (!st->metadata ||
+-	    !st->metadata->ss->get_spare_criteria) {
++	if (!st->metadata || !st->metadata->ss->get_spare_criteria) {
+ 		sc->min_size = 0;
+ 		sc->sector_size = 0;
+ 		return 0;
+@@ -779,14 +780,13 @@ static int check_donor(struct state *from, struct state *to)
+ }
+ 
+ static dev_t choose_spare(struct state *from, struct state *to,
+-			struct domainlist *domlist, struct spare_criteria *sc)
++			  struct domainlist *domlist, struct spare_criteria *sc)
+ {
+ 	int d;
+ 	dev_t dev = 0;
+ 
+ 	for (d = from->raid; !dev && d < MAX_DISKS; d++) {
+-		if (from->devid[d] > 0 &&
+-		    from->devstate[d] == 0) {
++		if (from->devid[d] > 0 && from->devstate[d] == 0) {
+ 			struct dev_policy *pol;
+ 			unsigned long long dev_size;
+ 			unsigned int dev_sector_size;
+@@ -810,7 +810,8 @@ static dev_t choose_spare(struct state *from, struct state *to,
+ 			if (from->spare_group)
+ 				pol_add(&pol, pol_domain,
+ 					from->spare_group, NULL);
+-			if (domain_test(domlist, pol, to->metadata->ss->name) == 1)
++			if (domain_test(domlist, pol,
++					to->metadata->ss->name) == 1)
+ 			    dev = from->devid[d];
+ 			dev_policy_free(pol);
+ 		}
+@@ -857,8 +858,8 @@ static dev_t container_choose_spare(struct state *from, struct state *to,
+ 		}
+ 		dp = list->devs;
+ 		while (dp) {
+-			if (dp->disk.state & (1<<MD_DISK_SYNC) &&
+-			    !(dp->disk.state & (1<<MD_DISK_FAULTY)))
++			if (dp->disk.state & (1 << MD_DISK_SYNC) &&
++			    !(dp->disk.state & (1 << MD_DISK_FAULTY)))
+ 				active_cnt++;
+ 			dp = dp->next;
+ 		}
+@@ -891,8 +892,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
+ 
+ 	link_containers_with_subarrays(statelist);
+ 	for (st = statelist; st; st = st->next)
+-		if (st->active < st->raid &&
+-		    st->spare == 0 && !st->err) {
++		if (st->active < st->raid && st->spare == 0 && !st->err) {
+ 			struct domainlist *domlist = NULL;
+ 			int d;
+ 			struct state *to = st;
+@@ -940,9 +940,11 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
+ 				else
+ 					devid = choose_spare(from, to, domlist,
+ 							     &sc);
+-				if (devid > 0
+-				    && move_spare(from->devname, to->devname, devid)) {
+-					alert("MoveSpare", to->devname, from->devname, info);
++				if (devid > 0 &&
++				    move_spare(from->devname, to->devname,
++					       devid)) {
++					alert("MoveSpare", to->devname,
++					      from->devname, info);
+ 					break;
+ 				}
+ 			}
+@@ -967,8 +969,7 @@ static void link_containers_with_subarrays(struct state *list)
+ 	for (st = list; st; st = st->next)
+ 		if (st->parent_devnm[0])
+ 			for (cont = list; cont; cont = cont->next)
+-				if (!cont->err &&
+-				    cont->parent_devnm[0] == 0 &&
++				if (!cont->err && cont->parent_devnm[0] == 0 &&
+ 				    strcmp(cont->devnm, st->parent_devnm) == 0) {
+ 					st->parent = cont;
+ 					st->subarray = cont->subarray;
+@@ -992,7 +993,7 @@ int Wait(char *dev)
+ 		struct mdstat_ent *ms = mdstat_read(1, 0);
+ 		struct mdstat_ent *e;
+ 
+-		for (e=ms ; e; e=e->next)
++		for (e = ms; e; e = e->next)
+ 			if (strcmp(e->devnm, devnm) == 0)
+ 				break;
+ 
+@@ -1115,8 +1116,7 @@ int WaitClean(char *dev, int sock, int verbose)
+ 		} else
+ 			rv = 1;
+ 		if (rv && verbose)
+-			pr_err("Error waiting for %s to be clean\n",
+-				dev);
++			pr_err("Error waiting for %s to be clean\n", dev);
+ 
+ 		/* restore the original safe_mode_delay */
+ 		sysfs_set_safemode(mdi, mdi->safe_mode_delay);
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-Include-containers-in-spare-migration2.patch b/SOURCES/Monitor-Include-containers-in-spare-migration2.patch
new file mode 100644
index 0000000..f2e9ea2
--- /dev/null
+++ b/SOURCES/Monitor-Include-containers-in-spare-migration2.patch
@@ -0,0 +1,36 @@
+From 2dab69c9e3acace828bbb6a00514fa820f8ca64f Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 16 Aug 2017 14:59:46 +0200
+Subject: [RHEL7.5 PATCH 169/169] Monitor: Include containers in spare
+ migration
+
+Spare migration doesn't work for external metadata. mdadm skips
+a container with spare device because it is inactive. It used to work
+because GET_ARRAY_INFO ioctl returned valid structure for a container
+and mdadm treated such response as active container. Current
+implementation checks it in sysfs where container is shown as inactive.
+
+Adapt sysfs implementation to work the same way as ioctl.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index f70e5b5..497e364 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -497,7 +497,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (mse->level == NULL)
+ 		is_container = 1;
+ 
+-	if (!md_array_active(fd))
++	if (!is_container && !md_array_active(fd))
+ 		goto disappeared;
+ 
+ 	fcntl(fd, F_SETFD, FD_CLOEXEC);
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch b/SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch
new file mode 100644
index 0000000..b08a04b
--- /dev/null
+++ b/SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch
@@ -0,0 +1,45 @@
+From 9f3dd4549b2b904d343b79a8a7ba40c547e71d5d Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 11 May 2017 16:40:16 -0400
+Subject: [RHEL7.5 PATCH 137/169] Monitor: Not much point declaring mdlist
+ in both forks of the if() statement
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 5b95847..a4afe75 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -127,6 +127,7 @@ int Monitor(struct mddev_dev *devlist,
+ 	struct mdstat_ent *mdstat = NULL;
+ 	char *mailfrom = NULL;
+ 	struct alert_info info;
++	struct mddev_ident *mdlist;
+ 
+ 	if (!mailaddr) {
+ 		mailaddr = conf_get_mailaddr();
+@@ -162,7 +163,7 @@ int Monitor(struct mddev_dev *devlist,
+ 			return 1;
+ 
+ 	if (devlist == NULL) {
+-		struct mddev_ident *mdlist = conf_get_ident(NULL);
++		mdlist = conf_get_ident(NULL);
+ 		for (; mdlist; mdlist=mdlist->next) {
+ 			struct state *st;
+ 			if (mdlist->devname == NULL)
+@@ -189,8 +190,8 @@ int Monitor(struct mddev_dev *devlist,
+ 	} else {
+ 		struct mddev_dev *dv;
+ 		for (dv=devlist ; dv; dv=dv->next) {
+-			struct mddev_ident *mdlist = conf_get_ident(dv->devname);
+ 			struct state *st = xcalloc(1, sizeof *st);
++			mdlist = conf_get_ident(dv->devname);
+ 			st->devname = xstrdup(dv->devname);
+ 			st->next = statelist;
+ 			st->devnm[0] = 0;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch b/SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch
new file mode 100644
index 0000000..68870c0
--- /dev/null
+++ b/SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch
@@ -0,0 +1,81 @@
+From b9a0309c7fc3e6c1607d51ab3c3f8486478a65ef Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Mon, 8 May 2017 17:34:08 -0400
+Subject: [RHEL7.5 PATCH 117/169] Monitor: Use md_array_active() instead of
+ manually fiddling in sysfs
+
+This removes a pile of clutter that can easily behandled with a simple
+check of array_state.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 39 +++++++++++----------------------------
+ 1 file changed, 11 insertions(+), 28 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index e2b36ff..b5231d2 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -454,7 +454,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	mdu_array_info_t array;
+ 	struct mdstat_ent *mse = NULL, *mse2;
+ 	char *dev = st->devname;
+-	int fd = -1;
++	int fd;
+ 	int i;
+ 	int remaining_disks;
+ 	int last_disk;
+@@ -462,33 +462,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 
+ 	if (test)
+ 		alert("TestMessage", dev, NULL, ainfo);
+-	if (st->devnm[0])
+-		fd = open("/sys/block", O_RDONLY|O_DIRECTORY);
+-	if (fd >= 0) {
+-		/* Don't open the device unless it is present and
+-		 * active in sysfs.
+-		 */
+-		char buf[10];
+-		close(fd);
+-		fd = sysfs_open(st->devnm, NULL, "array_state");
+-		if (fd < 0 ||
+-		    read(fd, buf, 10) < 5 ||
+-		    strncmp(buf,"clear",5) == 0 ||
+-		    strncmp(buf,"inact",5) == 0) {
+-			if (fd >= 0)
+-				close(fd);
+-			fd = sysfs_open(st->devnm, NULL, "level");
+-			if (fd < 0 || read(fd, buf, 10) != 0) {
+-				if (fd >= 0)
+-					close(fd);
+-				if (!st->err)
+-					alert("DeviceDisappeared", dev, NULL, ainfo);
+-				st->err++;
+-				return 0;
+-			}
+-		}
+-		close(fd);
+-	}
++
+ 	fd = open(dev, O_RDONLY);
+ 	if (fd < 0) {
+ 		if (!st->err)
+@@ -496,6 +470,15 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		st->err++;
+ 		return 0;
+ 	}
++
++	if (!md_array_active(fd)) {
++		close(fd);
++		if (!st->err)
++			alert("DeviceDisappeared", dev, NULL, ainfo);
++		st->err++;
++		return 0;
++	}
++
+ 	fcntl(fd, F_SETFD, FD_CLOEXEC);
+ 	if (md_get_array_info(fd, &array) < 0) {
+ 		if (!st->err)
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-Centralize-exit-path.patch b/SOURCES/Monitor-check_array-Centralize-exit-path.patch
new file mode 100644
index 0000000..a02e634
--- /dev/null
+++ b/SOURCES/Monitor-check_array-Centralize-exit-path.patch
@@ -0,0 +1,102 @@
+From 1830e74b4cbde28279f341bc80b68e9d82df32c6 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:25:23 -0400
+Subject: [RHEL7.5 PATCH 125/169] Monitor/check_array: Centralize exit path
+
+Improve exit handling to make it easier to share error handling and free
+sysfs entries later.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index c96f8e8..f404009 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -459,16 +459,19 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	int remaining_disks;
+ 	int last_disk;
+ 	int new_array = 0;
++	int retval;
+ 
+ 	if (test)
+ 		alert("TestMessage", dev, NULL, ainfo);
+ 
++	retval = 0;
++
+ 	fd = open(dev, O_RDONLY);
+ 	if (fd < 0) {
+ 		if (!st->err)
+ 			alert("DeviceDisappeared", dev, NULL, ainfo);
+ 		st->err++;
+-		return 0;
++		goto out;
+ 	}
+ 
+ 	if (!md_array_active(fd)) {
+@@ -476,7 +479,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		if (!st->err)
+ 			alert("DeviceDisappeared", dev, NULL, ainfo);
+ 		st->err++;
+-		return 0;
++		goto out;
+ 	}
+ 
+ 	fcntl(fd, F_SETFD, FD_CLOEXEC);
+@@ -485,7 +488,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			alert("DeviceDisappeared", dev, NULL, ainfo);
+ 		st->err++;
+ 		close(fd);
+-		return 0;
++		goto out;
+ 	}
+ 	/* It's much easier to list what array levels can't
+ 	 * have a device disappear than all of them that can
+@@ -495,7 +498,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
+ 		st->err++;
+ 		close(fd);
+-		return 0;
++		goto out;
+ 	}
+ 	if (st->devnm[0] == 0)
+ 		strcpy(st->devnm, fd2devnm(fd));
+@@ -511,7 +514,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		 * or re-created after reading mdstat*/
+ 		st->err++;
+ 		close(fd);
+-		return 0;
++		goto out;
+ 	}
+ 	/* this array is in /proc/mdstat */
+ 	if (array.utime == 0)
+@@ -533,9 +536,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	    (mse == NULL  || (mse->percent == st->percent))) {
+ 		close(fd);
+ 		if ((st->active < st->raid) && st->spare == 0)
+-			return 1;
+-		else
+-			return 0;
++			retval = 1;
++		goto out;
+ 	}
+ 	if (st->utime == 0 && /* new array */
+ 	    mse->pattern && strchr(mse->pattern, '_') /* degraded */)
+@@ -656,8 +658,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	st->raid = array.raid_disks;
+ 	st->err = 0;
+ 	if ((st->active < st->raid) && st->spare == 0)
+-		return 1;
+-	return 0;
++		retval = 1;
++
++ out:
++	return retval;
+ }
+ 
+ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch b/SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch
new file mode 100644
index 0000000..45e25b2
--- /dev/null
+++ b/SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch
@@ -0,0 +1,36 @@
+From 12a9d21f4e9fd4d3a14129407f1e8da6d6444cd6 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:58:55 -0400
+Subject: [RHEL7.5 PATCH 131/169] Monitor/check_array: Get array_disks from
+ sysfs
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 9456efd..fe6f2b4 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -481,7 +481,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->devnm[0] == 0)
+ 		strcpy(st->devnm, fd2devnm(fd));
+ 
+-	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DEGRADED |
++	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
+ 			 GET_MISMATCH);
+ 	if (!sra)
+ 		goto disappeared;
+@@ -641,7 +641,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	st->spare = array.spare_disks;
+ 	st->failed = sra->array.failed_disks;
+ 	st->utime = array.utime;
+-	st->raid = array.raid_disks;
++	st->raid = sra->array.raid_disks;
+ 	st->err = 0;
+ 	if ((st->active < st->raid) && st->spare == 0)
+ 		retval = 1;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch b/SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch
new file mode 100644
index 0000000..9b21ec6
--- /dev/null
+++ b/SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch
@@ -0,0 +1,46 @@
+From b8e5713c74901862b96bf599ab6fd227addc1498 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:54:19 -0400
+Subject: [RHEL7.5 PATCH 130/169] Monitor/check_array: Get 'failed_disks'
+ from sysfs
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index b94fd7c..9456efd 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -481,7 +481,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->devnm[0] == 0)
+ 		strcpy(st->devnm, fd2devnm(fd));
+ 
+-	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_MISMATCH);
++	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DEGRADED |
++			 GET_MISMATCH);
+ 	if (!sra)
+ 		goto disappeared;
+ 
+@@ -522,7 +523,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		alert("NewArray", st->devname, NULL, ainfo);
+ 	}
+ 
+-	if (st->utime == array.utime && st->failed == array.failed_disks &&
++	if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
+ 	    st->working == array.working_disks &&
+ 	    st->spare == array.spare_disks &&
+ 	    (mse == NULL  || (mse->percent == st->percent))) {
+@@ -638,7 +639,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	st->active = array.active_disks;
+ 	st->working = array.working_disks;
+ 	st->spare = array.spare_disks;
+-	st->failed = array.failed_disks;
++	st->failed = sra->array.failed_disks;
+ 	st->utime = array.utime;
+ 	st->raid = array.raid_disks;
+ 	st->err = 0;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch b/SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch
new file mode 100644
index 0000000..092c0ff
--- /dev/null
+++ b/SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch
@@ -0,0 +1,71 @@
+From b98943a4f889b466a3d07264068042b18c620d33 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 17:03:03 -0400
+Subject: [RHEL7.5 PATCH 132/169] Monitor/check_array: Get nr_disks,
+ active_disks and spare_disks from sysfs
+
+This leaves working_disks and utime missing before we can eliminate
+check_array()'s call to md_get_array_info()
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index fe6f2b4..2204528 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -482,7 +482,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		strcpy(st->devnm, fd2devnm(fd));
+ 
+ 	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
+-			 GET_MISMATCH);
++			 GET_MISMATCH | GET_DEVS | GET_STATE);
+ 	if (!sra)
+ 		goto disappeared;
+ 
+@@ -525,7 +525,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 
+ 	if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
+ 	    st->working == array.working_disks &&
+-	    st->spare == array.spare_disks &&
++	    st->spare == sra->array.spare_disks &&
+ 	    (mse == NULL  || (mse->percent == st->percent))) {
+ 		if ((st->active < st->raid) && st->spare == 0)
+ 			retval = 1;
+@@ -535,8 +535,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	    mse->pattern && strchr(mse->pattern, '_') /* degraded */)
+ 		alert("DegradedArray", dev, NULL, ainfo);
+ 
+-	if (st->utime == 0 && /* new array */
+-	    st->expected_spares > 0 && array.spare_disks < st->expected_spares)
++	if (st->utime == 0 && /* new array */ st->expected_spares > 0 &&
++	    sra->array.spare_disks < st->expected_spares)
+ 		alert("SparesMissing", dev, NULL, ainfo);
+ 	if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
+ 	    mse->percent >= 0)
+@@ -574,7 +574,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	}
+ 	st->percent = mse->percent;
+ 
+-	remaining_disks = array.nr_disks;
++	remaining_disks = sra->array.nr_disks;
+ 	for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
+ 		mdu_disk_info_t disc;
+ 		disc.number = i;
+@@ -636,9 +636,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		st->devstate[i] = newstate;
+ 		st->devid[i] = makedev(disc.major, disc.minor);
+ 	}
+-	st->active = array.active_disks;
++	st->active = sra->array.active_disks;
+ 	st->working = array.working_disks;
+-	st->spare = array.spare_disks;
++	st->spare = sra->array.spare_disks;
+ 	st->failed = sra->array.failed_disks;
+ 	st->utime = array.utime;
+ 	st->raid = sra->array.raid_disks;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch b/SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch
new file mode 100644
index 0000000..01b4eae
--- /dev/null
+++ b/SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch
@@ -0,0 +1,44 @@
+From 48bc2ade86db576036375184774a3ebadf6a22e3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:52:44 -0400
+Subject: [RHEL7.5 PATCH 129/169] Monitor/check_array: Obtain RAID level
+ from syfs
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 75aea91..b94fd7c 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -481,14 +481,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->devnm[0] == 0)
+ 		strcpy(st->devnm, fd2devnm(fd));
+ 
+-	sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
++	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_MISMATCH);
+ 	if (!sra)
+ 		goto disappeared;
+ 
+ 	/* It's much easier to list what array levels can't
+ 	 * have a device disappear than all of them that can
+ 	 */
+-	if (array.level == 0 || array.level == -1) {
++	if (sra->array.level == 0 || sra->array.level == -1) {
+ 		if (!st->err && !st->from_config)
+ 			alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
+ 		st->err++;
+@@ -566,7 +566,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			char cnt[80];
+ 			snprintf(cnt, sizeof(cnt),
+ 				 " mismatches found: %d (on raid level %d)",
+-				sra->mismatch_cnt, array.level);
++				sra->mismatch_cnt, sra->array.level);
+ 			alert("RebuildFinished", dev, cnt, ainfo);
+ 		} else
+ 			alert("RebuildFinished", dev, NULL, ainfo);
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch b/SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch
new file mode 100644
index 0000000..6542556
--- /dev/null
+++ b/SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch
@@ -0,0 +1,79 @@
+From aed5f5c34c2b248876b874898d0b3bf65b6cca53 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:49:33 -0400
+Subject: [RHEL7.5 PATCH 128/169] Monitor/check_array: Read sysfs entry
+ earlier
+
+This will allow us to pull additional info from sysfs, such as level
+and device info.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index bb3a2c4..75aea91 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -451,7 +451,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	 * '1' if the array is degraded, or '0' if it is optimal (or dead).
+ 	 */
+ 	struct { int state, major, minor; } info[MAX_DISKS];
+-	struct mdinfo *sra;
++	struct mdinfo *sra = NULL;
+ 	mdu_array_info_t array;
+ 	struct mdstat_ent *mse = NULL, *mse2;
+ 	char *dev = st->devname;
+@@ -478,6 +478,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (md_get_array_info(fd, &array) < 0)
+ 		goto disappeared;
+ 
++	if (st->devnm[0] == 0)
++		strcpy(st->devnm, fd2devnm(fd));
++
++	sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
++	if (!sra)
++		goto disappeared;
++
+ 	/* It's much easier to list what array levels can't
+ 	 * have a device disappear than all of them that can
+ 	 */
+@@ -487,8 +494,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		st->err++;
+ 		goto out;
+ 	}
+-	if (st->devnm[0] == 0)
+-		strcpy(st->devnm, fd2devnm(fd));
+ 
+ 	for (mse2 = mdstat ; mse2 ; mse2=mse2->next)
+ 		if (strcmp(mse2->devnm, st->devnm) == 0) {
+@@ -557,7 +562,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		 * If there is a number in /mismatch_cnt,
+ 		 * we should report that.
+ 		 */
+-		sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
+ 		if (sra && sra->mismatch_cnt > 0) {
+ 			char cnt[80];
+ 			snprintf(cnt, sizeof(cnt),
+@@ -566,8 +570,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 			alert("RebuildFinished", dev, cnt, ainfo);
+ 		} else
+ 			alert("RebuildFinished", dev, NULL, ainfo);
+-		if (sra)
+-			sysfs_free(sra);
+ 	}
+ 	st->percent = mse->percent;
+ 
+@@ -644,6 +646,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		retval = 1;
+ 
+  out:
++	if (sra)
++		sysfs_free(sra);
+ 	if (fd > 0)
+ 		close(fd);
+ 	return retval;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch b/SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch
new file mode 100644
index 0000000..54bafc1
--- /dev/null
+++ b/SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch
@@ -0,0 +1,38 @@
+From 826522f0dc86d31cc7207b01957b5c4243f49dc8 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:41:06 -0400
+Subject: [RHEL7.5 PATCH 127/169] Monitor/check_array: Declate mdinfo
+ instance globally
+
+We can pull in more information from sysfs earlier, so move sra to the top.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index c519877..bb3a2c4 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -451,6 +451,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	 * '1' if the array is degraded, or '0' if it is optimal (or dead).
+ 	 */
+ 	struct { int state, major, minor; } info[MAX_DISKS];
++	struct mdinfo *sra;
+ 	mdu_array_info_t array;
+ 	struct mdstat_ent *mse = NULL, *mse2;
+ 	char *dev = st->devname;
+@@ -556,8 +557,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		 * If there is a number in /mismatch_cnt,
+ 		 * we should report that.
+ 		 */
+-		struct mdinfo *sra =
+-			sysfs_read(-1, st->devnm, GET_MISMATCH);
++		sra = sysfs_read(-1, st->devnm, GET_MISMATCH);
+ 		if (sra && sra->mismatch_cnt > 0) {
+ 			char cnt[80];
+ 			snprintf(cnt, sizeof(cnt),
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch b/SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch
new file mode 100644
index 0000000..08078f1
--- /dev/null
+++ b/SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch
@@ -0,0 +1,99 @@
+From 13e5d8455c22d4db420ead9fde3ee0c1536b73a3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 16:38:06 -0400
+Subject: [RHEL7.5 PATCH 126/169] Monitor/check_array: Reduce duplicated
+ error handling
+
+Avoid closing fd in multiple places, and duplicating the error message
+for when a device disappeared.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 39 +++++++++++++++------------------------
+ 1 file changed, 15 insertions(+), 24 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index f404009..c519877 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -467,29 +467,16 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	retval = 0;
+ 
+ 	fd = open(dev, O_RDONLY);
+-	if (fd < 0) {
+-		if (!st->err)
+-			alert("DeviceDisappeared", dev, NULL, ainfo);
+-		st->err++;
+-		goto out;
+-	}
++	if (fd < 0)
++		goto disappeared;
+ 
+-	if (!md_array_active(fd)) {
+-		close(fd);
+-		if (!st->err)
+-			alert("DeviceDisappeared", dev, NULL, ainfo);
+-		st->err++;
+-		goto out;
+-	}
++	if (!md_array_active(fd))
++		goto disappeared;
+ 
+ 	fcntl(fd, F_SETFD, FD_CLOEXEC);
+-	if (md_get_array_info(fd, &array) < 0) {
+-		if (!st->err)
+-			alert("DeviceDisappeared", dev, NULL, ainfo);
+-		st->err++;
+-		close(fd);
+-		goto out;
+-	}
++	if (md_get_array_info(fd, &array) < 0)
++		goto disappeared;
++
+ 	/* It's much easier to list what array levels can't
+ 	 * have a device disappear than all of them that can
+ 	 */
+@@ -497,7 +484,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		if (!st->err && !st->from_config)
+ 			alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
+ 		st->err++;
+-		close(fd);
+ 		goto out;
+ 	}
+ 	if (st->devnm[0] == 0)
+@@ -534,7 +520,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	    st->working == array.working_disks &&
+ 	    st->spare == array.spare_disks &&
+ 	    (mse == NULL  || (mse->percent == st->percent))) {
+-		close(fd);
+ 		if ((st->active < st->raid) && st->spare == 0)
+ 			retval = 1;
+ 		goto out;
+@@ -614,8 +599,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->metadata == NULL && st->parent_devnm[0] == 0)
+ 		st->metadata = super_by_fd(fd, NULL);
+ 
+-	close(fd);
+-
+ 	for (i=0; i<MAX_DISKS; i++) {
+ 		mdu_disk_info_t disc = {0,0,0,0,0};
+ 		int newstate=0;
+@@ -661,7 +644,15 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		retval = 1;
+ 
+  out:
++	if (fd > 0)
++		close(fd);
+ 	return retval;
++
++ disappeared:
++	if (!st->err)
++		alert("DeviceDisappeared", dev, NULL, ainfo);
++	st->err++;
++	goto out;
+ }
+ 
+ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch b/SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch
new file mode 100644
index 0000000..e0c7736
--- /dev/null
+++ b/SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch
@@ -0,0 +1,38 @@
+From e5eb6857cde0a6a44684dcc7ea0fb196546cf56c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 17:15:14 -0400
+Subject: [RHEL7.5 PATCH 134/169] Monitor/check_array: Use working_disks
+ from sysfs
+
+sysfs now provides working_disks information, so lets use it too.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 2204528..5b95847 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -524,7 +524,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	}
+ 
+ 	if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
+-	    st->working == array.working_disks &&
++	    st->working == sra->array.working_disks &&
+ 	    st->spare == sra->array.spare_disks &&
+ 	    (mse == NULL  || (mse->percent == st->percent))) {
+ 		if ((st->active < st->raid) && st->spare == 0)
+@@ -637,7 +637,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		st->devid[i] = makedev(disc.major, disc.minor);
+ 	}
+ 	st->active = sra->array.active_disks;
+-	st->working = array.working_disks;
++	st->working = sra->array.working_disks;
+ 	st->spare = sra->array.spare_disks;
+ 	st->failed = sra->array.failed_disks;
+ 	st->utime = array.utime;
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch b/SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch
new file mode 100644
index 0000000..79acd00
--- /dev/null
+++ b/SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch
@@ -0,0 +1,105 @@
+From 802961a2396d342b7bb3d548d412be26acbd7fa8 Mon Sep 17 00:00:00 2001
+From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date: Wed, 16 Aug 2017 14:22:32 +0200
+Subject: [RHEL7.5 PATCH 168/169] Monitor: containers don't have the same
+ sysfs properties as arrays
+
+GET_MISMATCH option doesn't exist for containers so sysfs_read fails if
+this information is requested. Set options according to the device using
+information from /proc/mdstat.
+
+Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 46 ++++++++++++++++++++++++++++------------------
+ 1 file changed, 28 insertions(+), 18 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 48c451c..f70e5b5 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -465,6 +465,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	int last_disk;
+ 	int new_array = 0;
+ 	int retval;
++	int is_container = 0;
++	unsigned long array_only_flags = 0;
+ 
+ 	if (test)
+ 		alert("TestMessage", dev, NULL, ainfo);
+@@ -475,6 +477,26 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (fd < 0)
+ 		goto disappeared;
+ 
++	if (st->devnm[0] == 0)
++		strcpy(st->devnm, fd2devnm(fd));
++
++	for (mse2 = mdstat; mse2; mse2 = mse2->next)
++		if (strcmp(mse2->devnm, st->devnm) == 0) {
++			mse2->devnm[0] = 0; /* flag it as "used" */
++			mse = mse2;
++		}
++
++	if (!mse) {
++		/* duplicated array in statelist
++		 * or re-created after reading mdstat
++		 */
++		st->err++;
++		goto out;
++	}
++
++	if (mse->level == NULL)
++		is_container = 1;
++
+ 	if (!md_array_active(fd))
+ 		goto disappeared;
+ 
+@@ -482,11 +504,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (md_get_array_info(fd, &array) < 0)
+ 		goto disappeared;
+ 
+-	if (st->devnm[0] == 0)
+-		strcpy(st->devnm, fd2devnm(fd));
++	if (!is_container)
++		array_only_flags |= GET_MISMATCH;
++
++	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEVS |
++			GET_STATE | array_only_flags);
+ 
+-	sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_MISMATCH |
+-			 GET_DEVS | GET_STATE);
+ 	if (!sra)
+ 		goto disappeared;
+ 
+@@ -500,19 +523,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		goto out;
+ 	}
+ 
+-	for (mse2 = mdstat; mse2; mse2 = mse2->next)
+-		if (strcmp(mse2->devnm, st->devnm) == 0) {
+-			mse2->devnm[0] = 0; /* flag it as "used" */
+-			mse = mse2;
+-		}
+-
+-	if (!mse) {
+-		/* duplicated array in statelist
+-		 * or re-created after reading mdstat*/
+-		st->err++;
+-		close(fd);
+-		goto out;
+-	}
+ 	/* this array is in /proc/mdstat */
+ 	if (array.utime == 0)
+ 		/* external arrays don't update utime, so
+@@ -653,7 +663,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+  out:
+ 	if (sra)
+ 		sysfs_free(sra);
+-	if (fd > 0)
++	if (fd >= 0)
+ 		close(fd);
+ 	return retval;
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch b/SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch
new file mode 100644
index 0000000..8539856
--- /dev/null
+++ b/SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch
@@ -0,0 +1,49 @@
+From cb91230c87e02bf885759e9218abea629ab9f4b9 Mon Sep 17 00:00:00 2001
+From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date: Mon, 19 Jun 2017 11:19:53 +0200
+Subject: [RHEL7.5 PATCH 158/169] Monitor: don't assume mdadm parameter is
+ a block device
+
+If symlink (e.g. /dev/md/raid) is passed as a parameter to mdadm --wait,
+it fails as it's not able to find a corresponding entry in /proc/mdstat
+output. Get parameter file major:minor and look for block device name in
+sysfs. This commit is partial revert of commit 9e04ac1c43e6
+("mdadm/util: unify stat checking blkdev into function").
+
+Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index bef2f1b..48c451c 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -982,12 +982,21 @@ static void link_containers_with_subarrays(struct state *list)
+ int Wait(char *dev)
+ {
+ 	char devnm[32];
++	dev_t rdev;
++	char *tmp;
+ 	int rv = 1;
+ 	int frozen_remaining = 3;
+ 
+-	if (!stat_is_blkdev(dev, NULL))
++	if (!stat_is_blkdev(dev, &rdev))
++		return 2;
++
++	tmp = devid2devnm(rdev);
++	if (!tmp) {
++		pr_err("Cannot get md device name.\n");
+ 		return 2;
+-	strcpy(devnm, dev);
++	}
++
++	strcpy(devnm, tmp);
+ 
+ 	while(1) {
+ 		struct mdstat_ent *ms = mdstat_read(1, 0);
+-- 
+2.7.4
+
diff --git a/SOURCES/Monitor-mailfrom-is-initialized-correctly.patch b/SOURCES/Monitor-mailfrom-is-initialized-correctly.patch
new file mode 100644
index 0000000..95092b9
--- /dev/null
+++ b/SOURCES/Monitor-mailfrom-is-initialized-correctly.patch
@@ -0,0 +1,29 @@
+From 72362f18aee5adedb405fe61c324604184d74555 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 11 May 2017 16:44:19 -0400
+Subject: [RHEL7.5 PATCH 138/169] Monitor: mailfrom is initialized
+ correctly
+
+Remove gratituous variable initialization.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Monitor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index a4afe75..83a6d10 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -125,7 +125,7 @@ int Monitor(struct mddev_dev *devlist,
+ 	struct state *st2;
+ 	int finished = 0;
+ 	struct mdstat_ent *mdstat = NULL;
+-	char *mailfrom = NULL;
++	char *mailfrom;
+ 	struct alert_info info;
+ 	struct mddev_ident *mdlist;
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/Query-Handle-error-returned-by-fstat.patch b/SOURCES/Query-Handle-error-returned-by-fstat.patch
new file mode 100644
index 0000000..9b887da
--- /dev/null
+++ b/SOURCES/Query-Handle-error-returned-by-fstat.patch
@@ -0,0 +1,72 @@
+From 8d0cd09d73a9a9d57ee73b7a79114e881dad1507 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 13 Apr 2017 11:53:21 -0400
+Subject: [RHEL7.5 PATCH 079/169] Query: Handle error returned by fstat()
+
+We shouldn't ignore any error returned by fstat() even if open() didn't
+fail.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Query.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/Query.c b/Query.c
+index bea273f..0d18da4 100644
+--- a/Query.c
++++ b/Query.c
+@@ -32,22 +32,21 @@ int Query(char *dev)
+ 	 * whether it is an md device and whether it has
+ 	 * a superblock
+ 	 */
+-	int fd = open(dev, O_RDONLY);
+-	int ioctlerr;
++	int fd;
++	int ioctlerr, staterr;
+ 	int superror;
+ 	struct mdinfo info;
+ 	mdu_array_info_t array;
+ 	struct supertype *st = NULL;
+-
+ 	unsigned long long larray_size;
+ 	struct stat stb;
+ 	char *mddev;
+ 	mdu_disk_info_t disc;
+ 	char *activity;
+ 
++	fd = open(dev, O_RDONLY);
+ 	if (fd < 0){
+-		pr_err("cannot open %s: %s\n",
+-			dev, strerror(errno));
++		pr_err("cannot open %s: %s\n", dev, strerror(errno));
+ 		return 1;
+ 	}
+ 
+@@ -56,9 +55,12 @@ int Query(char *dev)
+ 	else
+ 		ioctlerr = 0;
+ 
+-	fstat(fd, &stb);
++	if (fstat(fd, &stb) < 0)
++		staterr = errno;
++	else
++		staterr = 0;
+ 
+-	if (!ioctlerr) {
++	if (!ioctlerr && !staterr) {
+ 		if (!get_dev_size(fd, NULL, &larray_size))
+ 			larray_size = 0;
+ 	}
+@@ -68,6 +70,9 @@ int Query(char *dev)
+ 	else if (ioctlerr)
+ 		printf("%s: is an md device, but gives \"%s\" when queried\n",
+ 		       dev, strerror(ioctlerr));
++	else if (staterr)
++		printf("%s: is not a valid md device, returning %s\n",
++		       dev, strerror(ioctlerr));
+ 	else {
+ 		printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n",
+ 		       dev,
+-- 
+2.7.4
+
diff --git a/SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch b/SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch
new file mode 100644
index 0000000..db4cfbb
--- /dev/null
+++ b/SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch
@@ -0,0 +1,28 @@
+From 0dfff0f24355ad4b5c1776f7f19a404ffae25415 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 21 Apr 2017 12:04:05 -0400
+Subject: [RHEL7.5 PATCH 090/169] Query: Quiet gcc since it cannot know
+ errno != 0 in this case
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Query.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/Query.c b/Query.c
+index 4dec9f5..2bd0e2a 100644
+--- a/Query.c
++++ b/Query.c
+@@ -68,6 +68,9 @@ int Query(char *dev)
+ 
+ 		if (md_get_array_info(fd, &array) < 0) {
+ 			ioctlerr = errno;
++			level = -1;
++			raid_disks = -1;
++			spare_disks = -1;
+ 		} else {
+ 			level = array.level;
+ 			raid_disks = array.raid_disks;
+-- 
+2.7.4
+
diff --git a/SOURCES/Query-Remove-all-references-to-md_get_version.patch b/SOURCES/Query-Remove-all-references-to-md_get_version.patch
new file mode 100644
index 0000000..58a65a2
--- /dev/null
+++ b/SOURCES/Query-Remove-all-references-to-md_get_version.patch
@@ -0,0 +1,65 @@
+From 5cb859962febacba3bb9257fc6ed9553ecc16752 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:37:38 -0400
+Subject: [RHEL7.5 PATCH 060/169] Query: Remove all references to
+ md_get_version()
+
+More legacy code removed
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Query.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/Query.c b/Query.c
+index a2c839c..bea273f 100644
+--- a/Query.c
++++ b/Query.c
+@@ -33,7 +33,6 @@ int Query(char *dev)
+ 	 * a superblock
+ 	 */
+ 	int fd = open(dev, O_RDONLY);
+-	int vers;
+ 	int ioctlerr;
+ 	int superror;
+ 	struct mdinfo info;
+@@ -52,7 +51,6 @@ int Query(char *dev)
+ 		return 1;
+ 	}
+ 
+-	vers = md_get_version(fd);
+ 	if (md_get_array_info(fd, &array) < 0)
+ 		ioctlerr = errno;
+ 	else
+@@ -60,16 +58,12 @@ int Query(char *dev)
+ 
+ 	fstat(fd, &stb);
+ 
+-	if (vers>=9000 && !ioctlerr) {
++	if (!ioctlerr) {
+ 		if (!get_dev_size(fd, NULL, &larray_size))
+ 			larray_size = 0;
+ 	}
+ 
+-	if (vers < 0)
+-		printf("%s: is not an md array\n", dev);
+-	else if (vers < 9000)
+-		printf("%s: is an md device, but kernel cannot provide details\n", dev);
+-	else if (ioctlerr == ENODEV)
++	if (ioctlerr == ENODEV)
+ 		printf("%s: is an md device which is not active\n", dev);
+ 	else if (ioctlerr)
+ 		printf("%s: is an md device, but gives \"%s\" when queried\n",
+@@ -100,8 +94,7 @@ int Query(char *dev)
+ 			disc.number = info.disk.number;
+ 			activity = "undetected";
+ 			if (mddev && (fd = open(mddev, O_RDONLY))>=0) {
+-				if (md_get_version(fd) >= 9000 &&
+-				    md_get_array_info(fd, &array) >= 0) {
++				if (md_get_array_info(fd, &array) >= 0) {
+ 					if (md_get_disk_info(fd, &disc) >= 0 &&
+ 					    makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev)
+ 						activity = "active";
+-- 
+2.7.4
+
diff --git a/SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch b/SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch
new file mode 100644
index 0000000..f3b783a
--- /dev/null
+++ b/SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch
@@ -0,0 +1,80 @@
+From f22d6cde7c7e4be38230ac4c51c3af850ed1614e Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 13 Apr 2017 12:20:46 -0400
+Subject: [RHEL7.5 PATCH 080/169] Query: Use sysfs to obtain data if
+ possible
+
+Use sysfs to obtain leve, raid_disks, and spare_disks. If sysfs fails,
+fall back to calling the ioctl via md_get_array_info().
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Query.c | 32 ++++++++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/Query.c b/Query.c
+index 0d18da4..b761c47 100644
+--- a/Query.c
++++ b/Query.c
+@@ -35,7 +35,9 @@ int Query(char *dev)
+ 	int fd;
+ 	int ioctlerr, staterr;
+ 	int superror;
++	int level, raid_disks, spare_disks;
+ 	struct mdinfo info;
++	struct mdinfo *sra;
+ 	mdu_array_info_t array;
+ 	struct supertype *st = NULL;
+ 	unsigned long long larray_size;
+@@ -50,16 +52,28 @@ int Query(char *dev)
+ 		return 1;
+ 	}
+ 
+-	if (md_get_array_info(fd, &array) < 0)
+-		ioctlerr = errno;
+-	else
+-		ioctlerr = 0;
+-
+ 	if (fstat(fd, &stb) < 0)
+ 		staterr = errno;
+ 	else
+ 		staterr = 0;
+ 
++	ioctlerr = 0;
++
++	sra = sysfs_read(fd, dev, GET_DISKS | GET_LEVEL | GET_DEVS | GET_STATE);
++	if (sra) {
++		level = sra->array.level;
++		raid_disks = sra->array.raid_disks;
++		spare_disks = sra->array.spare_disks;
++	} else {
++		if (md_get_array_info(fd, &array) < 0) {
++			ioctlerr = errno;
++		} else {
++			level = array.level;
++			raid_disks = array.raid_disks;
++			spare_disks = array.spare_disks;
++		}
++	}
++
+ 	if (!ioctlerr && !staterr) {
+ 		if (!get_dev_size(fd, NULL, &larray_size))
+ 			larray_size = 0;
+@@ -75,11 +89,9 @@ int Query(char *dev)
+ 		       dev, strerror(ioctlerr));
+ 	else {
+ 		printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n",
+-		       dev,
+-		       human_size_brief(larray_size,IEC),
+-		       map_num(pers, array.level),
+-		       array.raid_disks,
+-		       array.spare_disks, array.spare_disks==1?"":"s");
++		       dev, human_size_brief(larray_size,IEC),
++		       map_num(pers, level), raid_disks,
++		       spare_disks, spare_disks == 1 ? "" : "s");
+ 	}
+ 	st = guess_super(fd);
+ 	if (st && st->ss->compare_super != NULL)
+-- 
+2.7.4
+
diff --git a/SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch b/SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch
new file mode 100644
index 0000000..5a63e20
--- /dev/null
+++ b/SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch
@@ -0,0 +1,58 @@
+From 618f4e6d63c8c09d8d4002770e44617f3477f137 Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Sat, 18 Mar 2017 10:33:44 +0800
+Subject: [RHEL7.5 PATCH 015/169] Replace snprintf with strncpy at some
+ places to avoid truncation
+
+In gcc7 there are some building errors like:
+directive output may be truncated writing up to 31 bytes into a region of size 24
+snprintf(str, MPB_SIG_LEN, %s, mpb->sig);
+
+It just need to copy one string to target. So use strncpy to replace it.
+
+For this line code: snprintf(str, MPB_SIG_LEN, %s, mpb->sig);
+Because mpb->sig has the content of version after magic, so
+it's better to use strncpy to replace snprintf too.
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ super-intel.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index d5e9517..343f20d 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1811,7 +1811,8 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
+ 	__u32 reserved = imsm_reserved_sectors(super, super->disks);
+ 	struct dl *dl;
+ 
+-	snprintf(str, MPB_SIG_LEN, "%s", mpb->sig);
++	strncpy(str, (char *)mpb->sig, MPB_SIG_LEN);
++	str[MPB_SIG_LEN-1] = '\0';
+ 	printf("          Magic : %s\n", str);
+ 	snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb));
+ 	printf("        Version : %s\n", get_imsm_version(mpb));
+@@ -7142,14 +7143,16 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
+ 
+ 			u->type = update_rename_array;
+ 			u->dev_idx = vol;
+-			snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name);
++			strncpy((char *) u->name, name, MAX_RAID_SERIAL_LEN);
++			u->name[MAX_RAID_SERIAL_LEN-1] = '\0';
+ 			append_metadata_update(st, u, sizeof(*u));
+ 		} else {
+ 			struct imsm_dev *dev;
+ 			int i;
+ 
+ 			dev = get_imsm_dev(super, vol);
+-			snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
++			strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
++			dev->volume[MAX_RAID_SERIAL_LEN-1] = '\0';
+ 			for (i = 0; i < mpb->num_raid_devs; i++) {
+ 				dev = get_imsm_dev(super, i);
+ 				handle_missing(super, dev);
+-- 
+2.7.4
+
diff --git a/SOURCES/Retire-mdassemble.patch b/SOURCES/Retire-mdassemble.patch
new file mode 100644
index 0000000..9669b3d
--- /dev/null
+++ b/SOURCES/Retire-mdassemble.patch
@@ -0,0 +1,1396 @@
+From 32141c1765967e37d6f1accdf124c166bc103c3b Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 11 Apr 2017 12:54:26 -0400
+Subject: [RHEL7.5 PATCH 070/169] Retire mdassemble
+
+mdassemble doesn't handle container based arrays, no support for sysfs,
+etc. It has not been actively maintained for years, so time to send it
+off to retirement.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c    | 21 +++-------------
+ Makefile      | 37 ----------------------------
+ Manage.c      | 10 +-------
+ Monitor.c     |  3 ---
+ mdassemble.c  | 79 -----------------------------------------------------------
+ super-ddf.c   | 30 -----------------------
+ super-gpt.c   |  6 -----
+ super-intel.c | 52 +--------------------------------------
+ super-mbr.c   |  8 ------
+ super0.c      | 11 ---------
+ super1.c      | 21 +++-------------
+ util.c        | 37 +++-------------------------
+ 12 files changed, 12 insertions(+), 303 deletions(-)
+ delete mode 100644 mdassemble.c
+
+diff --git a/Assemble.c b/Assemble.c
+index 0db428f..b828523 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -222,13 +222,11 @@ static int select_devices(struct mddev_dev *devlist,
+ 					pr_err("%s is a container, but we are looking for components\n",
+ 					       devname);
+ 				tmpdev->used = 2;
+-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
+ 			} if (!tst && (tst = super_by_fd(dfd, NULL)) == NULL) {
+ 				if (report_mismatch)
+ 					pr_err("not a recognisable container: %s\n",
+ 					       devname);
+ 				tmpdev->used = 2;
+-#endif
+ 			} else if (!tst->ss->load_container
+ 				   || tst->ss->load_container(tst, dfd, NULL)) {
+ 				if (report_mismatch)
+@@ -574,9 +572,7 @@ static int load_devices(struct devs *devices, char *devmap,
+ 	struct mddev_dev *tmpdev;
+ 	int devcnt = 0;
+ 	int nextspare = 0;
+-#ifndef MDASSEMBLE
+ 	int bitmap_done = 0;
+-#endif
+ 	int most_recent = -1;
+ 	int bestcnt = 0;
+ 	int *best = *bestp;
+@@ -592,7 +588,6 @@ static int load_devices(struct devs *devices, char *devmap,
+ 		if (tmpdev->used != 1)
+ 			continue;
+ 		/* looks like a good enough match to update the super block if needed */
+-#ifndef MDASSEMBLE
+ 		if (c->update) {
+ 			/* prepare useful information in info structures */
+ 			struct stat stb2;
+@@ -683,9 +678,7 @@ static int load_devices(struct devs *devices, char *devmap,
+ 				else
+ 					bitmap_done = 1;
+ 			}
+-		} else
+-#endif
+-		{
++		} else {
+ 			dfd = dev_open(devname,
+ 				       tmpdev->disposition == 'I'
+ 				       ? O_RDWR : (O_RDWR|O_EXCL));
+@@ -1097,7 +1090,6 @@ static int start_array(int mdfd,
+ 		 * it read-only and let the grow code make it writable.
+ 		 */
+ 		int rv;
+-#ifndef MDASSEMBLE
+ 		if (content->reshape_active &&
+ 		    !(content->reshape_active & RESHAPE_NO_BACKUP) &&
+ 		    content->delta_disks <= 0) {
+@@ -1122,7 +1114,6 @@ static int start_array(int mdfd,
+ 			rv = sysfs_set_str(content, NULL,
+ 					   "array_state", "readonly");
+ 		} else
+-#endif
+ 			rv = ioctl(mdfd, RUN_ARRAY, NULL);
+ 		reopen_mddev(mdfd); /* drop O_EXCL */
+ 		if (rv == 0) {
+@@ -1506,7 +1497,6 @@ try_again:
+ 		ioctl(mdfd, STOP_ARRAY, NULL);
+ 	}
+ 
+-#ifndef MDASSEMBLE
+ 	if (content != &info) {
+ 		/* This is a member of a container.  Try starting the array. */
+ 		int err;
+@@ -1515,7 +1505,7 @@ try_again:
+ 		close(mdfd);
+ 		return err;
+ 	}
+-#endif
++
+ 	/* Ok, no bad inconsistancy, we can try updating etc */
+ 	devices = xcalloc(num_devs, sizeof(*devices));
+ 	devmap = xcalloc(num_devs, content->array.raid_disks);
+@@ -1668,14 +1658,13 @@ try_again:
+ 		return 1;
+ 	}
+ 	st->ss->getinfo_super(st, content, NULL);
+-#ifndef MDASSEMBLE
+ 	if (sysfs_init(content, mdfd, NULL)) {
+ 		pr_err("Unable to initialize sysfs\n");
+ 		close(mdfd);
+ 		free(devices);
+ 		return 1;
+ 	}
+-#endif
++
+ 	/* after reload context, store journal_clean in context */
+ 	content->journal_clean = journal_clean;
+ 	for (i=0; i<bestcnt; i++) {
+@@ -1761,7 +1750,6 @@ try_again:
+ 	 * that was moved aside due to the reshape overwriting live data
+ 	 * The code of doing this lives in Grow.c
+ 	 */
+-#ifndef MDASSEMBLE
+ 	if (content->reshape_active &&
+ 	    !(content->reshape_active & RESHAPE_NO_BACKUP)) {
+ 		int err = 0;
+@@ -1813,7 +1801,6 @@ try_again:
+ 			return err;
+ 		}
+ 	}
+-#endif
+ 
+ 	/* Almost ready to actually *do* something */
+ 	/* First, fill in the map, so that udev can find our name
+@@ -1876,7 +1863,6 @@ try_again:
+ 	return rv == 2 ? 0 : rv;
+ }
+ 
+-#ifndef MDASSEMBLE
+ int assemble_container_content(struct supertype *st, int mdfd,
+ 			       struct mdinfo *content, struct context *c,
+ 			       char *chosen_name, int *result)
+@@ -2119,4 +2105,3 @@ int assemble_container_content(struct supertype *st, int mdfd,
+ 	return err;
+ 	/* FIXME should have an O_EXCL and wait for read-auto */
+ }
+-#endif
+diff --git a/Makefile b/Makefile
+index 5ff6cc0..a5d2a0a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -158,18 +158,6 @@ MON_SRCS = $(patsubst %.o,%.c,$(MON_OBJS))
+ STATICSRC = pwgr.c
+ STATICOBJS = pwgr.o
+ 
+-ASSEMBLE_SRCS := mdassemble.c Assemble.c Manage.c config.c policy.c dlink.c util.c \
+-	maps.c lib.c xmalloc.c \
+-	super0.c super1.c super-ddf.c super-intel.c sha1.c crc32.c sg_io.c mdstat.c \
+-	platform-intel.c probe_roms.c sysfs.c super-mbr.c super-gpt.c mapfile.c \
+-	crc32c.c
+-ASSEMBLE_AUTO_SRCS := mdopen.c
+-ASSEMBLE_FLAGS:= $(CFLAGS) -DMDASSEMBLE
+-ifdef MDASSEMBLE_AUTO
+-ASSEMBLE_SRCS += $(ASSEMBLE_AUTO_SRCS)
+-ASSEMBLE_FLAGS += -DMDASSEMBLE_AUTO
+-endif
+-
+ all : mdadm mdmon
+ man : mdadm.man md.man mdadm.conf.man mdmon.man raid6check.man
+ 
+@@ -222,31 +210,6 @@ test_stripe : restripe.c xmalloc.o mdadm.h
+ raid6check : raid6check.o mdadm.h $(CHECK_OBJS)
+ 	$(CC) $(CXFLAGS) $(LDFLAGS) -o raid6check raid6check.o $(CHECK_OBJS)
+ 
+-mdassemble : $(ASSEMBLE_SRCS) $(INCL)
+-	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS)  $(STATICSRC)
+-
+-mdassemble.diet : $(ASSEMBLE_SRCS) $(INCL)
+-	rm -f $(OBJS)
+-	$(DIET_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS)  $(STATICSRC)
+-
+-mdassemble.static : $(ASSEMBLE_SRCS) $(INCL)
+-	rm -f $(OBJS)
+-	$(CC) $(LDFLAGS) $(CPPFLAGS) $(ASSEMBLE_FLAGS) -static -DHAVE_STDINT_H -o mdassemble.static $(ASSEMBLE_SRCS) $(STATICSRC)
+-
+-mdassemble.auto : $(ASSEMBLE_SRCS) $(INCL) $(ASSEMBLE_AUTO_SRCS)
+-	rm -f mdassemble.static
+-	$(MAKE) MDASSEMBLE_AUTO=1 mdassemble.static
+-	mv mdassemble.static mdassemble.auto
+-
+-mdassemble.uclibc : $(ASSEMBLE_SRCS) $(INCL)
+-	rm -f $(OJS)
+-	$(UCLIBC_GCC) $(ASSEMBLE_FLAGS) -DUCLIBC -DHAVE_STDINT_H -static -o mdassemble.uclibc $(ASSEMBLE_SRCS) $(STATICSRC)
+-
+-# This doesn't work
+-mdassemble.klibc : $(ASSEMBLE_SRCS) $(INCL)
+-	rm -f $(OBJS)
+-	$(KLIBC_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS)
+-
+ mdadm.8 : mdadm.8.in
+ 	sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' \
+ 	-e 's,{MAP_PATH},$(MAP_PATH),g'  mdadm.8.in > mdadm.8
+diff --git a/Manage.c b/Manage.c
+index 9e69132..bb84d28 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -41,12 +41,9 @@ int Manage_ro(char *devname, int fd, int readonly)
+ 	 *
+ 	 */
+ 	mdu_array_info_t array;
+-#ifndef MDASSEMBLE
+ 	struct mdinfo *mdi;
+-#endif
+ 	int rv = 0;
+ 
+-#ifndef MDASSEMBLE
+ 	/* If this is an externally-managed array, we need to modify the
+ 	 * metadata_version so that mdmon doesn't undo our change.
+ 	 */
+@@ -90,7 +87,7 @@ int Manage_ro(char *devname, int fd, int readonly)
+ 		}
+ 		goto out;
+ 	}
+-#endif
++
+ 	if (md_get_array_info(fd, &array)) {
+ 		pr_err("%s does not appear to be active.\n",
+ 			devname);
+@@ -114,14 +111,10 @@ int Manage_ro(char *devname, int fd, int readonly)
+ 		}
+ 	}
+ out:
+-#ifndef MDASSEMBLE
+ 	sysfs_free(mdi);
+-#endif
+ 	return rv;
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static void remove_devices(char *devnm, char *path)
+ {
+ 	/*
+@@ -1802,4 +1795,3 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
+ 	close(fd2);
+ 	return 0;
+ }
+-#endif
+diff --git a/Monitor.c b/Monitor.c
+index 036a561..1f15377 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -1058,8 +1058,6 @@ int Wait(char *dev)
+ 	}
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static char *clean_states[] = {
+ 	"clear", "inactive", "readonly", "read-auto", "clean", NULL };
+ 
+@@ -1151,4 +1149,3 @@ int WaitClean(char *dev, int sock, int verbose)
+ 
+ 	return rv;
+ }
+-#endif /* MDASSEMBLE */
+diff --git a/mdassemble.c b/mdassemble.c
+deleted file mode 100644
+index f0833bc..0000000
+--- a/mdassemble.c
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/*
+- * mdassemble - assemble Linux "md" devices aka RAID arrays.
+- *
+- * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
+- * Copyright (C) 2003 Luca Berra <bluca@vodka.it>
+- *
+- *
+- *    This program is free software; you can redistribute it and/or modify
+- *    it under the terms of the GNU General Public License as published by
+- *    the Free Software Foundation; either version 2 of the License, or
+- *    (at your option) any later version.
+- *
+- *    This program is distributed in the hope that it will be useful,
+- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- *    GNU General Public License for more details.
+- *
+- *    You should have received a copy of the GNU General Public License
+- *    along with this program; if not, write to the Free Software
+- *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+- *
+- *    Author: Neil Brown
+- *    Email: <neilb@suse.de>
+- */
+-
+-#include "mdadm.h"
+-#include "md_p.h"
+-
+-char const Name[] = "mdassemble";
+-
+-#ifndef MDASSEMBLE_AUTO
+-/* from mdopen.c */
+-int open_mddev(char *dev, int report_errors/*unused*/)
+-{
+-	struct mdu_array_info_s array;
+-	int mdfd = open(dev, O_RDONLY);
+-	if (mdfd < 0)
+-		pr_err("error opening %s: %s\n", dev, strerror(errno));
+-	else if (md_get_array_info(mdfd, &array) != 0) {
+-		pr_err("%s does not appear to be an md device\n", dev);
+-		close(mdfd);
+-		mdfd = -1;
+-	}
+-	return mdfd;
+-}
+-int create_mddev(char *dev, char *name, int autof/*unused*/, int trustworthy,
+-		 char *chosen)
+-{
+-	return open_mddev(dev, 0);
+-}
+-#endif
+-
+-int rv;
+-int mdfd = -1;
+-
+-int main(int argc, char *argv[])
+-{
+-	struct mddev_ident *array_list =  conf_get_ident(NULL);
+-	struct context c = { .freeze_reshape = 1 };
+-	if (!array_list) {
+-		pr_err("No arrays found in config file\n");
+-		rv = 1;
+-	} else
+-		for (; array_list; array_list = array_list->next) {
+-			mdu_array_info_t array;
+-			if (strcasecmp(array_list->devname, "<ignore>") == 0)
+-				continue;
+-			mdfd = open_mddev(array_list->devname, 0);
+-			if (mdfd >= 0 && md_get_array_info(mdfd, &array) == 0) {
+-				rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */
+-				continue;
+-			}
+-			if (mdfd >= 0)
+-				close(mdfd);
+-			rv |= Assemble(array_list->st, array_list->devname,
+-				       array_list, NULL, &c);
+-		}
+-	return rv;
+-}
+diff --git a/super-ddf.c b/super-ddf.c
+index c6037c1..796eaa5 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -500,7 +500,6 @@ struct ddf_super {
+ 	} *dlist, *add_list;
+ };
+ 
+-#ifndef MDASSEMBLE
+ static int load_super_ddf_all(struct supertype *st, int fd,
+ 			      void **sbp, char *devname);
+ static int get_svd_state(const struct ddf_super *, const struct vcl *);
+@@ -518,7 +517,6 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
+ 				     unsigned long long data_offset,
+ 				     char *dev, unsigned long long *freesize,
+ 				     int verbose);
+-#endif
+ 
+ static void free_super_ddf(struct supertype *st);
+ static int all_ff(const char *guid);
+@@ -1305,8 +1303,6 @@ static struct supertype *match_metadata_desc_ddf(char *arg)
+ 	return st;
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static mapping_t ddf_state[] = {
+ 	{ "Optimal", 0},
+ 	{ "Degraded", 1},
+@@ -1355,7 +1351,6 @@ static mapping_t ddf_sec_level[] = {
+ 	{ "Spanned", DDF_2SPANNED},
+ 	{ NULL, 0}
+ };
+-#endif
+ 
+ static int all_ff(const char *guid)
+ {
+@@ -1382,7 +1377,6 @@ static const char *guid_str(const char *guid)
+ 	return (const char *) buf;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static void print_guid(char *guid, int tstamp)
+ {
+ 	/* A GUIDs are part (or all) ASCII and part binary.
+@@ -1748,7 +1742,6 @@ static void detail_super_ddf(struct supertype *st, char *homehost)
+ 	printf("     Virtual Disks : %d\n", cnt);
+ 	printf("\n");
+ }
+-#endif
+ 
+ static const char *vendors_with_variable_volume_UUID[] = {
+ 	"LSI      ",
+@@ -1795,7 +1788,6 @@ static void uuid_of_ddf_subarray(const struct ddf_super *ddf,
+ 	memcpy(uuid, sha, 4*4);
+ }
+ 
+-#ifndef MDASSEMBLE
+ static void brief_detail_super_ddf(struct supertype *st)
+ {
+ 	struct mdinfo info;
+@@ -1811,7 +1803,6 @@ static void brief_detail_super_ddf(struct supertype *st)
+ 	fname_from_uuid(st, &info, nbuf,':');
+ 	printf(" UUID=%s", nbuf + 5);
+ }
+-#endif
+ 
+ static int match_home_ddf(struct supertype *st, char *homehost)
+ {
+@@ -1833,7 +1824,6 @@ static int match_home_ddf(struct supertype *st, char *homehost)
+ 		ddf->controller.vendor_data[len] == 0);
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int find_index_in_bvd(const struct ddf_super *ddf,
+ 			     const struct vd_config *conf, unsigned int n,
+ 			     unsigned int *n_bvd)
+@@ -1914,7 +1904,6 @@ bad:
+ 	pr_err("Could't find disk %d in array %u\n", n, inst);
+ 	return NULL;
+ }
+-#endif
+ 
+ static int find_phys(const struct ddf_super *ddf, be32 phys_refnum)
+ {
+@@ -2274,7 +2263,6 @@ static unsigned int find_vde_by_name(const struct ddf_super *ddf,
+ 	return DDF_NOTFOUND;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static unsigned int find_vde_by_guid(const struct ddf_super *ddf,
+ 				     const char *guid)
+ {
+@@ -2286,7 +2274,6 @@ static unsigned int find_vde_by_guid(const struct ddf_super *ddf,
+ 			return i;
+ 	return DDF_NOTFOUND;
+ }
+-#endif
+ 
+ static int init_super_ddf(struct supertype *st,
+ 			  mdu_array_info_t *info,
+@@ -2507,7 +2494,6 @@ static int chunk_to_shift(int chunksize)
+ 	return ffs(chunksize/512)-1;
+ }
+ 
+-#ifndef MDASSEMBLE
+ struct extent {
+ 	unsigned long long start, size;
+ };
+@@ -2608,7 +2594,6 @@ static unsigned long long find_space(
+ 	free(e);
+ 	return INVALID_SECTORS;
+ }
+-#endif
+ 
+ static int init_super_ddf_bvd(struct supertype *st,
+ 			      mdu_array_info_t *info,
+@@ -2727,7 +2712,6 @@ static int init_super_ddf_bvd(struct supertype *st,
+ 	return 1;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static void add_to_super_ddf_bvd(struct supertype *st,
+ 				 mdu_disk_info_t *dk, int fd, char *devname,
+ 				 unsigned long long data_offset)
+@@ -3015,7 +2999,6 @@ static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk)
+ 	}
+ 	return 0;
+ }
+-#endif
+ 
+ /*
+  * This is the write_init_super method for a ddf container.  It is
+@@ -3176,7 +3159,6 @@ static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d)
+ 	return 1;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int __write_init_super_ddf(struct supertype *st)
+ {
+ 	struct ddf_super *ddf = st->sb;
+@@ -3259,8 +3241,6 @@ static int write_init_super_ddf(struct supertype *st)
+ 	}
+ }
+ 
+-#endif
+-
+ static __u64 avail_size_ddf(struct supertype *st, __u64 devsize,
+ 			    unsigned long long data_offset)
+ {
+@@ -3270,8 +3250,6 @@ static __u64 avail_size_ddf(struct supertype *st, __u64 devsize,
+ 	return devsize - 32*1024*2;
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static int reserve_space(struct supertype *st, int raiddisks,
+ 			 unsigned long long size, int chunk,
+ 			 unsigned long long data_offset,
+@@ -3653,8 +3631,6 @@ static int load_container_ddf(struct supertype *st, int fd,
+ 	return load_super_ddf_all(st, fd, &st->sb, devname);
+ }
+ 
+-#endif /* MDASSEMBLE */
+-
+ static int check_secondary(const struct vcl *vc)
+ {
+ 	const struct vd_config *conf = &vc->conf;
+@@ -4075,7 +4051,6 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst)
+ 	return 0;
+ }
+ 
+-#ifndef MDASSEMBLE
+ /*
+  * A new array 'a' has been started which claims to be instance 'inst'
+  * within container 'c'.
+@@ -5196,7 +5171,6 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
+ 	*updates = mu;
+ 	return rv;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ static int ddf_level_to_layout(int level)
+ {
+@@ -5225,7 +5199,6 @@ static void default_geometry_ddf(struct supertype *st, int *level, int *layout,
+ }
+ 
+ struct superswitch super_ddf = {
+-#ifndef	MDASSEMBLE
+ 	.examine_super	= examine_super_ddf,
+ 	.brief_examine_super = brief_examine_super_ddf,
+ 	.brief_examine_subarrays = brief_examine_subarrays_ddf,
+@@ -5239,7 +5212,6 @@ struct superswitch super_ddf = {
+ 	.load_container	= load_container_ddf,
+ 	.copy_metadata = copy_metadata_ddf,
+ 	.kill_subarray  = kill_subarray_ddf,
+-#endif
+ 	.match_home	= match_home_ddf,
+ 	.uuid_from_super= uuid_from_super_ddf,
+ 	.getinfo_super  = getinfo_super_ddf,
+@@ -5259,7 +5231,6 @@ struct superswitch super_ddf = {
+ 
+ 	.external	= 1,
+ 
+-#ifndef MDASSEMBLE
+ /* for mdmon */
+ 	.open_new       = ddf_open_new,
+ 	.set_array_state= ddf_set_array_state,
+@@ -5268,6 +5239,5 @@ struct superswitch super_ddf = {
+ 	.process_update	= ddf_process_update,
+ 	.prepare_update	= ddf_prepare_update,
+ 	.activate_spare = ddf_activate_spare,
+-#endif
+ 	.name = "ddf",
+ };
+diff --git a/super-gpt.c b/super-gpt.c
+index bb38a97..a1e9aa9 100644
+--- a/super-gpt.c
++++ b/super-gpt.c
+@@ -47,7 +47,6 @@ static void free_gpt(struct supertype *st)
+ 	st->sb = NULL;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static void examine_gpt(struct supertype *st, char *homehost)
+ {
+ 	struct GPT *gpt = st->sb + 512;
+@@ -66,7 +65,6 @@ static void examine_gpt(struct supertype *st, char *homehost)
+ 			);
+ 	}
+ }
+-#endif /* MDASSEMBLE */
+ 
+ static int load_gpt(struct supertype *st, int fd, char *devname)
+ {
+@@ -199,7 +197,6 @@ static struct supertype *match_metadata_desc(char *arg)
+ 	return st;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int validate_geometry(struct supertype *st, int level,
+ 			     int layout, int raiddisks,
+ 			     int *chunk, unsigned long long size,
+@@ -210,13 +207,10 @@ static int validate_geometry(struct supertype *st, int level,
+ 	pr_err("gpt metadata cannot be used this way\n");
+ 	return 0;
+ }
+-#endif
+ 
+ struct superswitch gpt = {
+-#ifndef MDASSEMBLE
+ 	.examine_super = examine_gpt,
+ 	.validate_geometry = validate_geometry,
+-#endif
+ 	.match_metadata_desc = match_metadata_desc,
+ 	.load_super = load_gpt,
+ 	.store_super = store_gpt,
+diff --git a/super-intel.c b/super-intel.c
+index 84dfe2b..0aed57c 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -260,9 +260,7 @@ struct bbm_log {
+ 	struct bbm_log_entry marked_block_entries[BBM_LOG_MAX_ENTRIES];
+ } __attribute__ ((__packed__));
+ 
+-#ifndef MDASSEMBLE
+ static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" };
+-#endif
+ 
+ #define BLOCKS_PER_KB	(1024/512)
+ 
+@@ -672,12 +670,10 @@ static struct supertype *match_metadata_desc_imsm(char *arg)
+ 	return st;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static __u8 *get_imsm_version(struct imsm_super *mpb)
+ {
+ 	return &mpb->sig[MPB_SIG_LEN];
+ }
+-#endif
+ 
+ /* retrieve a disk directly from the anchor when the anchor is known to be
+  * up-to-date, currently only at load time
+@@ -784,7 +780,6 @@ static size_t sizeof_imsm_dev(struct imsm_dev *dev, int migr_state)
+ 	return size;
+ }
+ 
+-#ifndef MDASSEMBLE
+ /* retrieve disk serial number list from a metadata update */
+ static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
+ {
+@@ -796,7 +791,6 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
+ 
+ 	return inf;
+ }
+-#endif
+ 
+ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
+ {
+@@ -847,7 +841,6 @@ static inline struct bbm_log_block_addr __cpu_to_le48(unsigned long long sec)
+ 	return addr;
+ }
+ 
+-#ifndef MDASSEMBLE
+ /* get size of the bbm log */
+ static __u32 get_imsm_bbm_log_size(struct bbm_log *log)
+ {
+@@ -978,7 +971,6 @@ static int clear_badblock(struct bbm_log *log, const __u8 idx, const unsigned
+ 
+ 	return 1;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ /* allocate and load BBM log from metadata */
+ static int load_bbm_log(struct intel_super *super)
+@@ -1423,7 +1415,6 @@ static int is_gen_migration(struct imsm_dev *dev);
+ 
+ #define IMSM_4K_DIV 8
+ 
+-#ifndef MDASSEMBLE
+ static __u64 blocks_per_migr_unit(struct intel_super *super,
+ 				  struct imsm_dev *dev);
+ 
+@@ -1698,7 +1689,6 @@ void examine_migr_rec_imsm(struct intel_super *super)
+ 		break;
+ 	}
+ }
+-#endif /* MDASSEMBLE */
+ 
+ void convert_from_4k_imsm_migr_rec(struct intel_super *super)
+ {
+@@ -1858,7 +1848,6 @@ static int imsm_check_attributes(__u32 attributes)
+ 	return ret_val;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map);
+ 
+ static void examine_super_imsm(struct supertype *st, char *homehost)
+@@ -2572,8 +2561,6 @@ static int export_detail_platform_imsm(int verbose, char *controller_path)
+ 	return result;
+ }
+ 
+-#endif
+-
+ static int match_home_imsm(struct supertype *st, char *homehost)
+ {
+ 	/* the imsm metadata format does not specify any host
+@@ -2984,7 +2971,6 @@ out:
+ 	return retval;
+ }
+ 
+-#ifndef MDASSEMBLE
+ /*******************************************************************************
+  * function: imsm_create_metadata_checkpoint_update
+  * Description: It creates update for checkpoint change.
+@@ -3125,7 +3111,6 @@ static int write_imsm_migr_rec(struct supertype *st)
+ 		close(fd);
+ 	return retval;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ /* spare/missing disks activations are not allowe when
+  * array/container performs reshape operation, because
+@@ -3396,7 +3381,6 @@ static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev,
+ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
+ 			     int look_in_map);
+ 
+-#ifndef MDASSEMBLE
+ static void manage_second_map(struct intel_super *super, struct imsm_dev *dev)
+ {
+ 	if (is_gen_migration(dev)) {
+@@ -3412,7 +3396,6 @@ static void manage_second_map(struct intel_super *super, struct imsm_dev *dev)
+ 		}
+ 	}
+ }
+-#endif
+ 
+ static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
+ {
+@@ -3994,7 +3977,6 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
+ 	return 0;
+ }
+ 
+-#ifndef MDASSEMBLE
+ /* When migrating map0 contains the 'destination' state while map1
+  * contains the current state.  When not migrating map0 contains the
+  * current state.  This routine assumes that map[0].map_state is set to
+@@ -4082,7 +4064,6 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super,
+ 	dev->vol.curr_migr_unit = 0;
+ 	map->map_state = map_state;
+ }
+-#endif
+ 
+ static int parse_raid_devices(struct intel_super *super)
+ {
+@@ -4528,7 +4509,6 @@ static int find_missing(struct intel_super *super)
+ 	return 0;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static struct intel_disk *disk_list_get(__u8 *serial, struct intel_disk *disk_list)
+ {
+ 	struct intel_disk *idisk = disk_list;
+@@ -5066,7 +5046,6 @@ static int load_container_imsm(struct supertype *st, int fd, char *devname)
+ {
+ 	return load_super_imsm_all(st, fd, &st->sb, devname, NULL, 1);
+ }
+-#endif
+ 
+ static int load_super_imsm(struct supertype *st, int fd, char *devname)
+ {
+@@ -5483,7 +5462,6 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
+ 	return 1;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
+ 				     int fd, char *devname)
+ {
+@@ -6028,7 +6006,6 @@ static int mgmt_disk(struct supertype *st)
+ 
+ 	return 0;
+ }
+-#endif
+ 
+ __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len);
+ 
+@@ -6136,8 +6113,6 @@ out:
+ 	return ret;
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static int write_init_ppl_imsm_all(struct supertype *st, struct mdinfo *info)
+ {
+ 	struct intel_super *super = st->sb;
+@@ -6199,7 +6174,6 @@ static int write_init_super_imsm(struct supertype *st)
+ 
+ 	return rv;
+ }
+-#endif
+ 
+ static int store_super_imsm(struct supertype *st, int fd)
+ {
+@@ -6209,16 +6183,11 @@ static int store_super_imsm(struct supertype *st, int fd)
+ 	if (!mpb)
+ 		return 1;
+ 
+-#ifndef MDASSEMBLE
+ 	if (super->sector_size == 4096)
+ 		convert_to_4k(super);
+ 	return store_imsm_mpb(fd, mpb);
+-#else
+-	return 1;
+-#endif
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int validate_geometry_imsm_container(struct supertype *st, int level,
+ 					    int layout, int raiddisks, int chunk,
+ 					    unsigned long long size,
+@@ -7433,7 +7402,6 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
+ 
+ 	return 0;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ static int is_gen_migration(struct imsm_dev *dev)
+ {
+@@ -7467,7 +7435,6 @@ static int is_rebuilding(struct imsm_dev *dev)
+ 		return 0;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int is_initializing(struct imsm_dev *dev)
+ {
+ 	struct imsm_map *migr_map;
+@@ -7485,7 +7452,6 @@ static int is_initializing(struct imsm_dev *dev)
+ 
+ 	return 0;
+ }
+-#endif
+ 
+ static void update_recovery_start(struct intel_super *super,
+ 					struct imsm_dev *dev,
+@@ -7519,9 +7485,7 @@ static void update_recovery_start(struct intel_super *super,
+ 	rebuild->recovery_start = units * blocks_per_migr_unit(super, dev);
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int recover_backup_imsm(struct supertype *st, struct mdinfo *info);
+-#endif
+ 
+ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarray)
+ {
+@@ -7560,9 +7524,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		struct imsm_map *map2;
+ 		struct mdinfo *this;
+ 		int slot;
+-#ifndef MDASSEMBLE
+ 		int chunk;
+-#endif
+ 		char *ep;
+ 
+ 		if (subarray &&
+@@ -7591,7 +7553,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		super->current_vol = i;
+ 		getinfo_super_imsm_volume(st, this, NULL);
+ 		this->next = rest;
+-#ifndef MDASSEMBLE
+ 		chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
+ 		/* mdadm does not support all metadata features- set the bit in all arrays state */
+ 		if (!validate_geometry_imsm_orom(super,
+@@ -7606,7 +7567,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 			  (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
+ 			  (1<<MD_SB_BLOCK_VOLUME);
+ 		}
+-#endif
+ 
+ 		/* if array has bad blocks, set suitable bit in all arrays state */
+ 		if (sb_errors)
+@@ -7697,11 +7657,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		update_recovery_start(super, dev, this);
+ 		this->array.spare_disks += spare_disks;
+ 
+-#ifndef MDASSEMBLE
+ 		/* check for reshape */
+ 		if (this->reshape_active == 1)
+ 			recover_backup_imsm(st, this);
+-#endif
+ 		rest = this;
+ 	}
+ 
+@@ -7831,7 +7789,6 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
+ 	return failed;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int imsm_open_new(struct supertype *c, struct active_array *a,
+ 			 char *inst)
+ {
+@@ -10003,7 +9960,6 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind
+ 		__free_imsm_disk(dl);
+ 	}
+ }
+-#endif /* MDASSEMBLE */
+ 
+ static void close_targets(int *targets, int new_disks)
+ {
+@@ -10206,7 +10162,7 @@ int validate_container_imsm(struct mdinfo *info)
+ 
+ 	return 0;
+ }
+-#ifndef MDASSEMBLE
++
+ /*******************************************************************************
+ * Function:   imsm_record_badblock
+ * Description: This routine stores new bad block record in BBM log
+@@ -11852,10 +11808,7 @@ abort:
+ 	return ret_val;
+ }
+ 
+-#endif /* MDASSEMBLE */
+-
+ struct superswitch super_imsm = {
+-#ifndef	MDASSEMBLE
+ 	.examine_super	= examine_super_imsm,
+ 	.brief_examine_super = brief_examine_super_imsm,
+ 	.brief_examine_subarrays = brief_examine_subarrays_imsm,
+@@ -11878,7 +11831,6 @@ struct superswitch super_imsm = {
+ 	.recover_backup = recover_backup_imsm,
+ 	.copy_metadata = copy_metadata_imsm,
+ 	.examine_badblocks = examine_badblocks_imsm,
+-#endif
+ 	.match_home	= match_home_imsm,
+ 	.uuid_from_super= uuid_from_super_imsm,
+ 	.getinfo_super  = getinfo_super_imsm,
+@@ -11904,7 +11856,6 @@ struct superswitch super_imsm = {
+ 	.external	= 1,
+ 	.name = "imsm",
+ 
+-#ifndef MDASSEMBLE
+ /* for mdmon */
+ 	.open_new	= imsm_open_new,
+ 	.set_array_state= imsm_set_array_state,
+@@ -11916,5 +11867,4 @@ struct superswitch super_imsm = {
+ 	.record_bad_block = imsm_record_badblock,
+ 	.clear_bad_block  = imsm_clear_badblock,
+ 	.get_bad_blocks   = imsm_get_badblocks,
+-#endif /* MDASSEMBLE */
+ };
+diff --git a/super-mbr.c b/super-mbr.c
+index 1bbe57a..839f000 100644
+--- a/super-mbr.c
++++ b/super-mbr.c
+@@ -48,8 +48,6 @@ static void free_mbr(struct supertype *st)
+ 	st->sb = NULL;
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static void examine_mbr(struct supertype *st, char *homehost)
+ {
+ 	struct MBR *sb = st->sb;
+@@ -71,8 +69,6 @@ static void examine_mbr(struct supertype *st, char *homehost)
+ 
+ }
+ 
+-#endif /*MDASSEMBLE */
+-
+ static int load_super_mbr(struct supertype *st, int fd, char *devname)
+ {
+ 	/* try to read an mbr
+@@ -187,7 +183,6 @@ static struct supertype *match_metadata_desc(char *arg)
+ 	return st;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int validate_geometry(struct supertype *st, int level,
+ 			     int layout, int raiddisks,
+ 			     int *chunk, unsigned long long size,
+@@ -198,13 +193,10 @@ static int validate_geometry(struct supertype *st, int level,
+ 	pr_err("mbr metadata cannot be used this way\n");
+ 	return 0;
+ }
+-#endif
+ 
+ struct superswitch mbr = {
+-#ifndef MDASSEMBLE
+ 	.examine_super = examine_mbr,
+ 	.validate_geometry = validate_geometry,
+-#endif
+ 	.match_metadata_desc = match_metadata_desc,
+ 	.load_super = load_super_mbr,
+ 	.store_super = store_mbr,
+diff --git a/super0.c b/super0.c
+index 10d9c40..dc13efb 100644
+--- a/super0.c
++++ b/super0.c
+@@ -76,8 +76,6 @@ static void super0_swap_endian(struct mdp_superblock_s *sb)
+ 
+ }
+ 
+-#ifndef MDASSEMBLE
+-
+ static void examine_super0(struct supertype *st, char *homehost)
+ {
+ 	mdp_super_t *sb = st->sb;
+@@ -380,7 +378,6 @@ static void brief_detail_super0(struct supertype *st)
+ 	else
+ 		printf("%08x", sb->set_uuid0);
+ }
+-#endif
+ 
+ static int match_home0(struct supertype *st, char *homehost)
+ {
+@@ -814,7 +811,6 @@ struct devinfo {
+ 	struct devinfo *next;
+ };
+ 
+-#ifndef MDASSEMBLE
+ /* Add a device to the superblock being created */
+ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
+ 			 int fd, char *devname, unsigned long long data_offset)
+@@ -845,7 +841,6 @@ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
+ 
+ 	return 0;
+ }
+-#endif
+ 
+ static int store_super0(struct supertype *st, int fd)
+ {
+@@ -899,7 +894,6 @@ static int store_super0(struct supertype *st, int fd)
+ 	return 0;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int write_init_super0(struct supertype *st)
+ {
+ 	mdp_super_t *sb = st->sb;
+@@ -930,7 +924,6 @@ static int write_init_super0(struct supertype *st)
+ 	}
+ 	return rv;
+ }
+-#endif
+ 
+ static int compare_super0(struct supertype *st, struct supertype *tst)
+ {
+@@ -1261,7 +1254,6 @@ static void free_super0(struct supertype *st)
+ 	st->sb = NULL;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int validate_geometry0(struct supertype *st, int level,
+ 			      int layout, int raiddisks,
+ 			      int *chunk, unsigned long long size,
+@@ -1320,10 +1312,8 @@ static int validate_geometry0(struct supertype *st, int level,
+ 	*freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9);
+ 	return 1;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ struct superswitch super0 = {
+-#ifndef MDASSEMBLE
+ 	.examine_super = examine_super0,
+ 	.brief_examine_super = brief_examine_super0,
+ 	.export_examine_super = export_examine_super0,
+@@ -1333,7 +1323,6 @@ struct superswitch super0 = {
+ 	.validate_geometry = validate_geometry0,
+ 	.add_to_super = add_to_super0,
+ 	.copy_metadata = copy_metadata0,
+-#endif
+ 	.match_home = match_home0,
+ 	.uuid_from_super = uuid_from_super0,
+ 	.getinfo_super = getinfo_super0,
+diff --git a/super1.c b/super1.c
+index 6f91611..4db4dff 100644
+--- a/super1.c
++++ b/super1.c
+@@ -152,7 +152,6 @@ struct misc_dev_info {
+ 					|MD_FEATURE_PPL			\
+ 					)
+ 
+-#ifndef MDASSEMBLE
+ static int role_from_sb(struct mdp_superblock_1 *sb)
+ {
+ 	unsigned int d;
+@@ -165,7 +164,6 @@ static int role_from_sb(struct mdp_superblock_1 *sb)
+ 		role = MD_DISK_ROLE_SPARE;
+ 	return role;
+ }
+-#endif
+ 
+ /* return how many bytes are needed for bitmap, for cluster-md each node
+  * should have it's own bitmap */
+@@ -304,7 +302,6 @@ static inline unsigned int choose_ppl_space(int chunk)
+ 	return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2);
+ }
+ 
+-#ifndef MDASSEMBLE
+ static void examine_super1(struct supertype *st, char *homehost)
+ {
+ 	struct mdp_superblock_1 *sb = st->sb;
+@@ -903,8 +900,6 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
+ 	return 0;
+ }
+ 
+-#endif
+-
+ static int match_home1(struct supertype *st, char *homehost)
+ {
+ 	struct mdp_superblock_1 *sb = st->sb;
+@@ -1276,7 +1271,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		long bm_sectors = 0;
+ 		long space;
+ 
+-#ifndef MDASSEMBLE
+ 		if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ 			bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
+ 			bm_sectors = calc_bitmap_size(bms, 4096) >> 9;
+@@ -1284,7 +1278,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset);
+ 			bm_sectors = (long)__le16_to_cpu(sb->ppl.size);
+ 		}
+-#endif
++
+ 		if (sb_offset < data_offset) {
+ 			/* 1.1 or 1.2.  Put bbl after bitmap leaving at least 32K
+ 			 */
+@@ -1578,7 +1572,7 @@ struct devinfo {
+ 	mdu_disk_info_t disk;
+ 	struct devinfo *next;
+ };
+-#ifndef MDASSEMBLE
++
+ /* Add a device to the superblock being created */
+ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 			 int fd, char *devname, unsigned long long data_offset)
+@@ -1634,7 +1628,6 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 
+ 	return 0;
+ }
+-#endif
+ 
+ static int locate_bitmap1(struct supertype *st, int fd, int node_num);
+ 
+@@ -1742,8 +1735,6 @@ static unsigned long choose_bm_space(unsigned long devsize)
+ 
+ static void free_super1(struct supertype *st);
+ 
+-#ifndef MDASSEMBLE
+-
+ __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len);
+ 
+ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
+@@ -2028,7 +2019,6 @@ error_out:
+ out:
+ 	return rv;
+ }
+-#endif
+ 
+ static int compare_super1(struct supertype *st, struct supertype *tst)
+ {
+@@ -2282,7 +2272,6 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
+ 	if (devsize < 24)
+ 		return 0;
+ 
+-#ifndef MDASSEMBLE
+ 	if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) {
+ 		/* hot-add. allow for actual size of bitmap */
+ 		struct bitmap_super_s *bsb;
+@@ -2291,7 +2280,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
+ 	} else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) {
+ 		bmspace = __le16_to_cpu(super->ppl.size);
+ 	}
+-#endif
++
+ 	/* Allow space for bad block log */
+ 	if (super->bblog_size)
+ 		bbspace = __le16_to_cpu(super->bblog_size);
+@@ -2644,7 +2633,6 @@ static void free_super1(struct supertype *st)
+ 	st->sb = NULL;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static int validate_geometry1(struct supertype *st, int level,
+ 			      int layout, int raiddisks,
+ 			      int *chunk, unsigned long long size,
+@@ -2740,7 +2728,6 @@ static int validate_geometry1(struct supertype *st, int level,
+ 	*freesize = devsize;
+ 	return 1;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0)
+ {
+@@ -2793,7 +2780,6 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0
+ }
+ 
+ struct superswitch super1 = {
+-#ifndef MDASSEMBLE
+ 	.examine_super = examine_super1,
+ 	.brief_examine_super = brief_examine_super1,
+ 	.export_examine_super = export_examine_super1,
+@@ -2806,7 +2792,6 @@ struct superswitch super1 = {
+ 	.examine_badblocks = examine_badblocks_super1,
+ 	.copy_metadata = copy_metadata1,
+ 	.write_init_ppl = write_init_ppl1,
+-#endif
+ 	.match_home = match_home1,
+ 	.uuid_from_super = uuid_from_super1,
+ 	.getinfo_super = getinfo_super1,
+diff --git a/util.c b/util.c
+index a536f81..a695c45 100644
+--- a/util.c
++++ b/util.c
+@@ -89,7 +89,6 @@ int dlm_funs_ready(void)
+ 	return is_dlm_hooks_ready ? 1 : 0;
+ }
+ 
+-#ifndef MDASSEMBLE
+ static struct dlm_hooks *dlm_hooks = NULL;
+ struct dlm_lock_resource *dlm_lock_res = NULL;
+ static int ast_called = 0;
+@@ -200,16 +199,6 @@ int cluster_release_dlmlock(int lockid)
+ out:
+ 	return ret;
+ }
+-#else
+-int cluster_get_dlmlock(int *lockid)
+-{
+-	return -1;
+-}
+-int cluster_release_dlmlock(int lockid)
+-{
+-	return -1;
+-}
+-#endif
+ 
+ /*
+  * Get array info from the kernel. Longer term we want to deprecate the
+@@ -291,7 +280,6 @@ int get_linux_version()
+ 	return (a*1000000)+(b*1000)+c;
+ }
+ 
+-#ifndef MDASSEMBLE
+ int mdadm_version(char *version)
+ {
+ 	int a, b, c;
+@@ -397,7 +385,6 @@ long parse_num(char *num)
+ 	else
+ 		return rv;
+ }
+-#endif
+ 
+ int parse_cluster_confirm_arg(char *input, char **devname, int *slot)
+ {
+@@ -639,7 +626,6 @@ char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char
+ 	return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : st->ss->swapuuid, buf, sep);
+ }
+ 
+-#ifndef MDASSEMBLE
+ int check_ext2(int fd, char *name)
+ {
+ 	/*
+@@ -743,7 +729,6 @@ int ask(char *mesg)
+ 	pr_err("assuming 'no'\n");
+ 	return 0;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ int is_standard(char *dev, int *nump)
+ {
+@@ -803,7 +788,6 @@ unsigned long calc_csum(void *super, int bytes)
+ 	return csum;
+ }
+ 
+-#ifndef MDASSEMBLE
+ char *human_size(long long bytes)
+ {
+ 	static char buf[47];
+@@ -895,7 +879,6 @@ void print_r10_layout(int layout)
+ 	if (near*far == 1)
+ 		printf("NO REDUNDANCY");
+ }
+-#endif
+ 
+ unsigned long long calc_array_size(int level, int raid_disks, int layout,
+ 				   int chunksize, unsigned long long devsize)
+@@ -962,7 +945,6 @@ dev_t devnm2devid(char *devnm)
+ 	return 0;
+ }
+ 
+-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
+ char *get_md_name(char *devnm)
+ {
+ 	/* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */
+@@ -1016,7 +998,6 @@ void put_md_name(char *name)
+ 	if (strncmp(name, "/dev/.tmp.md", 12) == 0)
+ 		unlink(name);
+ }
+-#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
+ 
+ int get_maj_min(char *dev, int *major, int *minor)
+ {
+@@ -1146,9 +1127,8 @@ struct superswitch *superlist[] =
+ 	&super0, &super1,
+ 	&super_ddf, &super_imsm,
+ 	&mbr, &gpt,
+-	NULL };
+-
+-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
++	NULL
++};
+ 
+ struct supertype *super_by_fd(int fd, char **subarrayp)
+ {
+@@ -1213,7 +1193,6 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
+ 
+ 	return st;
+ }
+-#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
+ 
+ int dev_size_from_id(dev_t id, unsigned long long *size)
+ {
+@@ -1753,7 +1732,7 @@ int add_disk(int mdfd, struct supertype *st,
+ {
+ 	/* Add a device to an array, in one of 2 ways. */
+ 	int rv;
+-#ifndef MDASSEMBLE
++
+ 	if (st->ss->external) {
+ 		if (info->disk.state & (1<<MD_DISK_SYNC))
+ 			info->recovery_start = MaxSector;
+@@ -1773,7 +1752,6 @@ int add_disk(int mdfd, struct supertype *st,
+ 			}
+ 		}
+ 	} else
+-#endif
+ 		rv = ioctl(mdfd, ADD_NEW_DISK, &info->disk);
+ 	return rv;
+ }
+@@ -1782,12 +1760,11 @@ int remove_disk(int mdfd, struct supertype *st,
+ 		struct mdinfo *sra, struct mdinfo *info)
+ {
+ 	int rv;
++
+ 	/* Remove the disk given by 'info' from the array */
+-#ifndef MDASSEMBLE
+ 	if (st->ss->external)
+ 		rv = sysfs_set_str(sra, info, "slot", "none");
+ 	else
+-#endif
+ 		rv = ioctl(mdfd, HOT_REMOVE_DISK, makedev(info->disk.major,
+ 							  info->disk.minor));
+ 	return rv;
+@@ -1832,10 +1809,8 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
+ 	mdu_array_info_t inf;
+ 	int rv;
+ 
+-#ifndef MDASSEMBLE
+ 	if (st->ss->external)
+ 		return sysfs_set_array(info, 9003);
+-#endif
+ 		
+ 	memset(&inf, 0, sizeof(inf));
+ 	inf.major_version = info->array.major_version;
+@@ -2015,7 +1990,6 @@ use_random:
+ 	memcpy(buf, r, 16);
+ }
+ 
+-#ifndef MDASSEMBLE
+ int flush_metadata_updates(struct supertype *st)
+ {
+ 	int sfd;
+@@ -2057,7 +2031,6 @@ void append_metadata_update(struct supertype *st, void *buf, int len)
+ 	*st->update_tail = mu;
+ 	st->update_tail = &mu->next;
+ }
+-#endif /* MDASSEMBLE */
+ 
+ #ifdef __TINYC__
+ /* tinyc doesn't optimize this check in ioctl.h out ... */
+@@ -2197,7 +2170,6 @@ void reopen_mddev(int mdfd)
+ 		dup2(fd, mdfd);
+ }
+ 
+-#ifndef MDASSEMBLE
+ static struct cmap_hooks *cmap_hooks = NULL;
+ static int is_cmap_hooks_ready = 0;
+ 
+@@ -2272,4 +2244,3 @@ void set_hooks(void)
+ 	set_dlm_hooks();
+ 	set_cmap_hooks();
+ }
+-#endif
+-- 
+2.7.4
+
diff --git a/SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch b/SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch
new file mode 100644
index 0000000..271fc4c
--- /dev/null
+++ b/SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch
@@ -0,0 +1,117 @@
+From 2dd271fe7041c2f7036939cf6917c0578b92fefe Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Mon, 27 Mar 2017 12:50:16 +1100
+Subject: [RHEL7.5 PATCH 020/169] Retry HOT_REMOVE_DISK a few times.
+
+HOT_REMOVE_DISK can fail with EBUSY if there are outstanding
+IO request that have not completed yet.  It can sometimes
+be helpful to wait a little while for these to complete.
+
+We already do this in impose_level() when reshaping a device,
+but not in Manage.c in response to an explicit --remove request.
+
+So create hot_remove_disk() to central this code, and call it
+where-ever it makes sense to wait for a HOT_REMOVE_DISK to succeed.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Grow.c   |  9 +--------
+ Manage.c |  4 ++--
+ mdadm.h  |  1 +
+ util.c   | 18 ++++++++++++++++++
+ 4 files changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/Grow.c b/Grow.c
+index 455c5f9..218a706 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -2736,7 +2736,6 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 		for (d = 0, found = 0;
+ 		     d < MAX_DISKS && found < array.nr_disks;
+ 		     d++) {
+-			int cnt;
+ 			mdu_disk_info_t disk;
+ 			disk.number = d;
+ 			if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
+@@ -2750,13 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 				continue;
+ 			ioctl(fd, SET_DISK_FAULTY,
+ 			      makedev(disk.major, disk.minor));
+-			cnt = 5;
+-			while (ioctl(fd, HOT_REMOVE_DISK,
+-				     makedev(disk.major, disk.minor)) < 0
+-			       && errno == EBUSY
+-			       && cnt--) {
+-				usleep(10000);
+-			}
++			hot_remove_disk(fd, makedev(disk.major, disk.minor));
+ 		}
+ 	}
+ 	c = map_num(pers, level);
+diff --git a/Manage.c b/Manage.c
+index 5c3d2b9..9139f96 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1183,7 +1183,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
+ 		else
+ 			err = 0;
+ 	} else {
+-		err = ioctl(fd, HOT_REMOVE_DISK, rdev);
++		err = hot_remove_disk(fd, rdev);
+ 		if (err && errno == ENODEV) {
+ 			/* Old kernels rejected this if no personality
+ 			 * is registered */
+@@ -1607,7 +1607,7 @@ int Manage_subdevs(char *devname, int fd,
+ 
+ 			if (dv->disposition == 'F')
+ 				/* Need to remove first */
+-				ioctl(fd, HOT_REMOVE_DISK, rdev);
++				hot_remove_disk(fd, rdev);
+ 			/* Make sure it isn't in use (in 2.6 or later) */
+ 			tfd = dev_open(dv->devname, O_RDONLY|O_EXCL);
+ 			if (tfd >= 0) {
+diff --git a/mdadm.h b/mdadm.h
+index 91fd9eb..5bcfb86 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1476,6 +1476,7 @@ extern int add_disk(int mdfd, struct supertype *st,
+ 		    struct mdinfo *sra, struct mdinfo *info);
+ extern int remove_disk(int mdfd, struct supertype *st,
+ 		       struct mdinfo *sra, struct mdinfo *info);
++extern int hot_remove_disk(int mdfd, unsigned long dev);
+ extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info);
+ unsigned long long min_recovery_start(struct mdinfo *array);
+ 
+diff --git a/util.c b/util.c
+index 32bd909..d09a7e2 100644
+--- a/util.c
++++ b/util.c
+@@ -1795,6 +1795,24 @@ int remove_disk(int mdfd, struct supertype *st,
+ 	return rv;
+ }
+ 
++int hot_remove_disk(int mdfd, unsigned long dev)
++{
++	int cnt = 5;
++	int ret;
++
++	/* HOT_REMOVE_DISK can fail with EBUSY if there are
++	 * outstanding IO requests to the device.
++	 * In this case, it can be helpful to wait a little while,
++	 * up to half a second, for that IO to flush.
++	 */
++	while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 &&
++	       errno == EBUSY &&
++	       cnt-- > 0)
++		usleep(10000);
++
++	return ret;
++}
++
+ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
+ {
+ 	/* Initialise kernel's knowledge of array.
+-- 
+2.7.4
+
diff --git a/SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch b/SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch
new file mode 100644
index 0000000..2b0e01e
--- /dev/null
+++ b/SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch
@@ -0,0 +1,32 @@
+From 2cfe6f7c646ebc25043f7607f5756edad0bc3071 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Tue, 11 Apr 2017 11:30:23 -0400
+Subject: [RHEL7.5 PATCH 069/169] Revert "mdadm/grow: reshape would be
+ stuck from raid1 to raid5"
+
+This reverts commit 5b2846684ef5172eccc432e3520b79efbc2abba5.
+
+This was a red herring and shouldn't have been applied in the first
+place.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ systemd/mdadm-grow-continue@.service | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
+index 882bc0b..5c667d2 100644
+--- a/systemd/mdadm-grow-continue@.service
++++ b/systemd/mdadm-grow-continue@.service
+@@ -10,7 +10,7 @@ Description=Manage MD Reshape on /dev/%I
+ DefaultDependencies=no
+ 
+ [Service]
+-ExecStart=BINDIR/mdadm --grow --continue /dev/%i
++ExecStart=BINDIR/mdadm --grow --continue /dev/%I
+ StandardInput=null
+ StandardOutput=null
+ StandardError=null
+-- 
+2.7.4
+
diff --git a/SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch b/SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch
new file mode 100644
index 0000000..a80d6f1
--- /dev/null
+++ b/SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch
@@ -0,0 +1,49 @@
+From ceb5f8ef92c97d1f44c75a3b74f64aa12a3303ef Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 4 Aug 2017 15:30:02 +1000
+Subject: [RHEL7.5 PATCH 165/169] Use correct syntax for passing DEVLINKS
+ to mdadm from udev
+
+ ${DEVLINKS}
+is not valid udev syntax, and is passed through uninterpreted.
+ $env{DEVLINKS}
+or
+  %e{DEVLINKS}
+is correct.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in                  | 2 +-
+ udev-md-raid-assembly.rules | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 461c5de..e0747fb 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -2947,7 +2947,7 @@ This is the only context where the aliases are used.  They are
+ usually provided by a
+ .I udev
+ rules mentioning
+-.BR ${DEVLINKS} .
++.BR $env{DEVLINKS} .
+ 
+ .IP +
+ Does the device have a valid md superblock?  If a specific metadata
+diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
+index 8ca232a..9f055ed 100644
+--- a/udev-md-raid-assembly.rules
++++ b/udev-md-raid-assembly.rules
+@@ -30,7 +30,7 @@ LABEL="md_inc"
+ 
+ # remember you can limit what gets auto/incrementally assembled by
+ # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
+-ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot ${DEVLINKS}"
++ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
+ ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
+ ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}"
+ ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name"
+-- 
+2.7.4
+
diff --git a/SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch b/SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch
new file mode 100644
index 0000000..4b284ec
--- /dev/null
+++ b/SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch
@@ -0,0 +1,134 @@
+From b251424242b46d62f666829c0e7a7550768fc8de Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:11 +0200
+Subject: [PATCH 05/12] Zeroout whole ppl space during creation/force
+ assemble
+
+PPL area should be cleared before creation/force assemble.
+If the drive was used in other RAID array, it might contains PPL from it.
+There is a risk that mdadm recognizes those PPLs and
+refuses to assemble the RAID due to PPL conflict with created
+array.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.h       |  1 +
+ super-intel.c |  7 ++++++-
+ super1.c      |  5 +++++
+ util.c        | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 61 insertions(+), 1 deletion(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index 3fc8a4f..85947bf 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -687,6 +687,7 @@ extern int sysfs_unique_holder(char *devnm, long rdev);
+ extern int sysfs_freeze_array(struct mdinfo *sra);
+ extern int sysfs_wait(int fd, int *msec);
+ extern int load_sys(char *path, char *buf, int len);
++extern int zero_disk_range(int fd, unsigned long long sector, size_t count);
+ extern int reshape_prepare_fdlist(char *devname,
+ 				  struct mdinfo *sra,
+ 				  int raid_disks,
+diff --git a/super-intel.c b/super-intel.c
+index 56dec36..65cdc92 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6065,7 +6065,12 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd
+ 	struct ppl_header *ppl_hdr;
+ 	int ret;
+ 
+-	ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
++	/* first clear entire ppl space */
++	ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size);
++	if (ret)
++		return ret;
++
++	ret = posix_memalign(&buf, MAX_SECTOR_SIZE, PPL_HEADER_SIZE);
+ 	if (ret) {
+ 		pr_err("Failed to allocate PPL header buffer\n");
+ 		return ret;
+diff --git a/super1.c b/super1.c
+index f80e38a..7ae6dc3 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1823,6 +1823,11 @@ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
+ 	struct ppl_header *ppl_hdr;
+ 	int ret;
+ 
++	/* first clear entire ppl space */
++	ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size);
++	if (ret)
++		return ret;
++
+ 	ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
+ 	if (ret) {
+ 		pr_err("Failed to allocate PPL header buffer\n");
+diff --git a/util.c b/util.c
+index 68af381..c11729e 100644
+--- a/util.c
++++ b/util.c
+@@ -30,6 +30,7 @@
+ #include	<sys/un.h>
+ #include	<sys/resource.h>
+ #include	<sys/vfs.h>
++#include	<sys/mman.h>
+ #include	<linux/magic.h>
+ #include	<poll.h>
+ #include	<ctype.h>
+@@ -2334,3 +2335,51 @@ void set_hooks(void)
+ 	set_dlm_hooks();
+ 	set_cmap_hooks();
+ }
++
++int zero_disk_range(int fd, unsigned long long sector, size_t count)
++{
++	int ret = 0;
++	int fd_zero;
++	void *addr = NULL;
++	size_t written = 0;
++	size_t len = count * 512;
++	ssize_t n;
++
++	fd_zero = open("/dev/zero", O_RDONLY);
++	if (fd_zero < 0) {
++		pr_err("Cannot open /dev/zero\n");
++		return -1;
++	}
++
++	if (lseek64(fd, sector * 512, SEEK_SET) < 0) {
++		ret = -errno;
++		pr_err("Failed to seek offset for zeroing\n");
++		goto out;
++	}
++
++	addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd_zero, 0);
++
++	if (addr == MAP_FAILED) {
++		ret = -errno;
++		pr_err("Mapping /dev/zero failed\n");
++		goto out;
++	}
++
++	do {
++		n = write(fd, addr + written, len - written);
++		if (n < 0) {
++			if (errno == EINTR)
++				continue;
++			ret = -errno;
++			pr_err("Zeroing disk range failed\n");
++			break;
++		}
++		written += n;
++	} while (written != len);
++
++	munmap(addr, len);
++
++out:
++	close(fd_zero);
++	return ret;
++}
+-- 
+2.7.4
+
diff --git a/SOURCES/bitmap-Remove-use-of-md-get-version1.patch b/SOURCES/bitmap-Remove-use-of-md-get-version1.patch
new file mode 100644
index 0000000..e0a754d
--- /dev/null
+++ b/SOURCES/bitmap-Remove-use-of-md-get-version1.patch
@@ -0,0 +1,26 @@
+From 5d89b18da805cb9ce2b0f726cd534bcbf4dce8c6 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:38:48 -0400
+Subject: [RHEL7.5 PATCH 061/169] bitmap: Remove use of md_get_version()
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ bitmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bitmap.c b/bitmap.c
+index ccedfd3..16a6b73 100644
+--- a/bitmap.c
++++ b/bitmap.c
+@@ -260,7 +260,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
+ 	if (!info)
+ 		return rv;
+ 	sb = &info->sb;
+-	if (sb->magic != BITMAP_MAGIC && md_get_version(fd) > 0) {
++	if (sb->magic != BITMAP_MAGIC) {
+ 		pr_err("This is an md array.  To view a bitmap you need to examine\n");
+ 		pr_err("a member device, not the array.\n");
+ 		pr_err("Reporting bitmap that would be used if this array were used\n");
+-- 
+2.7.4
+
diff --git a/SOURCES/change-back-0644-permission-for-Grow.c.patch b/SOURCES/change-back-0644-permission-for-Grow.c.patch
new file mode 100644
index 0000000..472482a
--- /dev/null
+++ b/SOURCES/change-back-0644-permission-for-Grow.c.patch
@@ -0,0 +1,21 @@
+From 99148c19bd9149bb938309ffb6b4dcde20b67934 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Tue, 2 May 2017 17:27:13 +0800
+Subject: [RHEL7.5 PATCH 105/169] change back 0644 permission for Grow.c
+
+Fixes commit:
+26714713cd2b ("mdadm: Change timestamps to unsigned data type.")
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Grow.c | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ mode change 100755 => 100644 Grow.c
+
+diff --git a/Grow.c b/Grow.c
+old mode 100755
+new mode 100644
+-- 
+2.7.4
+
diff --git a/SOURCES/container_members_max-degradation-Switch-to-using-sy.patch b/SOURCES/container_members_max-degradation-Switch-to-using-sy.patch
new file mode 100644
index 0000000..26ad79a
--- /dev/null
+++ b/SOURCES/container_members_max-degradation-Switch-to-using-sy.patch
@@ -0,0 +1,65 @@
+From 74d293a2535ef8726a9d43577dad4a908f471a0e Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 5 May 2017 12:06:57 -0400
+Subject: [RHEL7.5 PATCH 114/169] container_members_max_degradation: Switch
+ to using syfs for disk info
+
+With sysfs now providing the necessary active_disks info, switch to
+sysfs and eliminate one more use of md_get_array_info(). We can do
+this unconditionally since we wouldn't get here witout sysfs being
+available.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index c00a43d..b73eabd 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -802,27 +802,27 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
+ }
+ 
+ /* test if container has degraded member(s) */
+-static int container_members_max_degradation(struct map_ent *map, struct map_ent *me)
++static int
++container_members_max_degradation(struct map_ent *map, struct map_ent *me)
+ {
+-	mdu_array_info_t array;
+-	int afd;
+-	int max_degraded = 0;
++	struct mdinfo *sra;
++	int degraded, max_degraded = 0;
+ 
+ 	for(; map; map = map->next) {
+ 		if (!metadata_container_matches(map->metadata, me->devnm))
+ 			continue;
+-		afd = open_dev(map->devnm);
+-		if (afd < 0)
+-			continue;
+ 		/* most accurate information regarding array degradation */
+-		if (md_get_array_info(afd, &array) >= 0) {
+-			int degraded = array.raid_disks - array.active_disks -
+-				       array.spare_disks;
+-			if (degraded > max_degraded)
+-				max_degraded = degraded;
+-		}
+-		close(afd);
++		sra = sysfs_read(-1, map->devnm,
++				 GET_DISKS | GET_DEVS | GET_STATE);
++		if (!sra)
++			continue;
++		degraded = sra->array.raid_disks - sra->array.active_disks -
++			sra->array.spare_disks;
++		if (degraded > max_degraded)
++			max_degraded = degraded;
++		sysfs_free(sra);
+ 	}
++
+ 	return max_degraded;
+ }
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/disable-journal.patch b/SOURCES/disable-journal.patch
index 7631164..1bd67c3 100644
--- a/SOURCES/disable-journal.patch
+++ b/SOURCES/disable-journal.patch
@@ -1,32 +1,30 @@
-diff --git a/ReadMe.c b/ReadMe.c
-index eb8fb4b..2de30e1 100644
---- a/ReadMe.c
-+++ b/ReadMe.c
-@@ -147,7 +147,9 @@ struct option long_options[] = {
+--- a/ReadMe.c~	2017-12-11 11:15:10.314176222 +0800
++++ b/ReadMe.c	2017-12-11 11:16:42.451297334 +0800
+@@ -147,7 +147,9 @@
      {"data-offset",1, 0, DataOffset},
      {"nodes",1, 0, Nodes}, /* also for --assemble */
      {"home-cluster",1, 0, ClusterName},
-+#if 0 /* Disable for RHEL */
++#if 0 /*Disable for rhel7.5*/
      {"write-journal",1, 0, WriteJournal},
 +#endif
      {"consistency-policy", 1, 0, 'k'},
  
      /* For assemble */
-@@ -163,7 +165,9 @@ struct option long_options[] = {
+@@ -163,7 +165,9 @@
      /* Management */
      {"add",       0, 0, Add},
      {"add-spare", 0, 0, AddSpare},
-+#if 0 /* Disable for RHEL */
++#if 0 /*Disable for rhel7.5*/
      {"add-journal", 0, 0, AddJournal},
 +#endif
      {"remove",    0, 0, Remove},
      {"fail",      0, 0, Fail},
      {"set-faulty",0, 0, Fail},
-@@ -383,7 +387,9 @@ char Help_create[] =
+@@ -383,7 +387,9 @@
  "  --name=            -N : Textual name for array - max 32 characters\n"
  "  --bitmap-chunk=       : bitmap chunksize in Kilobytes.\n"
  "  --delay=           -d : bitmap update delay in seconds.\n"
-+#if 0 /* Disable for RHEL */
++#if 0 /*Disable for rhel7.5*/
  "  --write-journal=      : Specify journal device for RAID-4/5/6 array\n"
 +#endif
  "  --consistency-policy= : Specify the policy that determines how the array\n"
diff --git a/SOURCES/dont-allow-disks-with-different-sector-size-in-one.patch b/SOURCES/dont-allow-disks-with-different-sector-size-in-one.patch
deleted file mode 100644
index 6b2ec98..0000000
--- a/SOURCES/dont-allow-disks-with-different-sector-size-in-one.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-commit f2cc4f7d829e1b849e78bdf6c38b7bd6e234c600
-Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
-Date:   Tue May 9 12:25:45 2017 +0200
-
-    imsm: don't allow disks with different sector size in one array
-    
-    As there is no support in IMSM for arrays including disks with different
-    sector sizes, don't allow to create such configuration. Also skip the
-    disk with unsuitable sector size when looking for spares in the same
-    container.
-    
-    Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
-    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
-    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
-
-diff --git a/super-intel.c b/super-intel.c
-index cfb10d5..e88fe82 100644
---- a/super-intel.c
-+++ b/super-intel.c
-@@ -5483,6 +5483,22 @@
- 	return 1;
- }
- 
-+static int drive_validate_sector_size(struct intel_super *super, struct dl *dl)
-+{
-+	unsigned int member_sector_size;
-+
-+	if (dl->fd < 0) {
-+		pr_err("Invalid file descriptor for %s\n", dl->devname);
-+		return 0;
-+	}
-+
-+	if (!get_dev_sector_size(dl->fd, dl->devname, &member_sector_size))
-+		return 0;
-+	if (member_sector_size != super->sector_size)
-+		return 0;
-+	return 1;
-+}
-+
- #ifndef MDASSEMBLE
- static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
- 				     int fd, char *devname)
-@@ -5523,6 +5539,11 @@
- 		return 1;
- 	}
- 
-+	if (!drive_validate_sector_size(super, dl)) {
-+		pr_err("Combining drives of different sector size in one volume is not allowed\n");
-+		return 1;
-+	}
-+
- 	/* add a pristine spare to the metadata */
- 	if (dl->index < 0) {
- 		dl->index = super->anchor->num_disks;
-@@ -8484,6 +8505,9 @@
- 		if (dl->index == -1 && !activate_new)
- 			continue;
- 
-+		if (!drive_validate_sector_size(super, dl))
-+			continue;
-+
- 		/* Does this unused device have the requisite free space?
- 		 * It needs to be able to cover all member volumes
- 		 */
diff --git a/SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch b/SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch
new file mode 100644
index 0000000..02f1b02
--- /dev/null
+++ b/SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch
@@ -0,0 +1,64 @@
+commit f2cc4f7d829e1b849e78bdf6c38b7bd6e234c600
+Author: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
+Date:   Tue May 9 12:25:45 2017 +0200
+
+    imsm: don't allow disks with different sector size in one array
+    
+    As there is no support in IMSM for arrays including disks with different
+    sector sizes, don't allow to create such configuration. Also skip the
+    disk with unsuitable sector size when looking for spares in the same
+    container.
+    
+    Signed-off-by: Alexey Obitotskiy <aleksey.obitotskiy@intel.com>
+    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/super-intel.c b/super-intel.c
+index cfb10d5..e88fe82 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -5468,6 +5468,22 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
+ 	return 1;
+ }
+ 
++static int drive_validate_sector_size(struct intel_super *super, struct dl *dl)
++{
++	unsigned int member_sector_size;
++
++	if (dl->fd < 0) {
++		pr_err("Invalid file descriptor for %s\n", dl->devname);
++		return 0;
++	}
++
++	if (!get_dev_sector_size(dl->fd, dl->devname, &member_sector_size))
++		return 0;
++	if (member_sector_size != super->sector_size)
++		return 0;
++	return 1;
++}
++
+ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
+ 				     int fd, char *devname)
+ {
+@@ -5507,6 +5523,11 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
+ 		return 1;
+ 	}
+ 
++	if (!drive_validate_sector_size(super, dl)) {
++		pr_err("Combining drives of different sector size in one volume is not allowed\n");
++		return 1;
++	}
++
+ 	/* add a pristine spare to the metadata */
+ 	if (dl->index < 0) {
+ 		dl->index = super->anchor->num_disks;
+@@ -8440,6 +8461,9 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
+ 		if (dl->index == -1 && !activate_new)
+ 			continue;
+ 
++		if (!drive_validate_sector_size(super, dl))
++			continue;
++
+ 		/* Does this unused device have the requisite free space?
+ 		 * It needs to be able to cover all member volumes
+ 		 */
diff --git a/SOURCES/examine-tidy-up-some-code.patch b/SOURCES/examine-tidy-up-some-code.patch
new file mode 100644
index 0000000..d157195
--- /dev/null
+++ b/SOURCES/examine-tidy-up-some-code.patch
@@ -0,0 +1,146 @@
+From 36352fc95778677f0319f677ea079c49f7bbe9d0 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 3 Mar 2017 10:57:00 +1100
+Subject: [RHEL7.5 PATCH 006/169] examine: tidy up some code.
+
+Michael Shigorin reports that the 'lcc' compiler isn't able
+to deduce that 'st' must be initialized in
+
+		if (c->SparcAdjust)
+			st->ss->update_super(st, NULL, "sparc2.2",
+
+just because the only times it isn't initialised, 'err' is set non-zero.
+
+This results in a 'possibly uninitialised' warning.
+While there is no bug in the code, this does suggest that maybe
+the code could be made more obviously correct.
+
+So this patch:
+ 1/ moves the "err" variable inside the for loop, so an error in
+    one device doesn't stop the other devices from being processed
+ 2/ calls 'continue' early if the device cannot be opened, so that
+    a level of indent can be removed, and so that it is clear that
+    'st' is always initialised before being used
+ 3/ frees 'st' if an error occured in load_super or load_container.
+
+Reported-by: Michael Shigorin <mike@altlinux.org>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Examine.c | 75 +++++++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 39 insertions(+), 36 deletions(-)
+
+diff --git a/Examine.c b/Examine.c
+index 953b8ee..7013480 100644
+--- a/Examine.c
++++ b/Examine.c
+@@ -53,7 +53,6 @@ int Examine(struct mddev_dev *devlist,
+ 	 */
+ 	int fd;
+ 	int rv = 0;
+-	int err = 0;
+ 
+ 	struct array {
+ 		struct supertype *st;
+@@ -66,6 +65,8 @@ int Examine(struct mddev_dev *devlist,
+ 	for (; devlist ; devlist = devlist->next) {
+ 		struct supertype *st;
+ 		int have_container = 0;
++		int err = 0;
++		int container = 0;
+ 
+ 		fd = dev_open(devlist->devname, O_RDONLY);
+ 		if (fd < 0) {
+@@ -74,44 +75,46 @@ int Examine(struct mddev_dev *devlist,
+ 				       devlist->devname, strerror(errno));
+ 				rv = 1;
+ 			}
+-			err = 1;
++			continue;
+ 		}
+-		else {
+-			int container = 0;
+-			if (forcest)
+-				st = dup_super(forcest);
+-			else if (must_be_container(fd)) {
+-				/* might be a container */
+-				st = super_by_fd(fd, NULL);
+-				container = 1;
+-			} else
+-				st = guess_super(fd);
+-			if (st) {
+-				err = 1;
+-				st->ignore_hw_compat = 1;
+-				if (!container)
+-					err = st->ss->load_super(st, fd,
+-								 (c->brief||c->scan) ? NULL
+-								 :devlist->devname);
+-				if (err && st->ss->load_container) {
+-					err = st->ss->load_container(st, fd,
+-								 (c->brief||c->scan) ? NULL
+-								 :devlist->devname);
+-					if (!err)
+-						have_container = 1;
+-				}
+-				st->ignore_hw_compat = 0;
+-			} else {
+-				if (!c->brief) {
+-					pr_err("No md superblock detected on %s.\n", devlist->devname);
+-					rv = 1;
+-				}
+-				err = 1;
++
++		if (forcest)
++			st = dup_super(forcest);
++		else if (must_be_container(fd)) {
++			/* might be a container */
++			st = super_by_fd(fd, NULL);
++			container = 1;
++		} else
++			st = guess_super(fd);
++		if (st) {
++			err = 1;
++			st->ignore_hw_compat = 1;
++			if (!container)
++				err = st->ss->load_super(st, fd,
++							 (c->brief||c->scan) ? NULL
++							 :devlist->devname);
++			if (err && st->ss->load_container) {
++				err = st->ss->load_container(st, fd,
++							     (c->brief||c->scan) ? NULL
++							     :devlist->devname);
++				if (!err)
++					have_container = 1;
+ 			}
+-			close(fd);
++			st->ignore_hw_compat = 0;
++		} else {
++			if (!c->brief) {
++				pr_err("No md superblock detected on %s.\n", devlist->devname);
++				rv = 1;
++			}
++			err = 1;
+ 		}
+-		if (err)
++		close(fd);
++
++		if (err) {
++			if (st)
++				st->ss->free_super(st);
+ 			continue;
++		}
+ 
+ 		if (c->SparcAdjust)
+ 			st->ss->update_super(st, NULL, "sparc2.2",
+@@ -121,7 +124,7 @@ int Examine(struct mddev_dev *devlist,
+ 		if (c->brief && st->ss->brief_examine_super == NULL) {
+ 			if (!c->scan)
+ 				pr_err("No brief listing for %s on %s\n",
+-					st->ss->name, devlist->devname);
++				       st->ss->name, devlist->devname);
+ 		} else if (c->brief) {
+ 			struct array *ap;
+ 			char *d;
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-Set-disk-slot-number.patch b/SOURCES/imsm-Set-disk-slot-number.patch
new file mode 100644
index 0000000..a382c59
--- /dev/null
+++ b/SOURCES/imsm-Set-disk-slot-number.patch
@@ -0,0 +1,32 @@
+commit 20dc76d15b40c17b4ccdc3d6283af8ecb513707f
+Author: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+Date:   Tue Oct 3 14:49:49 2017 +0200
+
+    imsm: Set disk slot number
+    
+    If first disk of IMSM RAID1 is failed but still present in the system,
+    the array is not auto-assembled. Auto-assemble uses raid disk slot from
+    metadata to index disks. As it's not set, the valid disk is seen as a
+    replacement disk and its metadata is ignored. The problem is not
+    observed for other RAID levels as they have more than 2 disks -
+    replacement disks are only stored under uneven indexes so third disk
+    metadata is used in such scenario.
+    
+    Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
+    Reviewed-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/super-intel.c b/super-intel.c
+index 536cb61..b561fe2 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -3502,6 +3502,9 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
+ 			__u32 ord = get_imsm_ord_tbl_ent(dev, j, MAP_0);
+ 			__u32 idx = ord_to_idx(ord);
+ 
++			if (super->disks && super->disks->index == (int)idx)
++				info->disk.raid_disk = j;
++
+ 			if (!(ord & IMSM_ORD_REBUILD) &&
+ 			    get_imsm_missing(super, idx)) {
+ 				missing = 1;
diff --git a/SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch b/SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch
new file mode 100644
index 0000000..84d2ef0
--- /dev/null
+++ b/SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch
@@ -0,0 +1,38 @@
+From 50b9c10da0e7c153744b548680147dc8cc7c4c72 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:15 +0200
+Subject: [PATCH 09/12] imsm: Write empty PPL header if assembling
+ regular clean array.
+
+If array was initially assembled with kernel without PPL support -
+initial header was never written to the drive.
+If initial resync was completed and system is rebooted to kernel with
+PPL support - mdadm prevents from assembling normal clean array
+due to lack of valid PPL.
+Write empty header when assemble normal clean array, so the
+its assamble is no longer blocked.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 7b2327b..501d0c3 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6225,7 +6225,9 @@ out:
+ 	}
+ 
+ 	if (ret == 1) {
+-		if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
++		if (map->map_state == IMSM_T_STATE_UNINITIALIZED ||
++		   (map->map_state == IMSM_T_STATE_NORMAL &&
++		   !(dev->vol.dirty & RAIDVOL_DIRTY)))
+ 			ret = st->ss->write_init_ppl(st, info, d->fd);
+ 		else
+ 			info->mismatch_cnt++;
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch b/SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch
new file mode 100644
index 0000000..afbf310
--- /dev/null
+++ b/SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch
@@ -0,0 +1,32 @@
+From 98e96bdbefaf0bf1c3d4161862af1ab6d03da1db Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Thu, 28 Sep 2017 14:41:16 +0200
+Subject: [PATCH 10/12] imsm: always do ppl recovery when starting a
+ rebuilding array
+
+Set resync_start to 0 when starting a rebuilding array to make the
+kernel perform ppl recovery before the rebuild.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@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 501d0c3..996d133 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -7756,6 +7756,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 						map->blocks_per_strip;
+ 				info_d->ppl_sector = this->ppl_sector;
+ 				info_d->ppl_size = this->ppl_size;
++				if (this->consistency_policy == CONSISTENCY_POLICY_PPL &&
++				    recovery_start == 0)
++					this->resync_start = 0;
+ 			} else {
+ 				info_d->component_size = blocks_per_member(map);
+ 			}
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-continue-resync-on-3disk-RAID10.patch b/SOURCES/imsm-continue-resync-on-3disk-RAID10.patch
new file mode 100644
index 0000000..33a218c
--- /dev/null
+++ b/SOURCES/imsm-continue-resync-on-3disk-RAID10.patch
@@ -0,0 +1,113 @@
+commit 8b9cd157dc030924afaeb1dd1a4d3306f5bda118
+Author: Maksymilian Kunt <maksymilian.kunt@intel.com>
+Date:   Mon Nov 13 12:30:49 2017 +0100
+
+    imsm: continue resync on 3-disk RAID10
+    
+    If RAID10 gets degraded during resync and is stopped, it doesn't continue
+    resync after automatic assemble and it is reported to be in sync. Resync
+    is blocked because the disk is missing. It should not happen for RAID10 as
+    it can still continue with 3 disks.
+    
+    Count missing disks. Block resync only if number of missing disks exceeds
+    limit for given RAID level (only different for RAID10). Check if the
+    disk under recovery is present. If not, resync should be allowed to run.
+    
+    Signed-off-by: Maksymilian Kunt <maksymilian.kunt@intel.com>
+    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/super-intel.c b/super-intel.c
+index 2f912f2..c55802f 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -1342,6 +1342,20 @@ static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
+ 	return size;
+ }
+ 
++static int able_to_resync(int raid_level, int missing_disks)
++{
++	int max_missing_disks = 0;
++
++	switch (raid_level) {
++	case 10:
++		max_missing_disks = 1;
++		break;
++	default:
++		max_missing_disks = 0;
++	}
++	return missing_disks <= max_missing_disks;
++}
++
+ /* try to determine how much space is reserved for metadata from
+  * the last get_extents() entry on the smallest active disk,
+  * otherwise fallback to the default
+@@ -7645,6 +7659,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		int slot;
+ 		int chunk;
+ 		char *ep;
++		int level;
+ 
+ 		if (subarray &&
+ 		    (i != strtoul(subarray, &ep, 10) || *ep != '\0'))
+@@ -7653,6 +7668,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		dev = get_imsm_dev(super, i);
+ 		map = get_imsm_map(dev, MAP_0);
+ 		map2 = get_imsm_map(dev, MAP_1);
++		level = get_imsm_raid_level(map);
+ 
+ 		/* do not publish arrays that are in the middle of an
+ 		 * unsupported migration
+@@ -7675,8 +7691,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 		chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
+ 		/* mdadm does not support all metadata features- set the bit in all arrays state */
+ 		if (!validate_geometry_imsm_orom(super,
+-						 get_imsm_raid_level(map), /* RAID level */
+-						 imsm_level_to_layout(get_imsm_raid_level(map)),
++						 level, /* RAID level */
++						 imsm_level_to_layout(level),
+ 						 map->num_members, /* raid disks */
+ 						 &chunk, join_u32(dev->size_low, dev->size_high),
+ 						 1 /* verbose */)) {
+@@ -7700,6 +7716,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 			int idx;
+ 			int skip;
+ 			__u32 ord;
++			int missing = 0;
+ 
+ 			skip = 0;
+ 			idx = get_imsm_disk_idx(dev, slot, MAP_0);
+@@ -7713,19 +7730,27 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
+ 				skip = 1;
+ 			if (d && is_failed(&d->disk))
+ 				skip = 1;
+-			if (ord & IMSM_ORD_REBUILD)
++			if (!skip && (ord & IMSM_ORD_REBUILD))
+ 				recovery_start = 0;
+ 
+ 			/*
+ 			 * if we skip some disks the array will be assmebled degraded;
+ 			 * reset resync start to avoid a dirty-degraded
+ 			 * situation when performing the intial sync
+-			 *
+-			 * FIXME handle dirty degraded
+ 			 */
+-			if ((skip || recovery_start == 0) &&
+-			    !(dev->vol.dirty & RAIDVOL_DIRTY))
+-				this->resync_start = MaxSector;
++			if (skip)
++				missing++;
++
++			if (!(dev->vol.dirty & RAIDVOL_DIRTY)) {
++				if ((!able_to_resync(level, missing) ||
++				     recovery_start == 0))
++					this->resync_start = MaxSector;
++			} else {
++				/*
++				 * FIXME handle dirty degraded
++				 */
++			}
++
+ 			if (skip)
+ 				continue;
+ 
diff --git a/SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch b/SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch
new file mode 100644
index 0000000..a2e8196
--- /dev/null
+++ b/SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch
@@ -0,0 +1,61 @@
+From b23d07503d5940086ea0884d09a737ccb0a9e435 Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Thu, 28 Sep 2017 14:41:14 +0200
+Subject: [PATCH 08/12] imsm: don't skip resync when an invalid ppl
+ header is found
+
+If validate_ppl_imsm() detects an invalid ppl header it will be
+overwritten with a valid, empty ppl header. But if we are assembling an
+array after unclean shutdown this will cause the kernel to skip resync
+after ppl recovery. We don't want that because if there was an invalid
+ppl it's best to assume that the ppl recovery is not enough to make the
+array consistent and a full resync should be performed. So when
+overwriting the invalid ppl add one ppl_header_entry with a wrong
+checksum. This will prevent the kernel from skipping resync after ppl
+recovery.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 630fb6e..7b2327b 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6080,6 +6080,16 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd
+ 	ppl_hdr = buf;
+ 	memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED);
+ 	ppl_hdr->signature = __cpu_to_le32(super->anchor->orig_family_num);
++
++	if (info->mismatch_cnt) {
++		/*
++		 * We are overwriting an invalid ppl. Make one entry with wrong
++		 * checksum to prevent the kernel from skipping resync.
++		 */
++		ppl_hdr->entries_count = __cpu_to_le32(1);
++		ppl_hdr->entries[0].checksum = ~0;
++	}
++
+ 	ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE));
+ 
+ 	if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) {
+@@ -6214,8 +6224,12 @@ out:
+ 		}
+ 	}
+ 
+-	if (ret == 1 && map->map_state == IMSM_T_STATE_UNINITIALIZED)
+-		return st->ss->write_init_ppl(st, info, d->fd);
++	if (ret == 1) {
++		if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
++			ret = st->ss->write_init_ppl(st, info, d->fd);
++		else
++			info->mismatch_cnt++;
++	}
+ 
+ 	return ret;
+ }
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-fix-missing-error-message-during-migration1.patch b/SOURCES/imsm-fix-missing-error-message-during-migration1.patch
new file mode 100644
index 0000000..70810d2
--- /dev/null
+++ b/SOURCES/imsm-fix-missing-error-message-during-migration1.patch
@@ -0,0 +1,35 @@
+From 565cc99e341b3021ad26ff6da19a67d4e4abffde Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Tue, 24 Jan 2017 14:29:33 +0100
+Subject: [RHEL7.5 PATCH 002/169] imsm: fix missing error message during
+ migration
+
+If user tries to migrate from raid0 to raid5 and there is no spare
+drive to perform it - mdadm will exit with errorcode, but
+no error message is printed.
+
+Print error instead of debug message when this condition occurs,
+so user is informed why requested migration is not started.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ super-intel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 433bb6d..d5e9517 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -10718,7 +10718,7 @@ static int imsm_create_metadata_update_for_migration(
+ 			free(u);
+ 			sysfs_free(spares);
+ 			update_memory_size = 0;
+-			dprintf("error: cannot get spare device for requested migration");
++			pr_err("cannot get spare device for requested migration\n");
+ 			return 0;
+ 		}
+ 		sysfs_free(spares);
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-rebuild-from-2-disk-RAID10.patch b/SOURCES/imsm-rebuild-from-2-disk-RAID10.patch
new file mode 100644
index 0000000..fe941c8
--- /dev/null
+++ b/SOURCES/imsm-rebuild-from-2-disk-RAID10.patch
@@ -0,0 +1,181 @@
+From fb12a7454000c56aa0439c5bc07fb29de2f3f2a1 Mon Sep 17 00:00:00 2001
+From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date: Thu, 10 Aug 2017 15:47:22 +0200
+Subject: [RHEL7.5 PATCH 163/169] imsm: rebuild from 2-disk RAID10
+
+When RAID10 loses 2 disks and it is still operational, it cannot be
+rebuilt. The rebuild process starts for the first disk and completes,
+however completion is not recorded in metadata. There is an assumption
+that rebuild completion corresponds to transition from degraded to
+normal state. It's not the case for 2-disk RAID10 as it's still degraded
+after rebuild to first disk completes.
+
+Check if disk rebuild flag is set in the second map and clear it. So far it
+has been checked only in the first map (where it was not set). The flag in
+the second map has not been cleared but rebuild completion dropped second
+map so the problem was not visible.
+
+If rebuild completion is notified and array still has failed disks and is in
+degraded state, check first if rebuild position is really unset (the same
+check as for array in normal state). If so, mark migration as done but don't
+change array state (it should remain degraded). Update failed disk number.
+
+On rebuild start don't clear the rebuild flag in the destination map for all
+the drives because failed state is lost for one of them. Just do a copy of
+a map and clear the flag in the destination map for the disk that goes into
+rebuild. Similarily preserve the rebuild flag in the map during disk removal.
+
+If the disk is missing on array start and migration has been in progress,
+don't just cancel it. Check first if maybe one of the disks was not under
+rebuild (rebuild flag present both in source and destination map). If so,
+rebuild was running despite of failed disk so there is no need to cancel
+migration.
+
+Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 67 insertions(+), 10 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 51b7cc3..125c3a9 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -4023,7 +4023,7 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super,
+ 
+ 	/* duplicate and then set the target end state in map[0] */
+ 	memcpy(dest, src, sizeof_imsm_map(src));
+-	if (migr_type == MIGR_REBUILD || migr_type == MIGR_GEN_MIGR) {
++	if (migr_type == MIGR_GEN_MIGR) {
+ 		__u32 ord;
+ 		int i;
+ 
+@@ -7936,14 +7936,35 @@ static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
+ 	/* end process for initialization and rebuild only
+ 	 */
+ 	if (is_gen_migration(dev) == 0) {
+-		__u8 map_state;
+-		int failed;
++		int failed = imsm_count_failed(super, dev, MAP_0);
+ 
+-		failed = imsm_count_failed(super, dev, MAP_0);
+-		map_state = imsm_check_degraded(super, dev, failed, MAP_0);
++		if (failed) {
++			__u8 map_state;
++			struct imsm_map *map = get_imsm_map(dev, MAP_0);
++			struct imsm_map *map1;
++			int i, ord, ord_map1;
++			int rebuilt = 1;
+ 
+-		if (failed)
+-			end_migration(dev, super, map_state);
++			for (i = 0; i < map->num_members; i++) {
++				ord = get_imsm_ord_tbl_ent(dev, i, MAP_0);
++				if (!(ord & IMSM_ORD_REBUILD))
++					continue;
++
++				map1 = get_imsm_map(dev, MAP_1);
++				if (!map1)
++					continue;
++
++				ord_map1 = __le32_to_cpu(map1->disk_ord_tbl[i]);
++				if (ord_map1 & IMSM_ORD_REBUILD)
++					rebuilt = 0;
++			}
++
++			if (rebuilt) {
++				map_state = imsm_check_degraded(super, dev,
++								failed, MAP_0);
++				end_migration(dev, super, map_state);
++			}
++		}
+ 	}
+ 	for (dl = super->missing; dl; dl = dl->next)
+ 		mark_missing(super, dev, &dl->disk, dl->index);
+@@ -8225,8 +8246,10 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 	int failed;
+ 	int ord;
+ 	__u8 map_state;
++	int rebuild_done = 0;
++	int i;
+ 
+-	ord = imsm_disk_slot_to_ord(a, n);
++	ord = get_imsm_ord_tbl_ent(dev, n, MAP_X);
+ 	if (ord < 0)
+ 		return;
+ 
+@@ -8244,6 +8267,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 		struct imsm_map *migr_map = get_imsm_map(dev, MAP_1);
+ 
+ 		set_imsm_ord_tbl_ent(migr_map, n, ord_to_idx(ord));
++		rebuild_done = 1;
+ 		super->updates_pending++;
+ 	}
+ 
+@@ -8306,7 +8330,39 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
+ 				dprintf_cont(" Map state change");
+ 				end_migration(dev, super, map_state);
+ 				super->updates_pending++;
++			} else if (!rebuild_done) {
++				break;
++			}
++
++			/* check if recovery is really finished */
++			for (mdi = a->info.devs; mdi ; mdi = mdi->next)
++				if (mdi->recovery_start != MaxSector) {
++					recovery_not_finished = 1;
++					break;
++				}
++			if (recovery_not_finished) {
++				dprintf_cont("\n");
++				dprintf("Rebuild has not finished yet, state not changed");
++				if (a->last_checkpoint < mdi->recovery_start) {
++					a->last_checkpoint =
++						mdi->recovery_start;
++					super->updates_pending++;
++				}
++				break;
+ 			}
++
++			dprintf_cont(" Rebuild done, still degraded");
++			dev->vol.migr_state = 0;
++			set_migr_type(dev, 0);
++			dev->vol.curr_migr_unit = 0;
++
++			for (i = 0; i < map->num_members; i++) {
++				int idx = get_imsm_ord_tbl_ent(dev, i, MAP_0);
++
++				if (idx & IMSM_ORD_REBUILD)
++					map->failed_disk_num = i;
++			}
++			super->updates_pending++;
+ 			break;
+ 		}
+ 		if (is_gen_migration(dev)) {
+@@ -9936,7 +9992,7 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind
+ 	struct imsm_dev *dev;
+ 	struct imsm_map *map;
+ 	unsigned int i, j, num_members;
+-	__u32 ord;
++	__u32 ord, ord_map0;
+ 	struct bbm_log *log = super->bbm_log;
+ 
+ 	dprintf("deleting device[%d] from imsm_super\n", index);
+@@ -9958,12 +10014,13 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind
+ 			 * ord-flags to the first map
+ 			 */
+ 			ord = get_imsm_ord_tbl_ent(dev, j, MAP_X);
++			ord_map0 = get_imsm_ord_tbl_ent(dev, j, MAP_0);
+ 
+ 			if (ord_to_idx(ord) <= index)
+ 				continue;
+ 
+ 			map = get_imsm_map(dev, MAP_0);
+-			set_imsm_ord_tbl_ent(map, j, ord_to_idx(ord - 1));
++			set_imsm_ord_tbl_ent(map, j, ord_map0 - 1);
+ 			map = get_imsm_map(dev, MAP_1);
+ 			if (map)
+ 				set_imsm_ord_tbl_ent(map, j, ord - 1);
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-switch-to-multiple-ppls-automatically-during-as.patch b/SOURCES/imsm-switch-to-multiple-ppls-automatically-during-as.patch
new file mode 100644
index 0000000..3aae7b5
--- /dev/null
+++ b/SOURCES/imsm-switch-to-multiple-ppls-automatically-during-as.patch
@@ -0,0 +1,60 @@
+From 54148aba7c1a02bf018ae777bebc7f16e6cd3195 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:12 +0200
+Subject: [PATCH 06/12] imsm: switch to multiple ppls automatically
+ during assemble
+
+If user has array with single ppl -
+update the metadata to use multiple ppls.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/super-intel.c b/super-intel.c
+index 65cdc92..630fb6e 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6184,6 +6184,36 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
+ out:
+ 	free(buf);
+ 
++	/*
++	 * Update metadata to use mutliple PPLs area (1MB).
++	 * This is done once for all RAID members
++	 */
++	if (info->consistency_policy == CONSISTENCY_POLICY_PPL &&
++	    info->ppl_size != (MULTIPLE_PPL_AREA_SIZE_IMSM >> 9)) {
++		char subarray[20];
++		struct mdinfo *member_dev;
++
++		sprintf(subarray, "%d", info->container_member);
++
++		if (mdmon_running(st->container_devnm))
++			st->update_tail = &st->updates;
++
++		if (st->ss->update_subarray(st, subarray, "ppl", NULL)) {
++			pr_err("Failed to update subarray %s\n",
++			      subarray);
++		} else {
++			if (st->update_tail)
++				flush_metadata_updates(st);
++			else
++				st->ss->sync_metadata(st);
++			info->ppl_size = (MULTIPLE_PPL_AREA_SIZE_IMSM >> 9);
++			for (member_dev = info->devs; member_dev;
++			     member_dev = member_dev->next)
++				member_dev->ppl_size =
++				    (MULTIPLE_PPL_AREA_SIZE_IMSM >> 9);
++		}
++	}
++
+ 	if (ret == 1 && map->map_state == IMSM_T_STATE_UNINITIALIZED)
+ 		return st->ss->write_init_ppl(st, info, d->fd);
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-use-correct-map-when-validating-ppl.patch b/SOURCES/imsm-use-correct-map-when-validating-ppl.patch
new file mode 100644
index 0000000..c0c40e6
--- /dev/null
+++ b/SOURCES/imsm-use-correct-map-when-validating-ppl.patch
@@ -0,0 +1,48 @@
+From 2fc0fc63a9dbf31a3e333492bc1df80c21fdb10c Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Thu, 28 Sep 2017 14:41:17 +0200
+Subject: [PATCH 11/12] imsm: use correct map when validating ppl
+
+Use the first map to get the correct disk when rebuilding and not the
+failed disk from the second map.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+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 996d133..cf5d822 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6119,7 +6119,6 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
+ 	struct ppl_header *ppl_hdr;
+ 	__u32 crc;
+ 	struct imsm_dev *dev;
+-	struct imsm_map *map;
+ 	__u32 idx;
+ 	unsigned int i;
+ 	unsigned long long ppl_offset = 0;
+@@ -6134,8 +6133,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
+ 	}
+ 
+ 	dev = get_imsm_dev(super, info->container_member);
+-	map = get_imsm_map(dev, MAP_X);
+-	idx = get_imsm_disk_idx(dev, disk->disk.raid_disk, MAP_X);
++	idx = get_imsm_disk_idx(dev, disk->disk.raid_disk, MAP_0);
+ 	d = get_imsm_dl_disk(super, idx);
+ 
+ 	if (!d || d->index < 0 || is_failed(&d->disk))
+@@ -6225,6 +6223,8 @@ out:
+ 	}
+ 
+ 	if (ret == 1) {
++		struct imsm_map *map = get_imsm_map(dev, MAP_X);
++
+ 		if (map->map_state == IMSM_T_STATE_UNINITIALIZED ||
+ 		   (map->map_state == IMSM_T_STATE_NORMAL &&
+ 		   !(dev->vol.dirty & RAIDVOL_DIRTY)))
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-validate-multiple-ppls-during-assemble.patch b/SOURCES/imsm-validate-multiple-ppls-during-assemble.patch
new file mode 100644
index 0000000..55f04de
--- /dev/null
+++ b/SOURCES/imsm-validate-multiple-ppls-during-assemble.patch
@@ -0,0 +1,124 @@
+From 44b6b87610281a4add36a1addd7630095dc8a545 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:10 +0200
+Subject: [PATCH 04/12] imsm: validate multiple ppls during assemble
+
+Change validation algorithm to check validity of multiple ppls that
+are stored in PPL area.
+
+If read error occurs during - treat the all PPLs as invalid -
+there is no guarantee that this one was not latest. If the header CRC is
+incorrect - assume that there are no further PPLs in PPL area.
+
+If whole PPL area was written at least once - there is a possibility that
+old PPL (with lower generation number) will follow the recent one
+(with higest generation number). Compare those generation numbers to check
+which PPL is latest.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 71 +++++++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 47 insertions(+), 24 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 347838e..56dec36 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6106,11 +6106,14 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
+ 	struct imsm_dev *dev;
+ 	struct imsm_map *map;
+ 	__u32 idx;
++	unsigned int i;
++	unsigned long long ppl_offset = 0;
++	unsigned long long prev_gen_num = 0;
+ 
+ 	if (disk->disk.raid_disk < 0)
+ 		return 0;
+ 
+-	if (posix_memalign(&buf, 4096, PPL_HEADER_SIZE)) {
++	if (posix_memalign(&buf, MAX_SECTOR_SIZE, PPL_HEADER_SIZE)) {
+ 		pr_err("Failed to allocate PPL header buffer\n");
+ 		return -1;
+ 	}
+@@ -6123,34 +6126,54 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
+ 	if (!d || d->index < 0 || is_failed(&d->disk))
+ 		goto out;
+ 
+-	if (lseek64(d->fd, info->ppl_sector * 512, SEEK_SET) < 0) {
+-		perror("Failed to seek to PPL header location");
+-		ret = -1;
+-		goto out;
+-	}
++	ret = 1;
++	while (ppl_offset < MULTIPLE_PPL_AREA_SIZE_IMSM) {
++		dprintf("Checking potential PPL at offset: %llu\n", ppl_offset);
+ 
+-	if (read(d->fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) {
+-		perror("Read PPL header failed");
+-		ret = -1;
+-		goto out;
+-	}
++		if (lseek64(d->fd, info->ppl_sector * 512 + ppl_offset,
++			    SEEK_SET) < 0) {
++			perror("Failed to seek to PPL header location");
++			ret = -1;
++			goto out;
++		}
+ 
+-	ppl_hdr = buf;
++		if (read(d->fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) {
++			perror("Read PPL header failed");
++			ret = -1;
++			goto out;
++		}
+ 
+-	crc = __le32_to_cpu(ppl_hdr->checksum);
+-	ppl_hdr->checksum = 0;
++		ppl_hdr = buf;
+ 
+-	if (crc != ~crc32c_le(~0, buf, PPL_HEADER_SIZE)) {
+-		dprintf("Wrong PPL header checksum on %s\n",
+-			d->devname);
+-		ret = 1;
+-	}
++		crc = __le32_to_cpu(ppl_hdr->checksum);
++		ppl_hdr->checksum = 0;
++
++		if (crc != ~crc32c_le(~0, buf, PPL_HEADER_SIZE)) {
++			dprintf("Wrong PPL header checksum on %s\n",
++				d->devname);
++			goto out;
++		}
++
++		if (prev_gen_num > __le64_to_cpu(ppl_hdr->generation)) {
++			/* previous was newest, it was already checked */
++			goto out;
++		}
++
++		if ((__le32_to_cpu(ppl_hdr->signature) !=
++			      super->anchor->orig_family_num)) {
++			dprintf("Wrong PPL header signature on %s\n",
++				d->devname);
++			ret = 1;
++			goto out;
++		}
++
++		ret = 0;
++		prev_gen_num = __le64_to_cpu(ppl_hdr->generation);
+ 
+-	if (!ret && (__le32_to_cpu(ppl_hdr->signature) !=
+-		      super->anchor->orig_family_num)) {
+-		dprintf("Wrong PPL header signature on %s\n",
+-			d->devname);
+-		ret = 1;
++		ppl_offset += PPL_HEADER_SIZE;
++		for (i = 0; i < __le32_to_cpu(ppl_hdr->entries_count); i++)
++			ppl_offset +=
++				   __le32_to_cpu(ppl_hdr->entries[i].pp_size);
+ 	}
+ 
+ out:
+-- 
+2.7.4
+
diff --git a/SOURCES/imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch b/SOURCES/imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch
new file mode 100644
index 0000000..47d2093
--- /dev/null
+++ b/SOURCES/imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch
@@ -0,0 +1,35 @@
+From 2ec9d182ea5821ec2f7234ff3c0cf07ae9f43cb4 Mon Sep 17 00:00:00 2001
+From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date: Thu, 28 Sep 2017 14:41:18 +0200
+Subject: [PATCH 12/12] imsm: write initial ppl on a disk added for
+ rebuild
+
+When rebuild is initiated by the UEFI driver it is possible that the new
+disk will not contain a valid ppl header. Just write the initial ppl
+and don't abort assembly.
+
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index cf5d822..536cb61 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6227,7 +6227,10 @@ out:
+ 
+ 		if (map->map_state == IMSM_T_STATE_UNINITIALIZED ||
+ 		   (map->map_state == IMSM_T_STATE_NORMAL &&
+-		   !(dev->vol.dirty & RAIDVOL_DIRTY)))
++		   !(dev->vol.dirty & RAIDVOL_DIRTY)) ||
++		   (dev->vol.migr_state == MIGR_REBUILD &&
++		    dev->vol.curr_migr_unit == 0 &&
++		    get_imsm_disk_idx(dev, disk->disk.raid_disk, MAP_1) != idx))
+ 			ret = st->ss->write_init_ppl(st, info, d->fd);
+ 		else
+ 			info->mismatch_cnt++;
+-- 
+2.7.4
+
diff --git a/SOURCES/imsmadd-support-for-multiple-ppls.patch b/SOURCES/imsmadd-support-for-multiple-ppls.patch
new file mode 100644
index 0000000..aafe19c
--- /dev/null
+++ b/SOURCES/imsmadd-support-for-multiple-ppls.patch
@@ -0,0 +1,132 @@
+From c24620685185eb7a159a8563b60a5e062b03b12e Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:09 +0200
+Subject: [PATCH 03/12] imsm: Add support for multiple ppls
+
+Add interpreting new rwh_policy bits. Set PPL size as 1MB.
+If new array with ppl is created - use new implementation of ppl by
+default.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-intel.c | 37 +++++++++++++++++++++++++++----------
+ 1 file changed, 27 insertions(+), 10 deletions(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index e3dcd3d..347838e 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -92,6 +92,9 @@
+ #define NUM_BLOCKS_DIRTY_STRIPE_REGION 2056
+ #define SECT_PER_MB_SHIFT 11
+ #define MAX_SECTOR_SIZE 4096
++#define MULTIPLE_PPL_AREA_SIZE_IMSM (1024 * 1024) /* Size of the whole
++						   * mutliple PPL area
++						   */
+ 
+ /* Disk configuration info. */
+ #define IMSM_MAX_DEVICES 255
+@@ -207,6 +210,9 @@ struct imsm_dev {
+ #define RWH_OFF 0
+ #define RWH_DISTRIBUTED 1
+ #define RWH_JOURNALING_DRIVE 2
++#define RWH_MULTIPLE_DISTRIBUTED 3
++#define RWH_MULTIPLE_PPLS_JOURNALING_DRIVE 4
++#define RWH_MULTIPLE_OFF 5
+ 	__u8  rwh_policy; /* Raid Write Hole Policy */
+ 	__u8  jd_serial[MAX_RAID_SERIAL_LEN]; /* Journal Drive serial number */
+ 	__u8  filler1;
+@@ -284,7 +290,7 @@ static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed"
+ 				 *  already been migrated and must
+ 				 *  be recovered from checkpoint area */
+ 
+-#define PPL_ENTRY_SPACE (128 * 1024) /* Size of the PPL, without the header */
++#define PPL_ENTRY_SPACE (128 * 1024) /* Size of single PPL, without the header */
+ 
+ struct migr_record {
+ 	__u32 rec_status;	    /* Status used to determine how to restart
+@@ -1539,12 +1545,16 @@ static void print_imsm_dev(struct intel_super *super,
+ 	printf("    Dirty State : %s\n", (dev->vol.dirty & RAIDVOL_DIRTY) ?
+ 					 "dirty" : "clean");
+ 	printf("     RWH Policy : ");
+-	if (dev->rwh_policy == RWH_OFF)
++	if (dev->rwh_policy == RWH_OFF || dev->rwh_policy == RWH_MULTIPLE_OFF)
+ 		printf("off\n");
+ 	else if (dev->rwh_policy == RWH_DISTRIBUTED)
+ 		printf("PPL distributed\n");
+ 	else if (dev->rwh_policy == RWH_JOURNALING_DRIVE)
+ 		printf("PPL journaling drive\n");
++	else if (dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED)
++		printf("Multiple distributed PPLs\n");
++	else if (dev->rwh_policy == RWH_MULTIPLE_PPLS_JOURNALING_DRIVE)
++		printf("Multiple PPLs on journaling drive\n");
+ 	else
+ 		printf("<unknown:%d>\n", dev->rwh_policy);
+ }
+@@ -3294,10 +3304,16 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
+ 	memset(info->uuid, 0, sizeof(info->uuid));
+ 	info->recovery_start = MaxSector;
+ 
+-	if (info->array.level == 5 && dev->rwh_policy == RWH_DISTRIBUTED) {
++	if (info->array.level == 5 &&
++	    (dev->rwh_policy == RWH_DISTRIBUTED ||
++	     dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED)) {
+ 		info->consistency_policy = CONSISTENCY_POLICY_PPL;
+ 		info->ppl_sector = get_ppl_sector(super, super->current_vol);
+-		info->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9;
++		if (dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED)
++			info->ppl_size = MULTIPLE_PPL_AREA_SIZE_IMSM >> 9;
++		else
++			info->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE)
++					  >> 9;
+ 	} else if (info->array.level <= 0) {
+ 		info->consistency_policy = CONSISTENCY_POLICY_NONE;
+ 	} else {
+@@ -5390,9 +5406,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ 	dev->my_vol_raid_dev_num = mpb->num_raid_devs_created;
+ 
+ 	if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) {
+-		dev->rwh_policy = RWH_OFF;
++		dev->rwh_policy = RWH_MULTIPLE_OFF;
+ 	} else if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
+-		dev->rwh_policy = RWH_DISTRIBUTED;
++		dev->rwh_policy = RWH_MULTIPLE_DISTRIBUTED;
+ 	} else {
+ 		free(dev);
+ 		free(dv);
+@@ -7403,9 +7419,9 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
+ 			return 2;
+ 
+ 		if (strcmp(update, "ppl") == 0)
+-			new_policy = RWH_DISTRIBUTED;
++			new_policy = RWH_MULTIPLE_DISTRIBUTED;
+ 		else
+-			new_policy = RWH_OFF;
++			new_policy = RWH_MULTIPLE_OFF;
+ 
+ 		if (st->update_tail) {
+ 			struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u));
+@@ -8205,7 +8221,8 @@ skip_mark_checkpoint:
+ 			dev->vol.dirty = RAIDVOL_CLEAN;
+ 		} else {
+ 			dev->vol.dirty = RAIDVOL_DIRTY;
+-			if (dev->rwh_policy == RWH_DISTRIBUTED)
++			if (dev->rwh_policy == RWH_DISTRIBUTED ||
++			    dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED)
+ 				dev->vol.dirty |= RAIDVOL_DSRECORD_VALID;
+ 		}
+ 		super->updates_pending++;
+@@ -8759,7 +8776,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
+ 		di->bb.supported = 1;
+ 		if (a->info.consistency_policy == CONSISTENCY_POLICY_PPL) {
+ 			di->ppl_sector = get_ppl_sector(super, inst);
+-			di->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9;
++			di->ppl_size = MULTIPLE_PPL_AREA_SIZE_IMSM >> 9;
+ 		}
+ 		super->random = random32();
+ 		di->next = rv;
+-- 
+2.7.4
+
diff --git a/SOURCES/kernel-patch-Remove-obsolete-kernel-patches-against-.patch b/SOURCES/kernel-patch-Remove-obsolete-kernel-patches-against-.patch
new file mode 100644
index 0000000..7db2c88
--- /dev/null
+++ b/SOURCES/kernel-patch-Remove-obsolete-kernel-patches-against-.patch
@@ -0,0 +1,395 @@
+From 2b7bddf06c30da08f8d6270b40f0d382c1c5fc6e Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 4 May 2017 11:39:05 -0400
+Subject: [RHEL7.5 PATCH 107/169] kernel-patch: Remove obsolete kernel
+ patches against 2.6
+
+While we still support some of these kernels, I do not think it makes
+sense to carry this patches around at this point.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ kernel-patch-2.6.18   |  35 ---------
+ kernel-patch-2.6.18.6 |  35 ---------
+ kernel-patch-2.6.19   |  34 ---------
+ kernel-patch-2.6.25   | 199 --------------------------------------------------
+ kernel-patch-2.6.27   |  36 ---------
+ 5 files changed, 339 deletions(-)
+ delete mode 100644 kernel-patch-2.6.18
+ delete mode 100644 kernel-patch-2.6.18.6
+ delete mode 100644 kernel-patch-2.6.19
+ delete mode 100644 kernel-patch-2.6.25
+ delete mode 100644 kernel-patch-2.6.27
+
+diff --git a/kernel-patch-2.6.18 b/kernel-patch-2.6.18
+deleted file mode 100644
+index 87496ea..0000000
+--- a/kernel-patch-2.6.18
++++ /dev/null
+@@ -1,35 +0,0 @@
+-
+-### Diffstat output
+- ./drivers/md/md.c |    6 +++++-
+- 1 file changed, 5 insertions(+), 1 deletion(-)
+-
+-diff .prev/drivers/md/md.c ./drivers/md/md.c
+---- .prev/drivers/md/md.c	2006-10-23 10:26:37.000000000 +1000
+-+++ ./drivers/md/md.c	2006-12-21 16:28:29.000000000 +1100
+-@@ -1783,7 +1783,8 @@ state_store(mdk_rdev_t *rdev, const char
+- 		else {
+- 			mddev_t *mddev = rdev->mddev;
+- 			kick_rdev_from_array(rdev);
+--			md_update_sb(mddev);
+-+			if (mddev->pers)
+-+				md_update_sb(mddev);
+- 			md_new_event(mddev);
+- 			err = 0;
+- 		}
+-@@ -1994,6 +1995,8 @@ static mdk_rdev_t *md_import_device(dev_
+- 	kobject_init(&rdev->kobj);
+- 
+- 	rdev->desc_nr = -1;
+-+	rdev->saved_raid_disk = -1;
+-+	rdev->raid_disk = -1;
+- 	rdev->flags = 0;
+- 	rdev->data_offset = 0;
+- 	rdev->sb_events = 0;
+-@@ -3991,6 +3994,7 @@ static int set_array_info(mddev_t * mdde
+- 		mddev->major_version = info->major_version;
+- 		mddev->minor_version = info->minor_version;
+- 		mddev->patch_version = info->patch_version;
+-+		mddev->persistent = ! info->not_persistent;
+- 		return 0;
+- 	}
+- 	mddev->major_version = MD_MAJOR_VERSION;
+diff --git a/kernel-patch-2.6.18.6 b/kernel-patch-2.6.18.6
+deleted file mode 100644
+index e702e14..0000000
+--- a/kernel-patch-2.6.18.6
++++ /dev/null
+@@ -1,35 +0,0 @@
+-Signed-off-by: Neil Brown <neilb@suse.de>
+-
+-### Diffstat output
+- ./drivers/md/md.c |    5 ++++-
+- 1 file changed, 4 insertions(+), 1 deletion(-)
+-
+-diff .prev/drivers/md/md.c ./drivers/md/md.c
+---- .prev/drivers/md/md.c	2006-12-21 17:08:23.000000000 +1100
+-+++ ./drivers/md/md.c	2006-12-21 17:08:26.000000000 +1100
+-@@ -1783,7 +1783,8 @@ state_store(mdk_rdev_t *rdev, const char
+- 		else {
+- 			mddev_t *mddev = rdev->mddev;
+- 			kick_rdev_from_array(rdev);
+--			md_update_sb(mddev);
+-+			if (mddev->pers)
+-+				md_update_sb(mddev);
+- 			md_new_event(mddev);
+- 			err = 0;
+- 		}
+-@@ -1995,6 +1996,7 @@ static mdk_rdev_t *md_import_device(dev_
+- 
+- 	rdev->desc_nr = -1;
+- 	rdev->saved_raid_disk = -1;
+-+	rdev->raid_disk = -1;
+- 	rdev->flags = 0;
+- 	rdev->data_offset = 0;
+- 	rdev->sb_events = 0;
+-@@ -3993,6 +3995,7 @@ static int set_array_info(mddev_t * mdde
+- 		mddev->major_version = info->major_version;
+- 		mddev->minor_version = info->minor_version;
+- 		mddev->patch_version = info->patch_version;
+-+		mddev->persistent = ! info->not_persistent;
+- 		return 0;
+- 	}
+- 	mddev->major_version = MD_MAJOR_VERSION;
+diff --git a/kernel-patch-2.6.19 b/kernel-patch-2.6.19
+deleted file mode 100644
+index 22a67a3..0000000
+--- a/kernel-patch-2.6.19
++++ /dev/null
+@@ -1,34 +0,0 @@
+-
+-### Diffstat output
+- ./drivers/md/md.c |    5 ++++-
+- 1 file changed, 4 insertions(+), 1 deletion(-)
+-
+-diff .prev/drivers/md/md.c ./drivers/md/md.c
+---- .prev/drivers/md/md.c	2006-12-21 15:55:01.000000000 +1100
+-+++ ./drivers/md/md.c	2006-12-21 16:28:09.000000000 +1100
+-@@ -1792,7 +1792,8 @@ state_store(mdk_rdev_t *rdev, const char
+- 		else {
+- 			mddev_t *mddev = rdev->mddev;
+- 			kick_rdev_from_array(rdev);
+--			md_update_sb(mddev, 1);
+-+			if (mddev->pers)
+-+				md_update_sb(mddev, 1);
+- 			md_new_event(mddev);
+- 			err = 0;
+- 		}
+-@@ -2004,6 +2005,7 @@ static mdk_rdev_t *md_import_device(dev_
+- 
+- 	rdev->desc_nr = -1;
+- 	rdev->saved_raid_disk = -1;
+-+	rdev->raid_disk = -1;
+- 	rdev->flags = 0;
+- 	rdev->data_offset = 0;
+- 	rdev->sb_events = 0;
+-@@ -3977,6 +3979,7 @@ static int set_array_info(mddev_t * mdde
+- 		mddev->major_version = info->major_version;
+- 		mddev->minor_version = info->minor_version;
+- 		mddev->patch_version = info->patch_version;
+-+		mddev->persistent = ! info->not_persistent;
+- 		return 0;
+- 	}
+- 	mddev->major_version = MD_MAJOR_VERSION;
+diff --git a/kernel-patch-2.6.25 b/kernel-patch-2.6.25
+deleted file mode 100644
+index 2329007..0000000
+--- a/kernel-patch-2.6.25
++++ /dev/null
+@@ -1,199 +0,0 @@
+-Status: ok
+-
+-Support adding a spare to a live md array with external metadata.
+-
+-i.e. extend the 'md/dev-XXX/slot' attribute so that you can
+-tell a device to fill an vacant slot in an and md array.
+-
+-
+-Signed-off-by: Neil Brown <neilb@suse.de>
+-
+-### Diffstat output
+- ./drivers/md/md.c        |   44 ++++++++++++++++++++++++++++++++++++++++----
+- ./drivers/md/multipath.c |    7 ++++++-
+- ./drivers/md/raid1.c     |    7 ++++++-
+- ./drivers/md/raid10.c    |   10 ++++++++--
+- ./drivers/md/raid5.c     |   10 ++++++++--
+- 5 files changed, 68 insertions(+), 10 deletions(-)
+-
+-diff .prev/drivers/md/md.c ./drivers/md/md.c
+---- .prev/drivers/md/md.c	2008-06-05 09:19:56.000000000 +1000
+-+++ ./drivers/md/md.c	2008-06-10 10:41:21.000000000 +1000
+-@@ -1932,7 +1932,7 @@ slot_store(mdk_rdev_t *rdev, const char 
+- 		slot = -1;
+- 	else if (e==buf || (*e && *e!= '\n'))
+- 		return -EINVAL;
+--	if (rdev->mddev->pers) {
+-+	if (rdev->mddev->pers && slot == -1) {
+- 		/* Setting 'slot' on an active array requires also
+- 		 * updating the 'rd%d' link, and communicating
+- 		 * with the personality with ->hot_*_disk.
+-@@ -1940,8 +1940,6 @@ slot_store(mdk_rdev_t *rdev, const char 
+- 		 * failed/spare devices.  This normally happens automatically,
+- 		 * but not when the metadata is externally managed.
+- 		 */
+--		if (slot != -1)
+--			return -EBUSY;
+- 		if (rdev->raid_disk == -1)
+- 			return -EEXIST;
+- 		/* personality does all needed checks */
+-@@ -1955,6 +1953,44 @@ slot_store(mdk_rdev_t *rdev, const char 
+- 		sysfs_remove_link(&rdev->mddev->kobj, nm);
+- 		set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
+- 		md_wakeup_thread(rdev->mddev->thread);
+-+	} else if (rdev->mddev->pers) {
+-+		mdk_rdev_t *rdev2;
+-+		struct list_head *tmp;
+-+		/* Activating a spare .. or possibly reactivating
+-+		 * if we every get bitmaps working here.
+-+		 */
+-+
+-+		if (rdev->raid_disk != -1)
+-+			return -EBUSY;
+-+
+-+		if (rdev->mddev->pers->hot_add_disk == NULL)
+-+			return -EINVAL;
+-+
+-+		rdev_for_each(rdev2, tmp, rdev->mddev)
+-+			if (rdev2->raid_disk == slot)
+-+				return -EEXIST;
+-+
+-+		rdev->raid_disk = slot;
+-+		if (test_bit(In_sync, &rdev->flags))
+-+			rdev->saved_raid_disk = slot;
+-+		else
+-+			rdev->saved_raid_disk = -1;
+-+		err = rdev->mddev->pers->
+-+			hot_add_disk(rdev->mddev, rdev);
+-+		if (err != 1) {
+-+			rdev->raid_disk = -1;
+-+			if (err == 0)
+-+				return -EEXIST;
+-+			return err;
+-+		}
+-+		sprintf(nm, "rd%d", rdev->raid_disk);
+-+		if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm))
+-+			printk(KERN_WARNING
+-+			       "md: cannot register "
+-+			       "%s for %s\n",
+-+			       nm, mdname(rdev->mddev));
+-+
+-+		/* don't wakeup anyone, leave that to userspace. */
+- 	} else {
+- 		if (slot >= rdev->mddev->raid_disks)
+- 			return -ENOSPC;
+-@@ -4205,7 +4241,7 @@ static int add_new_disk(mddev_t * mddev,
+- 			super_types[mddev->major_version].
+- 				validate_super(mddev, rdev);
+- 			err = mddev->pers->hot_add_disk(mddev, rdev);
+--			if (err)
+-+			if (err < 0)
+- 				unbind_rdev_from_array(rdev);
+- 		}
+- 		if (err)
+-
+-diff .prev/drivers/md/multipath.c ./drivers/md/multipath.c
+---- .prev/drivers/md/multipath.c	2008-05-30 14:49:31.000000000 +1000
+-+++ ./drivers/md/multipath.c	2008-06-10 10:35:03.000000000 +1000
+-@@ -284,10 +284,15 @@ static int multipath_add_disk(mddev_t *m
+- 	int found = 0;
+- 	int path;
+- 	struct multipath_info *p;
+-+	int first = 0;
+-+	int last = mddev->raid_disks - 1;
+-+
+-+	if (rdev->raid_disk >= 0)
+-+		first = last = rdev->raid_disk;
+- 
+- 	print_multipath_conf(conf);
+- 
+--	for (path=0; path<mddev->raid_disks; path++) 
+-+	for (path = first; path <= last; path++)
+- 		if ((p=conf->multipaths+path)->rdev == NULL) {
+- 			q = rdev->bdev->bd_disk->queue;
+- 			blk_queue_stack_limits(mddev->queue, q);
+-
+-diff .prev/drivers/md/raid10.c ./drivers/md/raid10.c
+---- .prev/drivers/md/raid10.c	2008-05-30 14:49:31.000000000 +1000
+-+++ ./drivers/md/raid10.c	2008-06-10 10:28:53.000000000 +1000
+-@@ -1116,6 +1116,8 @@ static int raid10_add_disk(mddev_t *mdde
+- 	int found = 0;
+- 	int mirror;
+- 	mirror_info_t *p;
+-+	int first = 0;
+-+	int last = mddev->raid_disks - 1;
+- 
+- 	if (mddev->recovery_cp < MaxSector)
+- 		/* only hot-add to in-sync arrays, as recovery is
+-@@ -1125,12 +1127,16 @@ static int raid10_add_disk(mddev_t *mdde
+- 	if (!enough(conf))
+- 		return 0;
+- 
+-+	if (rdev->raid_disk)
+-+		first = last = rdev->raid_disk;
+-+
+- 	if (rdev->saved_raid_disk >= 0 &&
+-+	    rdev->saved_raid_disk >= first &&
+- 	    conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
+- 		mirror = rdev->saved_raid_disk;
+- 	else
+--		mirror = 0;
+--	for ( ; mirror < mddev->raid_disks; mirror++)
+-+		mirror = first;
+-+	for ( ; mirror <= last ; mirror++)
+- 		if ( !(p=conf->mirrors+mirror)->rdev) {
+- 
+- 			blk_queue_stack_limits(mddev->queue,
+-
+-diff .prev/drivers/md/raid1.c ./drivers/md/raid1.c
+---- .prev/drivers/md/raid1.c	2008-05-30 14:49:31.000000000 +1000
+-+++ ./drivers/md/raid1.c	2008-06-10 10:41:00.000000000 +1000
+-@@ -1103,8 +1103,13 @@ static int raid1_add_disk(mddev_t *mddev
+- 	int found = 0;
+- 	int mirror = 0;
+- 	mirror_info_t *p;
+-+	int first = 0;
+-+	int last = mddev->raid_disks - 1;
+- 
+--	for (mirror=0; mirror < mddev->raid_disks; mirror++)
+-+	if (rdev->raid_disk >= 0)
+-+		first = last = rdev->raid_disk;
+-+
+-+	for (mirror = first; mirror <= last; mirror++)
+- 		if ( !(p=conf->mirrors+mirror)->rdev) {
+- 
+- 			blk_queue_stack_limits(mddev->queue,
+-
+-diff .prev/drivers/md/raid5.c ./drivers/md/raid5.c
+---- .prev/drivers/md/raid5.c	2008-05-30 14:49:35.000000000 +1000
+-+++ ./drivers/md/raid5.c	2008-06-10 10:27:51.000000000 +1000
+-@@ -4399,21 +4399,27 @@ static int raid5_add_disk(mddev_t *mddev
+- 	int found = 0;
+- 	int disk;
+- 	struct disk_info *p;
+-+	int first = 0;
+-+	int last = conf->raid_disks - 1;
+- 
+- 	if (mddev->degraded > conf->max_degraded)
+- 		/* no point adding a device */
+- 		return 0;
+- 
+-+	if (rdev->raid_disk >= 0)
+-+		first = last = rdev->raid_disk;
+-+
+- 	/*
+- 	 * find the disk ... but prefer rdev->saved_raid_disk
+- 	 * if possible.
+- 	 */
+- 	if (rdev->saved_raid_disk >= 0 &&
+-+	    rdev->saved_raid_disk >= first &&
+- 	    conf->disks[rdev->saved_raid_disk].rdev == NULL)
+- 		disk = rdev->saved_raid_disk;
+- 	else
+--		disk = 0;
+--	for ( ; disk < conf->raid_disks; disk++)
+-+		disk = first;
+-+	for ( ; disk <= last ; disk++)
+- 		if ((p=conf->disks + disk)->rdev == NULL) {
+- 			clear_bit(In_sync, &rdev->flags);
+- 			rdev->raid_disk = disk;
+diff --git a/kernel-patch-2.6.27 b/kernel-patch-2.6.27
+deleted file mode 100644
+index 8d0785d..0000000
+--- a/kernel-patch-2.6.27
++++ /dev/null
+@@ -1,36 +0,0 @@
+-touch_mnt_namespace when the mount flags change
+-
+-From: Dan Williams <dan.j.williams@intel.com>
+-
+-Daemons that need to be launched while the rootfs is read-only can now
+-poll /proc/mounts to be notified when their O_RDWR requests may no
+-longer end in EROFS.
+-
+-Cc: Kay Sievers <kay.sievers@vrfy.org>
+-Cc: Neil Brown <neilb@suse.de>
+-Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+----
+-
+- fs/namespace.c |    7 ++++++-
+- 1 files changed, 6 insertions(+), 1 deletions(-)
+-
+-
+-diff --git a/fs/namespace.c b/fs/namespace.c
+-index 6e283c9..1bd5ba2 100644
+---- a/fs/namespace.c
+-+++ b/fs/namespace.c
+-@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
+- 	if (!err)
+- 		nd->path.mnt->mnt_flags = mnt_flags;
+- 	up_write(&sb->s_umount);
+--	if (!err)
+-+	if (!err) {
+- 		security_sb_post_remount(nd->path.mnt, flags, data);
+-+
+-+		spin_lock(&vfsmount_lock);
+-+		touch_mnt_namespace(nd->path.mnt->mnt_ns);
+-+		spin_unlock(&vfsmount_lock);
+-+	}
+- 	return err;
+- }
+- 
+-- 
+2.7.4
+
diff --git a/SOURCES/lib-devid2kname-should-take-a-dev_t.patch b/SOURCES/lib-devid2kname-should-take-a-dev_t.patch
new file mode 100644
index 0000000..89c1617
--- /dev/null
+++ b/SOURCES/lib-devid2kname-should-take-a-dev_t.patch
@@ -0,0 +1,52 @@
+From d3c40faba807e3c7a63c5fe34de52bf753c88b2d Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 29 Sep 2017 17:54:12 -0400
+Subject: [RHEL7.5 PATCH 10/13] lib: devid2kname() should take a dev_t
+
+Make devid2kname() and devid2devnm() consistent in their APIs
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ lib.c   | 5 ++---
+ mdadm.h | 2 +-
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/lib.c b/lib.c
+index be093e8..60890b9 100644
+--- a/lib.c
++++ b/lib.c
+@@ -61,7 +61,7 @@ int get_mdp_major(void)
+ 	return mdp_major;
+ }
+ 
+-char *devid2kname(int devid)
++char *devid2kname(dev_t devid)
+ {
+ 	char path[30];
+ 	char link[PATH_MAX];
+@@ -73,8 +73,7 @@ char *devid2kname(int devid)
+ 	 * /sys/dev/block/%d:%d link which must look like
+ 	 * and take the last component.
+ 	 */
+-	sprintf(path, "/sys/dev/block/%d:%d", major(devid),
+-		minor(devid));
++	sprintf(path, "/sys/dev/block/%d:%d", major(devid), minor(devid));
+ 	n = readlink(path, link, sizeof(link) - 1);
+ 	if (n > 0) {
+ 		link[n] = 0;
+diff --git a/mdadm.h b/mdadm.h
+index 191ae8f..db08188 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1537,7 +1537,7 @@ extern void print_r10_layout(int layout);
+ extern char *find_free_devnm(int use_partitions);
+ 
+ extern void put_md_name(char *name);
+-extern char *devid2kname(int devid);
++extern char *devid2kname(dev_t devid);
+ extern char *devid2devnm(dev_t devid);
+ extern dev_t devnm2devid(char *devnm);
+ extern char *get_md_name(char *devnm);
+-- 
+2.7.4
+
diff --git a/SOURCES/managemon-Dont-add-disk-to-the-array-after-it.patch b/SOURCES/managemon-Dont-add-disk-to-the-array-after-it.patch
new file mode 100644
index 0000000..c2ed2bf
--- /dev/null
+++ b/SOURCES/managemon-Dont-add-disk-to-the-array-after-it.patch
@@ -0,0 +1,61 @@
+commit a44c262abc49b3c69ee80c97813388e5d021d20b
+Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date:   Thu Dec 7 10:23:54 2017 +0100
+
+    managemon: Don't add disk to the array after it has started
+    
+    If disk has disappeared from the system and appears again, it is added to the
+    corresponding container as long the metadata matches and disk number is set.
+    This code had no effect on imsm until commit 20dc76d15b40 ("imsm: Set disk slot
+    number"). Now the disk is added to container but not to the array - it is
+    correct as the disk is out-of-sync. Rebuild should start for the disk but it
+    doesn't. There is the same behaviour for both imsm and ddf metadata.
+    
+    There is no point to handle out-of-sync disk as "good member of array" so
+    remove that part of code. There are no scenarios when monitor is already
+    running and disk can be safely added to the array. Just write initial metadata
+    to the disk so it's taken for rebuild.
+    
+    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/managemon.c b/managemon.c
+index 4e85398..101231c 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -266,9 +266,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
+ {
+ 	int dfd;
+ 	char nm[20];
+-	struct supertype *st2;
+ 	struct metadata_update *update = NULL;
+-	struct mdinfo info;
+ 	mdu_disk_info_t dk = {
+ 		.number = -1,
+ 		.major = sd->disk.major,
+@@ -287,25 +285,6 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
+ 	if (dfd < 0)
+ 		return;
+ 
+-	/* Check the metadata and see if it is already part of this
+-	 * array
+-	 */
+-	st2 = dup_super(st);
+-	if (st2->ss->load_super(st2, dfd, NULL) == 0) {
+-		st2->ss->getinfo_super(st2, &info, NULL);
+-		if (st->ss->compare_super(st, st2) == 0 &&
+-		    info.disk.raid_disk >= 0) {
+-			/* Looks like a good member of array.
+-			 * Just accept it.
+-			 * mdadm will incorporate any parts into
+-			 * active arrays.
+-			 */
+-			st2->ss->free_super(st2);
+-			return;
+-		}
+-	}
+-	st2->ss->free_super(st2);
+-
+ 	st->update_tail = &update;
+ 	st->ss->add_to_super(st, &dk, dfd, NULL, INVALID_SECTORS);
+ 	st->ss->write_init_super(st);
diff --git a/SOURCES/manpage-badblock-support-for-IMSM.patch b/SOURCES/manpage-badblock-support-for-IMSM.patch
new file mode 100644
index 0000000..33b710b
--- /dev/null
+++ b/SOURCES/manpage-badblock-support-for-IMSM.patch
@@ -0,0 +1,29 @@
+From 8fac4a54cbafdd8e0a6a0c0b3ce87f1bcdef3d9d Mon Sep 17 00:00:00 2001
+From: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date: Thu, 18 May 2017 15:14:49 +0200
+Subject: [RHEL7.5 PATCH 146/169] manpage: bad block support for IMSM
+
+Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 388e0ed..ecfe9da 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -2211,8 +2211,8 @@ option. In any case space for a bitmap will be reserved so that one
+ can be added later with
+ .BR "\-\-grow \-\-bitmap=internal" .
+ 
+-If the metadata type supports it (currently only 1.x metadata), space
+-will be allocated to store a bad block list.  This allows a modest
++If the metadata type supports it (currently only 1.x and IMSM metadata),
++space will be allocated to store a bad block list.  This allows a modest
+ number of bad blocks to be recorded, allowing the drive to remain in
+ service while only partially functional.
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/maps-Remove-incorrect-comment-about-strcmp.patch b/SOURCES/maps-Remove-incorrect-comment-about-strcmp.patch
new file mode 100644
index 0000000..1de54bd
--- /dev/null
+++ b/SOURCES/maps-Remove-incorrect-comment-about-strcmp.patch
@@ -0,0 +1,29 @@
+From 966188e959ec198889bec6d2f9dac34bff97478f Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 21 Apr 2017 12:09:12 -0400
+Subject: [RHEL7.5 PATCH 092/169] maps: Remove incorrect comment about
+ strcmp()
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ maps.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/maps.c b/maps.c
+index 11dd3d2..81f29c4 100644
+--- a/maps.c
++++ b/maps.c
+@@ -141,10 +141,6 @@ mapping_t consistency_policies[] = {
+ };
+ 
+ mapping_t sysfs_array_states[] = {
+-	/*
+-	 * Beware map_name() uses strcmp() so active-idle must come before
+-	 * active, to be detected correctly.
+-	 */
+ 	{ "active-idle", ARRAY_ACTIVE_IDLE },
+ 	{ "active", ARRAY_ACTIVE },
+ 	{ "clear", ARRAY_CLEAR },
+-- 
+2.7.4
+
diff --git a/SOURCES/maps-Simplify-implementation-of-map_name.patch b/SOURCES/maps-Simplify-implementation-of-map_name.patch
new file mode 100644
index 0000000..6c458e4
--- /dev/null
+++ b/SOURCES/maps-Simplify-implementation-of-map_name.patch
@@ -0,0 +1,32 @@
+From 4a4379b054a72b3c4abd93dd6e1283d6aa992ee2 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 21 Apr 2017 12:11:21 -0400
+Subject: [RHEL7.5 PATCH 093/169] maps: Simplify implementation of
+ map_name()
+
+Reported-By: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ maps.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/maps.c b/maps.c
+index 81f29c4..bb28ba6 100644
+--- a/maps.c
++++ b/maps.c
+@@ -165,11 +165,8 @@ char *map_num(mapping_t *map, int num)
+ 
+ int map_name(mapping_t *map, char *name)
+ {
+-	while (map->name) {
+-		if (strcmp(map->name, name)==0)
+-			return map->num;
++	while (map->name && strcmp(map->name, name) != 0)
+ 		map++;
+-	}
+ 
+ 	return map->num;
+ }
+-- 
+2.7.4
+
diff --git a/SOURCES/maps-Terminate-modes-map-correctly.patch b/SOURCES/maps-Terminate-modes-map-correctly.patch
new file mode 100644
index 0000000..8be6f4b
--- /dev/null
+++ b/SOURCES/maps-Terminate-modes-map-correctly.patch
@@ -0,0 +1,28 @@
+From e47781fcea24778a16e4be53e5b84eab8db9413c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 20 Apr 2017 00:13:31 -0400
+Subject: [RHEL7.5 PATCH 083/169] maps: Terminate 'modes' map correctly.
+
+While we are unlikely to fail here, terminate the modes map correctly
+to ensure we don't start running over undefined data.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ maps.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/maps.c b/maps.c
+index a8a4639..a2d293b 100644
+--- a/maps.c
++++ b/maps.c
+@@ -106,6 +106,7 @@ mapping_t modes[] = {
+ 	{ "grow", GROW},
+ 	{ "incremental", INCREMENTAL},
+ 	{ "auto-detect", AUTODETECT},
++	{ NULL, 0 }
+ };
+ 
+ mapping_t faultylayout[] = {
+-- 
+2.7.4
+
diff --git a/SOURCES/maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch b/SOURCES/maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch
new file mode 100644
index 0000000..2b8d89a
--- /dev/null
+++ b/SOURCES/maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch
@@ -0,0 +1,106 @@
+From 5e8e35fb7e17495032e144f319517dcae38d1b56 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 20 Apr 2017 00:19:44 -0400
+Subject: [RHEL7.5 PATCH 084/169] maps: Use keyvalue for null terminator to
+ indicate 'unset' value
+
+This simplifies the code calling map_name() so it no longer has to
+manually check for UnSet and convert the value manually.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ maps.c  | 17 +++++++++--------
+ sysfs.c |  2 --
+ 2 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/maps.c b/maps.c
+index a2d293b..11dd3d2 100644
+--- a/maps.c
++++ b/maps.c
+@@ -44,7 +44,7 @@ mapping_t r5layout[] = {
+ 	{ "ddf-N-restart", ALGORITHM_LEFT_ASYMMETRIC},
+ 	{ "ddf-N-continue", ALGORITHM_LEFT_SYMMETRIC},
+ 
+-	{ NULL, 0}
++	{ NULL, UnSet }
+ };
+ mapping_t r6layout[] = {
+ 	{ "left-asymmetric", ALGORITHM_LEFT_ASYMMETRIC},
+@@ -70,7 +70,7 @@ mapping_t r6layout[] = {
+ 	{ "right-symmetric-6", ALGORITHM_RIGHT_SYMMETRIC_6},
+ 	{ "parity-first-6", ALGORITHM_PARITY_0_6},
+ 
+-	{ NULL, 0}
++	{ NULL, UnSet }
+ };
+ 
+ mapping_t pers[] = {
+@@ -93,7 +93,7 @@ mapping_t pers[] = {
+ 	{ "10", 10},
+ 	{ "faulty", LEVEL_FAULTY},
+ 	{ "container", LEVEL_CONTAINER},
+-	{ NULL, 0}
++	{ NULL, UnSet }
+ };
+ 
+ mapping_t modes[] = {
+@@ -106,7 +106,7 @@ mapping_t modes[] = {
+ 	{ "grow", GROW},
+ 	{ "incremental", INCREMENTAL},
+ 	{ "auto-detect", AUTODETECT},
+-	{ NULL, 0 }
++	{ NULL, UnSet }
+ };
+ 
+ mapping_t faultylayout[] = {
+@@ -127,7 +127,7 @@ mapping_t faultylayout[] = {
+ 	{ "flush", ClearFaults},
+ 	{ "none", ClearErrors},
+ 	{ "default", ClearErrors},
+-	{ NULL, 0}
++	{ NULL, UnSet }
+ };
+ 
+ mapping_t consistency_policies[] = {
+@@ -137,7 +137,7 @@ mapping_t consistency_policies[] = {
+ 	{ "bitmap", CONSISTENCY_POLICY_BITMAP},
+ 	{ "journal", CONSISTENCY_POLICY_JOURNAL},
+ 	{ "ppl", CONSISTENCY_POLICY_PPL},
+-	{ NULL, 0}
++	{ NULL, UnSet }
+ };
+ 
+ mapping_t sysfs_array_states[] = {
+@@ -154,7 +154,7 @@ mapping_t sysfs_array_states[] = {
+ 	{ "read-auto", ARRAY_READ_AUTO },
+ 	{ "clean", ARRAY_CLEAN },
+ 	{ "write-pending", ARRAY_WRITE_PENDING },
+-	{ NULL, 0 }
++	{ NULL, ARRAY_UNKNOWN_STATE }
+ };
+ 
+ char *map_num(mapping_t *map, int num)
+@@ -174,5 +174,6 @@ int map_name(mapping_t *map, char *name)
+ 			return map->num;
+ 		map++;
+ 	}
+-	return UnSet;
++
++	return map->num;
+ }
+diff --git a/sysfs.c b/sysfs.c
+index c6df9b0..712f8b3 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -250,8 +250,6 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 		if (load_sys(fname, buf, sizeof(buf)))
+ 			goto abort;
+ 		sra->array_state = map_name(sysfs_array_states, buf);
+-		if (sra->array_state == UnSet)
+-			sra->array_state = ARRAY_UNKNOWN_STATE;
+ 	}
+ 
+ 	if (options & GET_CONSISTENCY_POLICY) {
+-- 
+2.7.4
+
diff --git a/SOURCES/md_u-Remove-some-unused-ioctl-declarations.patch b/SOURCES/md_u-Remove-some-unused-ioctl-declarations.patch
new file mode 100644
index 0000000..2c580c6
--- /dev/null
+++ b/SOURCES/md_u-Remove-some-unused-ioctl-declarations.patch
@@ -0,0 +1,40 @@
+From b0ba6a1dee995b3cd7331b4df92d115e51d8ac0c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 15:48:24 -0400
+Subject: [RHEL7.5 PATCH 041/169] md_u: Remove some unused ioctl
+ declarations
+
+These were no longer used in the code, so get rid of them.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ md_u.h | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/md_u.h b/md_u.h
+index f570a34..d59aa2d 100644
+--- a/md_u.h
++++ b/md_u.h
+@@ -21,19 +21,13 @@
+ #define RAID_VERSION		_IOR (MD_MAJOR, 0x10, mdu_version_t)
+ #define GET_ARRAY_INFO		_IOR (MD_MAJOR, 0x11, mdu_array_info_t)
+ #define GET_DISK_INFO		_IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
+-#define PRINT_RAID_DEBUG	_IO (MD_MAJOR, 0x13)
+ #define RAID_AUTORUN		_IO (MD_MAJOR, 0x14)
+ #define GET_BITMAP_FILE		_IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t)
+ 
+ /* configuration */
+-#define CLEAR_ARRAY		_IO (MD_MAJOR, 0x20)
+ #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 SET_DISK_INFO		_IO (MD_MAJOR, 0x24)
+-#define WRITE_RAID_INFO		_IO (MD_MAJOR, 0x25)
+-#define UNPROTECT_ARRAY		_IO (MD_MAJOR, 0x26)
+-#define PROTECT_ARRAY		_IO (MD_MAJOR, 0x27)
+ #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.4
+
diff --git a/SOURCES/md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch b/SOURCES/md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch
new file mode 100644
index 0000000..4e17568
--- /dev/null
+++ b/SOURCES/md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch
@@ -0,0 +1,31 @@
+From ea1c4a8722605da9c2ce5dd1a8324b4f23a34b7a Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 31 May 2017 19:38:36 +0800
+Subject: [RHEL7.5 PATCH 149/169] md_u: Remove unused ioctl declaration of
+ START_ARRAY
+
+START_ARRAY is no longer used in the code, so get rid of it.
+MD commit: fbedac04fa11 ("[PATCH] md: the scheduled removal
+of the START_ARRAY ioctl for md") merged in the year 2006.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ md_u.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/md_u.h b/md_u.h
+index d59aa2d..2d66d52 100644
+--- a/md_u.h
++++ b/md_u.h
+@@ -34,7 +34,6 @@
+ 
+ /* usage */
+ #define RUN_ARRAY		_IOW (MD_MAJOR, 0x30, mdu_param_t)
+-#define START_ARRAY		_IO (MD_MAJOR, 0x31)
+ #define STOP_ARRAY		_IO (MD_MAJOR, 0x32)
+ #define STOP_ARRAY_RO		_IO (MD_MAJOR, 0x33)
+ #define RESTART_ARRAY_RW	_IO (MD_MAJOR, 0x34)
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-3.3-udev.patch b/SOURCES/mdadm-3.3-udev.patch
index 1dfac7b..8483d5c 100644
--- a/SOURCES/mdadm-3.3-udev.patch
+++ b/SOURCES/mdadm-3.3-udev.patch
@@ -1,5 +1,5 @@
---- mdadm-3.3.1/udev-md-raid-assembly.rules~	2014-06-10 13:29:41.192829830 +0200
-+++ mdadm-3.3.1/udev-md-raid-assembly.rules	2014-06-10 13:30:20.838613208 +0200
+--- mdadm/udev-md-raid-assembly.rules~	2017-09-19 11:22:49.912766829 +0800
++++ mdadm/udev-md-raid-assembly.rules	2017-09-19 11:23:23.951809560 +0800
 @@ -5,6 +5,10 @@
  ENV{ANACONDA}=="?*", GOTO="md_inc_end"
  # assemble md arrays
@@ -10,4 +10,4 @@
 +
  SUBSYSTEM!="block", GOTO="md_inc_end"
  
- # handle potential components of arrays (the ones supported by md)
+ # skip non-initialized devices
diff --git a/SOURCES/mdadm-3.3.2-skip-rules.patch b/SOURCES/mdadm-3.3.2-skip-rules.patch
index ee43d23..da7794a 100644
--- a/SOURCES/mdadm-3.3.2-skip-rules.patch
+++ b/SOURCES/mdadm-3.3.2-skip-rules.patch
@@ -1,11 +1,11 @@
---- mdadm-3.4/Makefile~	2016-02-01 22:59:47.327994011 +0800
-+++ mdadm-3.4/Makefile	2016-02-02 10:18:51.165377518 +0800
-@@ -292,7 +292,7 @@
+--- mdadm/Makefile~	2017-09-19 11:09:05.788484060 +0800
++++ mdadm/Makefile	2017-09-19 11:09:26.956482310 +0800
+@@ -257,7 +257,7 @@
  	$(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
  
- install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules
--	@for file in 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \
-+	@for file in 63-md-raid-arrays.rules ; \
+ install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid-creating.rules
+-	@for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \
++	@for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules ; \
  	do sed -e 's,BINDIR,$(BINDIR),g' udev-$${file#??-} > .install.tmp.1 && \
  	   $(ECHO) $(INSTALL) -D -m 644 udev-$${file#??-} $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \
  	   $(INSTALL) -D -m 644 .install.tmp.1 $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \
diff --git a/SOURCES/mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch b/SOURCES/mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch
new file mode 100644
index 0000000..4615fab
--- /dev/null
+++ b/SOURCES/mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch
@@ -0,0 +1,37 @@
+From 8268821b434d1308d083454fb681d80176cf352b Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Fri, 17 Mar 2017 19:55:42 +0800
+Subject: [RHEL7.5 PATCH 009/169] mdadm: Add Wimplicit-fallthrough=0 in
+ Makefile
+
+There are many errors like 'error: this statement may fall through'.
+But the logic is right. So add the flag Wimplicit-fallthrough=0
+to disable the error messages. The method I use is from
+https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
+#index-Wimplicit-fallthrough-375
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Makefile | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/Makefile b/Makefile
+index a6f464c..d1a6ac4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -48,6 +48,11 @@ ifdef WARN_UNUSED
+ CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3
+ endif
+ 
++FALLTHROUGH := $(shell gcc -v --help 2>&1 | grep "implicit-fallthrough" | wc -l)
++ifneq "$(FALLTHROUGH)"  "0"
++CWFLAGS += -Wimplicit-fallthrough=0
++endif
++
+ ifdef DEBIAN
+ CPPFLAGS += -DDEBIAN
+ endif
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Build1-check-the-level-parameter-when-build-new.patch b/SOURCES/mdadm-Build1-check-the-level-parameter-when-build-new.patch
new file mode 100644
index 0000000..b2ea514
--- /dev/null
+++ b/SOURCES/mdadm-Build1-check-the-level-parameter-when-build-new.patch
@@ -0,0 +1,34 @@
+From 1b4944f3a1e135871437cc33c26539028e6da5d6 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Tue, 28 Mar 2017 21:52:27 +0800
+Subject: [RHEL7.5 PATCH 021/169] mdadm/Build:check the level parameter
+ when build new array
+
+check if user forgets to specify the --level
+when build a new array. such as:
+./mdadm -B /dev/md0 -n2 /dev/loop[0-1]
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Build.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Build.c b/Build.c
+index 74a440e..a5fcc06 100644
+--- a/Build.c
++++ b/Build.c
+@@ -56,6 +56,10 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	int uuid[4] = {0,0,0,0};
+ 	struct map_ent *map = NULL;
+ 
++	if (s->level == UnSet) {
++		pr_err("a RAID level is needed to Build an array.\n");
++		return 1;
++	}
+ 	/* scan all devices, make sure they really are block devices */
+ 	for (dv = devlist; dv; dv=dv->next) {
+ 		subdevs++;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch b/SOURCES/mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch
new file mode 100644
index 0000000..d09f733
--- /dev/null
+++ b/SOURCES/mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch
@@ -0,0 +1,80 @@
+From ed1809969802ba03be0a33b7cd9f0ea85c7a42aa Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 11:55:19 -0400
+Subject: [RHEL7.5 PATCH 033/169] mdadm: Clean up some ugly multiple
+ actions on single line
+
+'foo(); continue;' on the same line within a switch statement is
+always wrong. Get rid of some of it.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 5ebf117..502e721 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1928,16 +1928,21 @@ static int misc_list(struct mddev_dev *devlist,
+ 			}
+ 			continue;
+ 		case 'Q':
+-			rv |= Query(dv->devname); continue;
++			rv |= Query(dv->devname);
++			continue;
+ 		case 'X':
+-			rv |= ExamineBitmap(dv->devname, c->brief, ss); continue;
++			rv |= ExamineBitmap(dv->devname, c->brief, ss);
++			continue;
+ 		case ExamineBB:
+-			rv |= ExamineBadblocks(dv->devname, c->brief, ss); continue;
++			rv |= ExamineBadblocks(dv->devname, c->brief, ss);
++			continue;
+ 		case 'W':
+ 		case WaitOpt:
+-			rv |= Wait(dv->devname); continue;
++			rv |= Wait(dv->devname);
++			continue;
+ 		case Waitclean:
+-			rv |= WaitClean(dv->devname, -1, c->verbose); continue;
++			rv |= WaitClean(dv->devname, -1, c->verbose);
++			continue;
+ 		case KillSubarray:
+ 			rv |= Kill_subarray(dv->devname, c->subarray, c->verbose);
+ 			continue;
+@@ -1964,7 +1969,8 @@ static int misc_list(struct mddev_dev *devlist,
+ 		switch(dv->devname[0] == '/') {
+ 			case 0:
+ 				mdfd = open_dev(dv->devname);
+-				if (mdfd >= 0) break;
++				if (mdfd >= 0)
++					break;
+ 			case 1:
+ 				mdfd = open_mddev(dv->devname, 1);  
+ 		}
+@@ -1972,13 +1978,17 @@ static int misc_list(struct mddev_dev *devlist,
+ 			switch(dv->disposition) {
+ 			case 'R':
+ 				c->runstop = 1;
+-				rv |= Manage_run(dv->devname, mdfd, c); break;
++				rv |= Manage_run(dv->devname, mdfd, c);
++				break;
+ 			case 'S':
+-				rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break;
++				rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0);
++				break;
+ 			case 'o':
+-				rv |= Manage_ro(dv->devname, mdfd, 1); break;
++				rv |= Manage_ro(dv->devname, mdfd, 1);
++				break;
+ 			case 'w':
+-				rv |= Manage_ro(dv->devname, mdfd, -1); break;
++				rv |= Manage_ro(dv->devname, mdfd, -1);
++				break;
+ 			}
+ 			close(mdfd);
+ 		} else
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Create-declaring1-an-existing-struct-within-sam.patch b/SOURCES/mdadm-Create-declaring1-an-existing-struct-within-sam.patch
new file mode 100644
index 0000000..2c8349c
--- /dev/null
+++ b/SOURCES/mdadm-Create-declaring1-an-existing-struct-within-sam.patch
@@ -0,0 +1,56 @@
+From 230a0dde0926125b8895e02a669b4701f79c0f07 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Sat, 1 Apr 2017 20:51:44 +0800
+Subject: [RHEL7.5 PATCH 049/169] mdadm/Create: declaring an existing
+ struct within same function
+
+Create:declaring 'struct stat stb' twice within the same
+function, rename stb as stb2 when declares 'struct stat'
+at the second time.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Create.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 32987af..ba24606 100644
+--- a/Create.c
++++ b/Create.c
+@@ -868,7 +868,7 @@ int Create(struct supertype *st, char *mddev,
+ 		for (dnum=0, raid_disk_num=0, dv = devlist ; dv ;
+ 		     dv=(dv->next)?(dv->next):moved_disk, dnum++) {
+ 			int fd;
+-			struct stat stb;
++			struct stat stb2;
+ 			struct mdinfo *inf = &infos[dnum];
+ 
+ 			if (dnum >= total_slots)
+@@ -924,9 +924,9 @@ int Create(struct supertype *st, char *mddev,
+ 							dv->devname);
+ 						goto abort_locked;
+ 					}
+-					fstat(fd, &stb);
+-					inf->disk.major = major(stb.st_rdev);
+-					inf->disk.minor = minor(stb.st_rdev);
++					fstat(fd, &stb2);
++					inf->disk.major = major(stb2.st_rdev);
++					inf->disk.minor = minor(stb2.st_rdev);
+ 				}
+ 				if (fd >= 0)
+ 					remove_partitions(fd);
+@@ -947,8 +947,8 @@ int Create(struct supertype *st, char *mddev,
+ 
+ 				if (!have_container) {
+ 					/* getinfo_super might have lost these ... */
+-					inf->disk.major = major(stb.st_rdev);
+-					inf->disk.minor = minor(stb.st_rdev);
++					inf->disk.major = major(stb2.st_rdev);
++					inf->disk.minor = minor(stb2.st_rdev);
+ 				}
+ 				break;
+ 			case 2:
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Fail-for-kernels-older-than-2.6.15.patch b/SOURCES/mdadm-Fail-for-kernels-older-than-2.6.15.patch
new file mode 100644
index 0000000..fefb45c
--- /dev/null
+++ b/SOURCES/mdadm-Fail-for-kernels-older-than-2.6.15.patch
@@ -0,0 +1,32 @@
+From dcf3d4de95d1a4cbc65b24a844173ba1c1300b55 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Thu, 6 Apr 2017 15:46:31 -0400
+Subject: [RHEL7.5 PATCH 067/169] mdadm: Fail for kernels older than 2.6.15
+
+With the removal of old kernel API support, mdadm will no longer run
+on kernels older than 2.6.15.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/mdadm.c b/mdadm.c
+index 3fe17fc..001ff68 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -120,6 +120,11 @@ int main(int argc, char *argv[])
+ 	ident.container = NULL;
+ 	ident.member = NULL;
+ 
++	if (get_linux_version() < 2006015) {
++		pr_err("This version of mdadm does not support kernels older than 2.6.15\n");
++		exit(1);
++	}
++
+ 	while ((option_index = -1),
+ 	       (opt = getopt_long(argc, argv, shortopt, long_options,
+ 				  &option_index)) != -1) {
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Fix-broken-formatting1.patch b/SOURCES/mdadm-Fix-broken-formatting1.patch
new file mode 100644
index 0000000..2d3a7a9
--- /dev/null
+++ b/SOURCES/mdadm-Fix-broken-formatting1.patch
@@ -0,0 +1,121 @@
+From b831b299e864224b389743d8a435d6629ee674e3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 16 May 2017 14:04:22 -0400
+Subject: [RHEL7.5 PATCH 144/169] mdadm: Fix '==' broken formatting
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Detail.c      |  6 +++---
+ config.c      |  4 ++--
+ managemon.c   |  4 ++--
+ super-ddf.c   | 16 ++++++++--------
+ super-intel.c |  2 +-
+ 5 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index ef2370c..bf881ff 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -714,9 +714,9 @@ This is pretty boring
+ 			if (disk.state & (1 << MD_DISK_JOURNAL))
+ 				printf(" journal");
+ 			if ((disk.state &
+-			     ((1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC)
+-			      |(1<<MD_DISK_REMOVED)|(1<<MD_DISK_FAULTY)|(1<<MD_DISK_JOURNAL)))
+-			    == 0) {
++			     ((1 << MD_DISK_ACTIVE) | (1 << MD_DISK_SYNC) |
++			      (1 << MD_DISK_REMOVED) | (1 << MD_DISK_FAULTY) |
++			      (1 << MD_DISK_JOURNAL))) == 0) {
+ 				printf(" spare");
+ 				if (disk.raid_disk < array.raid_disks &&
+ 				    disk.raid_disk >= 0)
+diff --git a/config.c b/config.c
+index 9b008e3..48e0278 100644
+--- a/config.c
++++ b/config.c
+@@ -1118,8 +1118,8 @@ struct mddev_ident *conf_match(struct supertype *st,
+ 	match = NULL;
+ 	for (; array_list; array_list = array_list->next) {
+ 		if (array_list->uuid_set &&
+-		    same_uuid(array_list->uuid, info->uuid, st->ss->swapuuid)
+-		    == 0) {
++		    same_uuid(array_list->uuid, info->uuid,
++			      st->ss->swapuuid) == 0) {
+ 			if (verbose >= 2 && array_list->devname)
+ 				pr_err("UUID differs from %s.\n",
+ 				       array_list->devname);
+diff --git a/managemon.c b/managemon.c
+index 0a33fc9..a8df666 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -580,8 +580,8 @@ static void manage_member(struct mdstat_ent *mdstat,
+ 			usleep(15*1000);
+ 		}
+ 		replace_array(container, a, newa);
+-		if (sysfs_set_str(&a->info, NULL, "sync_action", "recover")
+-		    == 0)
++		if (sysfs_set_str(&a->info, NULL,
++				  "sync_action", "recover") == 0)
+ 			newa->prev_action = recover;
+ 		dprintf("recovery started on %s\n", a->info.sys_name);
+  out:
+diff --git a/super-ddf.c b/super-ddf.c
+index 4da7c09..c233601 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -1883,8 +1883,8 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst,
+ 		nsec = n / be16_to_cpu(conf->prim_elmnt_count);
+ 		if (conf->sec_elmnt_seq != nsec) {
+ 			for (ibvd = 1; ibvd < conf->sec_elmnt_count; ibvd++) {
+-				if (v->other_bvds[ibvd-1]->sec_elmnt_seq
+-				    == nsec)
++				if (v->other_bvds[ibvd-1]->sec_elmnt_seq ==
++				    nsec)
+ 					break;
+ 			}
+ 			if (ibvd == conf->sec_elmnt_count)
+@@ -3814,13 +3814,13 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
+ 			unsigned int iphys;
+ 			int stt;
+ 
+-			if (be32_to_cpu(ddf->phys->entries[pd].refnum)
+-			    == 0xFFFFFFFF)
++			if (be32_to_cpu(ddf->phys->entries[pd].refnum) ==
++			    0xffffffff)
+ 				continue;
+ 
+ 			stt = be16_to_cpu(ddf->phys->entries[pd].state);
+-			if ((stt & (DDF_Online|DDF_Failed|DDF_Rebuilding))
+-			    != DDF_Online)
++			if ((stt & (DDF_Online|DDF_Failed|DDF_Rebuilding)) !=
++			    DDF_Online)
+ 				continue;
+ 
+ 			i = get_pd_index_from_refnum(
+@@ -4205,8 +4205,8 @@ static int get_bvd_state(const struct ddf_super *ddf,
+ 		if (pd < 0)
+ 			continue;
+ 		st = be16_to_cpu(ddf->phys->entries[pd].state);
+-		if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding))
+-		    == DDF_Online) {
++		if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding)) ==
++		    DDF_Online) {
+ 			working++;
+ 			avail[i] = 1;
+ 		}
+diff --git a/super-intel.c b/super-intel.c
+index 3d0a37c..51b7cc3 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -4023,7 +4023,7 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super,
+ 
+ 	/* duplicate and then set the target end state in map[0] */
+ 	memcpy(dest, src, sizeof_imsm_map(src));
+-	if (migr_type == MIGR_REBUILD || migr_type ==  MIGR_GEN_MIGR) {
++	if (migr_type == MIGR_REBUILD || migr_type == MIGR_GEN_MIGR) {
+ 		__u32 ord;
+ 		int i;
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch b/SOURCES/mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch
new file mode 100644
index 0000000..5386482
--- /dev/null
+++ b/SOURCES/mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch
@@ -0,0 +1,453 @@
+From fc54fe7a7e77fdb6316d332d4d41d0ed2293d6be Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 16 May 2017 13:52:15 -0400
+Subject: [RHEL7.5 PATCH 142/169] mdadm: Fixup a large number of bad
+ formatting of logical operators
+
+Logical oprators never belong at the beginning of a line.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c    | 23 ++++++++++-------------
+ Grow.c        | 34 ++++++++++++++++------------------
+ Manage.c      | 29 +++++++++++++----------------
+ managemon.c   | 10 +++++-----
+ mdadm.c       |  3 +--
+ monitor.c     |  4 ++--
+ super-ddf.c   | 33 ++++++++++++++++-----------------
+ super-intel.c | 10 +++++-----
+ util.c        | 20 ++++++++------------
+ 9 files changed, 76 insertions(+), 90 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 30d5838..1b1905c 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -753,12 +753,12 @@ static int load_devices(struct devs *devices, char *devmap,
+ 				bestcnt = newbestcnt;
+ 			}
+ 			if (best[i] >=0 &&
+-			    devices[best[i]].i.events
+-			    == devices[devcnt].i.events
+-			    && (devices[best[i]].i.disk.minor
+-				!= devices[devcnt].i.disk.minor)
+-			    && st->ss == &super0
+-			    && content->array.level != LEVEL_MULTIPATH) {
++			    devices[best[i]].i.events ==
++			    devices[devcnt].i.events &&
++			    (devices[best[i]].i.disk.minor
++			     != devices[devcnt].i.disk.minor) &&
++			    st->ss == &super0 &&
++			    content->array.level != LEVEL_MULTIPATH) {
+ 				/* two different devices with identical superblock.
+ 				 * Could be a mis-detection caused by overlapping
+ 				 * partitions.  fail-safe.
+@@ -801,14 +801,11 @@ static int force_array(struct mdinfo *content,
+ 	int okcnt = 0;
+ 	while (!enough(content->array.level, content->array.raid_disks,
+ 		       content->array.layout, 1,
+-		       avail)
+-	       ||
++		       avail) ||
+ 	       (content->reshape_active && content->delta_disks > 0 &&
+ 		!enough(content->array.level, (content->array.raid_disks
+ 					       - content->delta_disks),
+-			content->new_layout, 1,
+-			avail)
+-		       )) {
++			content->new_layout, 1, avail))) {
+ 		/* Choose the newest best drive which is
+ 		 * not up-to-date, update the superblock
+ 		 * and add it.
+@@ -1303,8 +1300,8 @@ int Assemble(struct supertype *st, char *mddev,
+ 	int mdfd;
+ 	int clean;
+ 	int auto_assem = (mddev == NULL && !ident->uuid_set &&
+-			  ident->super_minor == UnSet && ident->name[0] == 0
+-			  && (ident->container == NULL || ident->member == NULL));
++			  ident->super_minor == UnSet && ident->name[0] == 0 &&
++			  (ident->container == NULL || ident->member == NULL));
+ 	struct devs *devices;
+ 	char *devmap;
+ 	int *best = NULL; /* indexed by raid_disk */
+diff --git a/Grow.c b/Grow.c
+index a527436..39110b8 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -813,8 +813,8 @@ static void unfreeze(struct supertype *st)
+ 		char buf[20];
+ 
+ 		if (sra &&
+-		    sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0
+-		    && strcmp(buf, "frozen\n") == 0)
++		    sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0 &&
++		    strcmp(buf, "frozen\n") == 0)
+ 			sysfs_set_str(sra, NULL, "sync_action", "idle");
+ 		sysfs_free(sra);
+ 	}
+@@ -2902,8 +2902,8 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 			if (disk.major == 0 && disk.minor == 0)
+ 				continue;
+ 			found++;
+-			if ((disk.state & (1 << MD_DISK_ACTIVE))
+-			    && disk.raid_disk < data_disks)
++			if ((disk.state & (1 << MD_DISK_ACTIVE)) &&
++			    disk.raid_disk < data_disks)
+ 				/* keep this */
+ 				continue;
+ 			ioctl(fd, HOT_REMOVE_DISK,
+@@ -2921,8 +2921,8 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 			if (disk.major == 0 && disk.minor == 0)
+ 				continue;
+ 			found++;
+-			if ((disk.state & (1 << MD_DISK_ACTIVE))
+-			    && disk.raid_disk < data_disks)
++			if ((disk.state & (1 << MD_DISK_ACTIVE)) &&
++			    disk.raid_disk < data_disks)
+ 				/* keep this */
+ 				continue;
+ 			ioctl(fd, SET_DISK_FAULTY,
+@@ -3597,9 +3597,8 @@ started:
+ 	}
+ 
+ 	if (!st->ss->external &&
+-	    !(reshape.before.data_disks != reshape.after.data_disks
+-	      && info->custom_array_size) &&
+-	    info->new_level == reshape.level &&
++	    !(reshape.before.data_disks != reshape.after.data_disks &&
++	      info->custom_array_size) && info->new_level == reshape.level &&
+ 	    !forked) {
+ 		/* no need to wait for the reshape to finish as
+ 		 * there is nothing more to do.
+@@ -4092,14 +4091,14 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
+ 		 * before setting 'sync_action' to 'idle'.
+ 		 * So we need these extra tests.
+ 		 */
+-		if (completed == 0 && advancing
+-		    && strncmp(action, "idle", 4) == 0
+-		    && info->reshape_progress > 0)
++		if (completed == 0 && advancing &&
++		    strncmp(action, "idle", 4) == 0 &&
++		    info->reshape_progress > 0)
+ 			break;
+-		if (completed == 0 && !advancing
+-		    && strncmp(action, "idle", 4) == 0
+-		    && info->reshape_progress < (info->component_size
+-						 * reshape->after.data_disks))
++		if (completed == 0 && !advancing &&
++		    strncmp(action, "idle", 4) == 0 &&
++		    info->reshape_progress < (info->component_size
++					      * reshape->after.data_disks))
+ 			break;
+ 		sysfs_wait(fd, NULL);
+ 		if (sysfs_fd_get_ll(fd, &completed) < 0)
+@@ -4787,8 +4786,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
+ 				/* reshape_progress is increasing */
+ 				if ((__le64_to_cpu(bsb.arraystart)
+ 				     + __le64_to_cpu(bsb.length)
+-				     < info->reshape_progress)
+-				    &&
++				     < info->reshape_progress) &&
+ 				    (__le64_to_cpu(bsb.arraystart2)
+ 				     + __le64_to_cpu(bsb.length2)
+ 				     < info->reshape_progress))
+diff --git a/Manage.c b/Manage.c
+index 467efb7..cee5dad 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -204,11 +204,9 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
+ 	count = 5;
+ 	while (((fd = ((devname[0] == '/')
+ 		       ?open(devname, O_RDONLY|O_EXCL)
+-		       :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0
+-		|| strcmp(fd2devnm(fd), devnm) != 0)
+-	       && container[0]
+-	       && mdmon_running(container)
+-	       && count) {
++		       :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 ||
++		strcmp(fd2devnm(fd), devnm) != 0) && container[0] &&
++	       mdmon_running(container) && count) {
+ 		/* Can't open, so something might be wrong.  However it
+ 		 * is a container, so we might be racing with mdmon, so
+ 		 * retry for a bit.
+@@ -244,8 +242,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
+ 		while (count &&
+ 		       (err = sysfs_set_str(mdi, NULL,
+ 					    "array_state",
+-					    "inactive")) < 0
+-		       && errno == EBUSY) {
++					    "inactive")) < 0 &&
++		       errno == EBUSY) {
+ 			usleep(200000);
+ 			count--;
+ 		}
+@@ -447,9 +445,8 @@ done:
+ 	 * so it is reasonable to retry for a while - 5 seconds.
+ 	 */
+ 	count = 25; err = 0;
+-	while (count && fd >= 0
+-	       && (err = ioctl(fd, STOP_ARRAY, NULL)) < 0
+-	       && errno == EBUSY) {
++	while (count && fd >= 0 &&
++	       (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) {
+ 		usleep(200000);
+ 		count --;
+ 	}
+@@ -795,8 +792,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 				break;
+ 			}
+ 		/* FIXME this is a bad test to be using */
+-		if (!tst->sb && (dv->disposition != 'a'
+-				 && dv->disposition != 'S')) {
++		if (!tst->sb && (dv->disposition != 'a' &&
++				 dv->disposition != 'S')) {
+ 			/* we are re-adding a device to a
+ 			 * completely dead array - have to depend
+ 			 * on kernel to check
+@@ -1393,8 +1390,7 @@ int Manage_subdevs(char *devname, int fd,
+ 
+ 		if (strcmp(dv->devname, "failed") == 0 ||
+ 		    strcmp(dv->devname, "faulty") == 0) {
+-			if (dv->disposition != 'A'
+-			    && dv->disposition != 'r') {
++			if (dv->disposition != 'A' && dv->disposition != 'r') {
+ 				pr_err("%s only meaningful with -r or --re-add, not -%c\n",
+ 					dv->devname, dv->disposition);
+ 				goto abort;
+@@ -1499,8 +1495,9 @@ int Manage_subdevs(char *devname, int fd,
+ 					goto abort;
+ 				}
+ 			}
+-		} else if ((dv->disposition == 'r' || dv->disposition == 'f')
+-			   && get_maj_min(dv->devname, &mj, &mn)) {
++		} else if ((dv->disposition == 'r' ||
++			    dv->disposition == 'f') &&
++			   get_maj_min(dv->devname, &mj, &mn)) {
+ 			/* for 'fail' and 'remove', the device might
+ 			 * not exist.
+ 			 */
+diff --git a/managemon.c b/managemon.c
+index 3c1d4cb..0a33fc9 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -499,9 +499,9 @@ static void manage_member(struct mdstat_ent *mdstat,
+ 		frozen = 1; /* can't read metadata_version assume the worst */
+ 
+ 	/* If sync_action is not 'idle' then don't try recovery now */
+-	if (!frozen
+-	    && sysfs_get_str(&a->info, NULL, "sync_action", buf, sizeof(buf)) > 0
+-	    && strncmp(buf, "idle", 4) != 0)
++	if (!frozen &&
++	    sysfs_get_str(&a->info, NULL, "sync_action",
++			  buf, sizeof(buf)) > 0 && strncmp(buf, "idle", 4) != 0)
+ 		frozen = 1;
+ 
+ 	if (mdstat->level) {
+@@ -626,8 +626,8 @@ static void manage_member(struct mdstat_ent *mdstat,
+ 			newd = xmalloc(sizeof(*newd));
+ 			disk_init_and_add(newd, d, newa);
+ 		}
+-		if (sysfs_get_ll(info, NULL, "array_size", &array_size) == 0
+-		    && a->info.custom_array_size > array_size*2) {
++		if (sysfs_get_ll(info, NULL, "array_size", &array_size) == 0 &&
++		    a->info.custom_array_size > array_size*2) {
+ 			sysfs_set_num(info, NULL, "array_size",
+ 				      a->info.custom_array_size/2);
+ 		}
+diff --git a/mdadm.c b/mdadm.c
+index b689e32..70b16f2 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1843,8 +1843,7 @@ static int misc_scan(char devmode, struct context *c)
+ 			if (members != member)
+ 				continue;
+ 			me = map_by_devnm(&map, e->devnm);
+-			if (me && me->path
+-			    && strcmp(me->path, "/unknown") != 0)
++			if (me && me->path && strcmp(me->path, "/unknown") != 0)
+ 				name = me->path;
+ 			if (name == NULL || stat(name, &stb) != 0)
+ 				name = get_md_name(e->devnm);
+diff --git a/monitor.c b/monitor.c
+index 00b7c68..81537ed 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -576,8 +576,8 @@ static int read_and_act(struct active_array *a, fd_set *fds)
+ 		a->last_checkpoint = sync_completed;
+ 		a->container->ss->set_array_state(a, a->curr_state <= clean);
+ 	} else if ((a->curr_action == idle && a->prev_action == reshape) ||
+-		   (a->curr_action == reshape
+-		    && sync_completed > a->last_checkpoint) ) {
++		   (a->curr_action == reshape &&
++		    sync_completed > a->last_checkpoint)) {
+ 		/* Reshape has progressed or completed so we need to
+ 		 * update the array state - and possibly the array size
+ 		 */
+diff --git a/super-ddf.c b/super-ddf.c
+index 50197a8..769eded 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -670,8 +670,8 @@ static int layout_md2ddf(const mdu_array_info_t *array,
+ 			sec_elmnt_count = array->raid_disks / 2;
+ 			srl = DDF_2SPANNED;
+ 			prl = DDF_RAID1;
+-		} else if (array->raid_disks % 3 == 0
+-			   && array->layout == 0x103) {
++		} else if (array->raid_disks % 3 == 0 &&
++			   array->layout == 0x103) {
+ 			rlq = DDF_RAID1_MULTI;
+ 			prim_elmnt_count =  cpu_to_be16(3);
+ 			sec_elmnt_count = array->raid_disks / 3;
+@@ -853,8 +853,8 @@ static void *load_section(int fd, struct ddf_super *super, void *buf,
+ 	int dofree = (buf == NULL);
+ 
+ 	if (check)
+-		if (len != 2 && len != 8 && len != 32
+-		    && len != 128 && len != 512)
++		if (len != 2 && len != 8 && len != 32 &&
++		    len != 128 && len != 512)
+ 			return NULL;
+ 
+ 	if (len > 1024)
+@@ -2028,8 +2028,8 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
+ 			       be32_to_cpu(ddf->phys->entries[e].refnum) == 0xffffffff)
+ 				e++;
+ 			if (i < info->array.raid_disks && e < max &&
+-			    !(be16_to_cpu(ddf->phys->entries[e].state)
+-			      & DDF_Failed))
++			    !(be16_to_cpu(ddf->phys->entries[e].state) &
++			      DDF_Failed))
+ 				map[i] = 1;
+ 			else
+ 				map[i] = 0;
+@@ -2114,11 +2114,10 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
+ 	info->resync_start = 0;
+ 	info->reshape_active = 0;
+ 	info->recovery_blocked = 0;
+-	if (!(ddf->virt->entries[info->container_member].state
+-	      & DDF_state_inconsistent)  &&
+-	    (ddf->virt->entries[info->container_member].init_state
+-	     & DDF_initstate_mask)
+-	    == DDF_init_full)
++	if (!(ddf->virt->entries[info->container_member].state &
++	      DDF_state_inconsistent) &&
++	    (ddf->virt->entries[info->container_member].init_state &
++	     DDF_initstate_mask) == DDF_init_full)
+ 		info->resync_start = MaxSector;
+ 
+ 	uuid_from_super_ddf(st, info->uuid);
+@@ -2135,7 +2134,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
+ 	if (map)
+ 		for (j = 0; j < map_disks; j++) {
+ 			map[j] = 0;
+-			if (j <  info->array.raid_disks) {
++			if (j < info->array.raid_disks) {
+ 				int i = find_phys(ddf, vc->conf.phys_refnum[j]);
+ 				if (i >= 0 &&
+ 				    (be16_to_cpu(ddf->phys->entries[i].state)
+@@ -4618,9 +4617,9 @@ static void ddf_remove_failed(struct ddf_super *ddf)
+ 		    0xFFFFFFFF)
+ 			continue;
+ 		if (be16_and(ddf->phys->entries[pdnum].state,
+-			     cpu_to_be16(DDF_Failed))
+-		    && be16_and(ddf->phys->entries[pdnum].state,
+-				cpu_to_be16(DDF_Transition))) {
++			     cpu_to_be16(DDF_Failed)) &&
++		    be16_and(ddf->phys->entries[pdnum].state,
++			     cpu_to_be16(DDF_Transition))) {
+ 			/* skip this one unless in dlist*/
+ 			for (dl = ddf->dlist; dl; dl = dl->next)
+ 				if (dl->pdnum == (int)pdnum)
+@@ -5151,8 +5150,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
+ 		vc = (struct vd_config *)(mu->buf
+ 					  + i_sec * ddf->conf_rec_len * 512);
+ 		for (dl = ddf->dlist; dl; dl = dl->next)
+-			if (dl->major == di->disk.major
+-			    && dl->minor == di->disk.minor)
++			if (dl->major == di->disk.major &&
++			    dl->minor == di->disk.minor)
+ 				break;
+ 		if (!dl || dl->pdnum < 0) {
+ 			pr_err("BUG: can't find disk %d (%d/%d)\n",
+diff --git a/super-intel.c b/super-intel.c
+index 8ca80d3..c84e755 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -4165,8 +4165,8 @@ int check_mpb_migr_compatibility(struct intel_super *super)
+ 			if (pba_of_lba0(map0) != pba_of_lba0(map1))
+ 				/* migration optimization area was used */
+ 				return -1;
+-			if (migr_rec->ascending_migr == 0
+-				&& migr_rec->dest_depth_per_unit > 0)
++			if (migr_rec->ascending_migr == 0 &&
++			    migr_rec->dest_depth_per_unit > 0)
+ 				/* descending reshape not supported yet */
+ 				return -1;
+ 		}
+@@ -6442,7 +6442,7 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
+ 
+ 	for (memb = mdstat ; memb ; memb = memb->next) {
+ 		if (memb->metadata_version &&
+-		    (strncmp(memb->metadata_version, "external:", 9) == 0)  &&
++		    (strncmp(memb->metadata_version, "external:", 9) == 0) &&
+ 		    (strcmp(&memb->metadata_version[9], name) == 0) &&
+ 		    !is_subarray(memb->metadata_version+9) &&
+ 		    memb->members) {
+@@ -11640,8 +11640,8 @@ static int imsm_manage_reshape(
+ 
+ 	/* Find volume during the reshape */
+ 	for (dv = super->devlist; dv; dv = dv->next) {
+-		if (dv->dev->vol.migr_type == MIGR_GEN_MIGR
+-		    && dv->dev->vol.migr_state == 1) {
++		if (dv->dev->vol.migr_type == MIGR_GEN_MIGR &&
++		    dv->dev->vol.migr_state == 1) {
+ 			dev = dv->dev;
+ 			migr_vol_qan++;
+ 		}
+diff --git a/util.c b/util.c
+index fc9cd3f..0564c0b 100644
+--- a/util.c
++++ b/util.c
+@@ -1014,21 +1014,18 @@ char *get_md_name(char *devnm)
+ 	if (strncmp(devnm, "md_", 3) == 0) {
+ 		snprintf(devname, sizeof(devname), "/dev/md/%s",
+ 			devnm + 3);
+-		if (stat(devname, &stb) == 0
+-		    && (S_IFMT&stb.st_mode) == S_IFBLK
+-		    && (stb.st_rdev == rdev))
++		if (stat(devname, &stb) == 0 &&
++		    (S_IFMT&stb.st_mode) == S_IFBLK && (stb.st_rdev == rdev))
+ 			return devname;
+ 	}
+ 	snprintf(devname, sizeof(devname), "/dev/%s", devnm);
+-	if (stat(devname, &stb) == 0
+-	    && (S_IFMT&stb.st_mode) == S_IFBLK
+-	    && (stb.st_rdev == rdev))
++	if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK &&
++	    (stb.st_rdev == rdev))
+ 		return devname;
+ 
+ 	snprintf(devname, sizeof(devname), "/dev/md/%s", devnm+2);
+-	if (stat(devname, &stb) == 0
+-	    && (S_IFMT&stb.st_mode) == S_IFBLK
+-	    && (stb.st_rdev == rdev))
++	if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK &&
++	    (stb.st_rdev == rdev))
+ 		return devname;
+ 
+ 	dn = map_dev(major(rdev), minor(rdev), 0);
+@@ -1039,9 +1036,8 @@ char *get_md_name(char *devnm)
+ 		if (errno != EEXIST)
+ 			return NULL;
+ 
+-	if (stat(devname, &stb) == 0
+-	    && (S_IFMT&stb.st_mode) == S_IFBLK
+-	    && (stb.st_rdev == rdev))
++	if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK &&
++	    (stb.st_rdev == rdev))
+ 		return devname;
+ 	unlink(devname);
+ 	return NULL;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch b/SOURCES/mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch
new file mode 100644
index 0000000..009229c
--- /dev/null
+++ b/SOURCES/mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch
@@ -0,0 +1,197 @@
+From 8ea982179af73f5b1d3fc937676ec7c969a190ac Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 12:02:14 -0400
+Subject: [RHEL7.5 PATCH 034/169] mdadm: Fixup a number of whitespace
+ inconsistency cases
+
+Lots of code lacked whitespaces in assignments, and in other places
+had them in the wrong place.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 51 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 25 insertions(+), 26 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 502e721..0f32773 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -106,11 +106,11 @@ int main(int argc, char *argv[])
+ 
+ 	srandom(time(0) ^ getpid());
+ 
+-	ident.uuid_set=0;
++	ident.uuid_set = 0;
+ 	ident.level = UnSet;
+ 	ident.raid_disks = UnSet;
+-	ident.super_minor= UnSet;
+-	ident.devices=0;
++	ident.super_minor = UnSet;
++	ident.devices = 0;
+ 	ident.spare_group = NULL;
+ 	ident.autof = 0;
+ 	ident.st = NULL;
+@@ -120,10 +120,9 @@ int main(int argc, char *argv[])
+ 	ident.container = NULL;
+ 	ident.member = NULL;
+ 
+-	while ((option_index = -1) ,
+-	       (opt=getopt_long(argc, argv,
+-				shortopt, long_options,
+-				&option_index)) != -1) {
++	while ((option_index = -1),
++	       (opt = getopt_long(argc, argv, shortopt, long_options,
++				  &option_index)) != -1) {
+ 		int newmode = mode;
+ 		/* firstly, some mode-independent options */
+ 		switch(opt) {
+@@ -397,7 +396,7 @@ int main(int argc, char *argv[])
+ 				pr_err("metadata information already given\n");
+ 				exit(2);
+ 			}
+-			for(i=0; !ss && superlist[i]; i++)
++			for(i = 0; !ss && superlist[i]; i++)
+ 				ss = superlist[i]->match_metadata_desc(optarg);
+ 
+ 			if (!ss) {
+@@ -542,7 +541,7 @@ int main(int argc, char *argv[])
+ 
+ 			case 5:
+ 				s.layout = map_name(r5layout, optarg);
+-				if (s.layout==UnSet) {
++				if (s.layout == UnSet) {
+ 					pr_err("layout %s not understood for raid5.\n",
+ 						optarg);
+ 					exit(2);
+@@ -550,7 +549,7 @@ int main(int argc, char *argv[])
+ 				break;
+ 			case 6:
+ 				s.layout = map_name(r6layout, optarg);
+-				if (s.layout==UnSet) {
++				if (s.layout == UnSet) {
+ 					pr_err("layout %s not understood for raid6.\n",
+ 						optarg);
+ 					exit(2);
+@@ -665,7 +664,7 @@ int main(int argc, char *argv[])
+ 		case O(MISC,'f'): /* force zero */
+ 		case O(MISC,Force): /* force zero */
+ 		case O(MANAGE,Force): /* add device which is too large */
+-			c.force=1;
++			c.force = 1;
+ 			continue;
+ 			/* now for the Assemble options */
+ 		case O(ASSEMBLE, FreezeReshape):   /* Freeze reshape during
+@@ -777,12 +776,12 @@ int main(int argc, char *argv[])
+ 				continue;
+ 			if (strcmp(c.update, "revert-reshape") == 0)
+ 				continue;
+-			if (strcmp(c.update, "byteorder")==0) {
++			if (strcmp(c.update, "byteorder") == 0) {
+ 				if (ss) {
+ 					pr_err("must not set metadata type with --update=byteorder.\n");
+ 					exit(2);
+ 				}
+-				for(i=0; !ss && superlist[i]; i++)
++				for(i = 0; !ss && superlist[i]; i++)
+ 					ss = superlist[i]->match_metadata_desc(
+ 						"0.swap");
+ 				if (!ss) {
+@@ -1476,7 +1475,7 @@ int main(int argc, char *argv[])
+ 				pr_err("can only assemble a single array when providing a backup file.\n");
+ 				exit(1);
+ 			}
+-			for (dv = devlist ; dv ; dv=dv->next) {
++			for (dv = devlist; dv; dv = dv->next) {
+ 				struct mddev_ident *array_ident = conf_get_ident(dv->devname);
+ 				if (array_ident == NULL) {
+ 					pr_err("%s not identified in config file.\n",
+@@ -1611,10 +1610,10 @@ int main(int argc, char *argv[])
+ 			else
+ 				c.delay = 60;
+ 		}
+-		rv= Monitor(devlist, mailaddr, program,
+-			    &c, daemonise, oneshot,
+-			    dosyslog, pidfile, increments,
+-			    spare_sharing);
++		rv = Monitor(devlist, mailaddr, program,
++			     &c, daemonise, oneshot,
++			     dosyslog, pidfile, increments,
++			     spare_sharing);
+ 		break;
+ 
+ 	case GROW:
+@@ -1654,7 +1653,7 @@ int main(int argc, char *argv[])
+ 				rv = 1;
+ 				break;
+ 			}
+-			for (dv=devlist->next; dv ; dv=dv->next) {
++			for (dv = devlist->next; dv; dv = dv->next) {
+ 				rv = Grow_Add_device(devlist->devname, mdfd,
+ 						     dv->devname);
+ 				if (rv)
+@@ -1749,7 +1748,7 @@ static int scan_assemble(struct supertype *ss,
+ 		pr_err("No devices listed in conf file were found.\n");
+ 		return 1;
+ 	}
+-	for (a = array_list; a ; a = a->next) {
++	for (a = array_list; a; a = a->next) {
+ 		a->assembled = 0;
+ 		if (a->autof == 0)
+ 			a->autof = c->autof;
+@@ -1760,7 +1759,7 @@ static int scan_assemble(struct supertype *ss,
+ 		failures = 0;
+ 		successes = 0;
+ 		rv = 0;
+-		for (a = array_list; a ; a = a->next) {
++		for (a = array_list; a; a = a->next) {
+ 			int r;
+ 			if (a->assembled)
+ 				continue;
+@@ -1826,7 +1825,7 @@ static int misc_scan(char devmode, struct context *c)
+ 	int rv = 0;
+ 
+ 	for (members = 0; members <= 1; members++) {
+-		for (e=ms ; e ; e=e->next) {
++		for (e = ms; e; e = e->next) {
+ 			char *name = NULL;
+ 			struct map_ent *me;
+ 			struct stat stb;
+@@ -1864,7 +1863,7 @@ static int stop_scan(int verbose)
+ 	/* Due to possible stacking of devices, repeat until
+ 	 * nothing more can be stopped
+ 	 */
+-	int progress=1, err;
++	int progress = 1, err;
+ 	int last = 0;
+ 	int rv = 0;
+ 	do {
+@@ -1873,7 +1872,7 @@ static int stop_scan(int verbose)
+ 
+ 		if (!progress) last = 1;
+ 		progress = 0; err = 0;
+-		for (e=ms ; e ; e=e->next) {
++		for (e = ms; e; e = e->next) {
+ 			char *name = get_md_name(e->devnm);
+ 			int mdfd;
+ 
+@@ -1908,7 +1907,7 @@ static int misc_list(struct mddev_dev *devlist,
+ 	struct mddev_dev *dv;
+ 	int rv = 0;
+ 
+-	for (dv=devlist ; dv; dv=(rv & 16) ? NULL : dv->next) {
++	for (dv = devlist; dv; dv = (rv & 16) ? NULL : dv->next) {
+ 		int mdfd;
+ 
+ 		switch(dv->disposition) {
+@@ -1974,7 +1973,7 @@ static int misc_list(struct mddev_dev *devlist,
+ 			case 1:
+ 				mdfd = open_mddev(dv->devname, 1);  
+ 		}
+-		if (mdfd>=0) {
++		if (mdfd >= 0) {
+ 			switch(dv->disposition) {
+ 			case 'R':
+ 				c->runstop = 1;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Fixup-broken-formatting2.patch b/SOURCES/mdadm-Fixup-broken-formatting2.patch
new file mode 100644
index 0000000..e2197a2
--- /dev/null
+++ b/SOURCES/mdadm-Fixup-broken-formatting2.patch
@@ -0,0 +1,163 @@
+From d16a749444251c12689fa93d398149025a9c2398 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 16 May 2017 14:09:57 -0400
+Subject: [RHEL7.5 PATCH 145/169] mdadm: Fixup != broken formatting
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c  |  4 ++--
+ Grow.c      | 13 +++++++------
+ policy.c    |  5 ++---
+ restripe.c  |  8 +++++---
+ super-ddf.c |  8 ++++----
+ super0.c    |  8 ++++----
+ 6 files changed, 24 insertions(+), 22 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index afc6d9c..3c10b6c 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -755,8 +755,8 @@ static int load_devices(struct devs *devices, char *devmap,
+ 			if (best[i] >=0 &&
+ 			    devices[best[i]].i.events ==
+ 			    devices[devcnt].i.events &&
+-			    (devices[best[i]].i.disk.minor
+-			     != devices[devcnt].i.disk.minor) &&
++			    (devices[best[i]].i.disk.minor !=
++			     devices[devcnt].i.disk.minor) &&
+ 			    st->ss == &super0 &&
+ 			    content->array.level != LEVEL_MULTIPATH) {
+ 				/* two different devices with identical superblock.
+diff --git a/Grow.c b/Grow.c
+index db3f18b..ecf5ca0 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -1403,8 +1403,8 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
+ 			if (info->new_layout == UnSet) {
+ 				int copies = 1 + (info->delta_disks
+ 						  / info->array.raid_disks);
+-				if (info->array.raid_disks * (copies-1)
+-				    != info->delta_disks)
++				if (info->array.raid_disks * (copies-1) !=
++				    info->delta_disks)
+ 					return "Impossible number of devices for RAID0->RAID10";
+ 				info->new_layout = 0x100 + copies;
+ 			}
+@@ -3067,8 +3067,8 @@ static int reshape_array(char *container, int fd, char *devname,
+ 	if (restart &&
+ 	    (reshape.level != info->array.level ||
+ 	     reshape.before.layout != info->array.layout ||
+-	     reshape.before.data_disks + reshape.parity
+-	     != info->array.raid_disks - max(0, info->delta_disks))) {
++	     reshape.before.data_disks + reshape.parity !=
++	     info->array.raid_disks - max(0, info->delta_disks))) {
+ 		pr_err("reshape info is not in native format - cannot continue.\n");
+ 		goto release;
+ 	}
+@@ -4281,8 +4281,9 @@ static int grow_backup(struct mdinfo *sra,
+ 						((char*)&bsb.sb_csum2)-((char*)&bsb));
+ 
+ 		rv = -1;
+-		if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0)
+-		    != destoffsets[i] - 4096)
++		if ((unsigned long long)lseek64(destfd[i],
++						destoffsets[i] - 4096, 0) !=
++		    destoffsets[i] - 4096)
+ 			break;
+ 		if (write(destfd[i], &bsb, 512) != 512)
+ 			break;
+diff --git a/policy.c b/policy.c
+index 064d349..b17585a 100644
+--- a/policy.c
++++ b/policy.c
+@@ -887,9 +887,8 @@ int Write_rules(char *rule_name)
+ 		fd = 1;
+ 
+ 	/* write static invocation */
+-	if (write(fd, udev_template_start,
+-		  sizeof(udev_template_start) - 1)
+-	    != (int)sizeof(udev_template_start)-1)
++	if (write(fd, udev_template_start, sizeof(udev_template_start) - 1) !=
++	    (int)sizeof(udev_template_start) - 1)
+ 		goto abort;
+ 
+ 	/* iterate, if none created or error occurred, remove file */
+diff --git a/restripe.c b/restripe.c
+index 6b31695..31b07e8 100644
+--- a/restripe.c
++++ b/restripe.c
+@@ -581,14 +581,16 @@ int save_stripes(int *source, unsigned long long *offsets,
+ 				       raid_disks, level, layout);
+ 			if (dnum < 0) abort();
+ 			if (source[dnum] < 0 ||
+-			    lseek64(source[dnum], offsets[dnum]+offset, 0) < 0 ||
+-			    read(source[dnum], buf+disk * chunk_size, chunk_size)
+-			    != chunk_size)
++			    lseek64(source[dnum],
++				    offsets[dnum] + offset, 0) < 0 ||
++			    read(source[dnum], buf+disk * chunk_size,
++				 chunk_size) != chunk_size) {
+ 				if (failed <= 2) {
+ 					fdisk[failed] = dnum;
+ 					fblock[failed] = disk;
+ 					failed++;
+ 				}
++			}
+ 		}
+ 		if (failed == 0 || fblock[0] >= data_disks)
+ 			/* all data disks are good */
+diff --git a/super-ddf.c b/super-ddf.c
+index c233601..d02a19a 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -3511,8 +3511,8 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
+ 		if (minsize == 0)
+ 			minsize = 8;
+ 		for (dl = ddf->dlist; dl ; dl = dl->next) {
+-			if (find_space(ddf, dl, data_offset, &minsize)
+-			    != INVALID_SECTORS)
++			if (find_space(ddf, dl, data_offset, &minsize) !=
++			    INVALID_SECTORS)
+ 				dcnt++;
+ 		}
+ 		if (dcnt < raiddisks) {
+@@ -4004,8 +4004,8 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst)
+ 			continue;
+ 
+ 		if (posix_memalign((void **)&dl1, 512,
+-		       sizeof(*dl1) + (first->max_part) * sizeof(dl1->vlist[0]))
+-		    != 0) {
++				   sizeof(*dl1) + (first->max_part) *
++				   sizeof(dl1->vlist[0])) != 0) {
+ 			pr_err("could not allocate disk info buffer\n");
+ 			return 3;
+ 		}
+diff --git a/super0.c b/super0.c
+index dc13efb..756cab5 100644
+--- a/super0.c
++++ b/super0.c
+@@ -589,8 +589,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
+ 			 * being marked 'sync'
+ 			 */
+ 			add = (1<<MD_DISK_SYNC);
+-		if (((sb->disks[d].state & ~mask) | add)
+-		    != (unsigned)info->disk.state) {
++		if (((sb->disks[d].state & ~mask) | add) !=
++		    (unsigned)info->disk.state) {
+ 			sb->disks[d].state = info->disk.state | wonly |failfast;
+ 			rv = 1;
+ 		}
+@@ -1058,8 +1058,8 @@ static int load_super0(struct supertype *st, int fd, char *devname)
+ 	 * valid.  If it doesn't clear the bit.  An --assemble --force
+ 	 * should get that written out.
+ 	 */
+-	if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),4096))
+-	    != ROUND_UP(sizeof(struct bitmap_super_s),4096))
++	if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),4096)) !=
++	    ROUND_UP(sizeof(struct bitmap_super_s), 4096))
+ 		goto no_bitmap;
+ 
+ 	uuid_from_super0(st, uuid);
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Fixup-morebroken-logical-operator-formatting.patch b/SOURCES/mdadm-Fixup-morebroken-logical-operator-formatting.patch
new file mode 100644
index 0000000..e7f66a3
--- /dev/null
+++ b/SOURCES/mdadm-Fixup-morebroken-logical-operator-formatting.patch
@@ -0,0 +1,256 @@
+From d7be7d87366a7f9b190bc4e41ea06f7c9984028e Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 16 May 2017 13:59:43 -0400
+Subject: [RHEL7.5 PATCH 143/169] mdadm: Fixup more broken logical operator
+ formatting
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c       |  9 ++++-----
+ Grow.c           | 16 +++++++++-------
+ Manage.c         |  4 ++--
+ Monitor.c        |  4 ++--
+ mapfile.c        |  4 ++--
+ mdstat.c         | 10 ++++++----
+ platform-intel.c |  4 ++--
+ restripe.c       |  4 ++--
+ super-ddf.c      | 15 +++++++--------
+ super-intel.c    |  3 +--
+ util.c           |  3 +--
+ 11 files changed, 38 insertions(+), 38 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 1b1905c..afc6d9c 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -220,8 +220,8 @@ static int select_devices(struct mddev_dev *devlist,
+ 					pr_err("not a recognisable container: %s\n",
+ 					       devname);
+ 				tmpdev->used = 2;
+-			} else if (!tst->ss->load_container
+-				   || tst->ss->load_container(tst, dfd, NULL)) {
++			} else if (!tst->ss->load_container ||
++				   tst->ss->load_container(tst, dfd, NULL)) {
+ 				if (report_mismatch)
+ 					pr_err("no correct container type: %s\n",
+ 					       devname);
+@@ -776,9 +776,8 @@ static int load_devices(struct devs *devices, char *devmap,
+ 				*stp = st;
+ 				return -1;
+ 			}
+-			if (best[i] == -1
+-			    || (devices[best[i]].i.events
+-				< devices[devcnt].i.events))
++			if (best[i] == -1 || (devices[best[i]].i.events
++					      < devices[devcnt].i.events))
+ 				best[i] = devcnt;
+ 		}
+ 		devcnt++;
+diff --git a/Grow.c b/Grow.c
+index 39110b8..db3f18b 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -3995,8 +3995,8 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape,
+ 	 * a backup.
+ 	 */
+ 	if (advancing) {
+-		if ((need_backup > info->reshape_progress
+-		     || info->array.major_version < 0) &&
++		if ((need_backup > info->reshape_progress ||
++		     info->array.major_version < 0) &&
+ 		    *suspend_point < info->reshape_progress + target) {
+ 			if (need_backup < *suspend_point + 2 * target)
+ 				*suspend_point = need_backup;
+@@ -4149,8 +4149,9 @@ check_progress:
+ 	 * it was just a device failure that leaves us degraded but
+ 	 * functioning.
+ 	 */
+-	if (sysfs_get_str(info, NULL, "reshape_position", buf, sizeof(buf)) < 0
+-	    || strncmp(buf, "none", 4) != 0) {
++	if (sysfs_get_str(info, NULL, "reshape_position", buf,
++			  sizeof(buf)) < 0 ||
++	    strncmp(buf, "none", 4) != 0) {
+ 		/* The abort might only be temporary.  Wait up to 10
+ 		 * seconds for fd to contain a valid number again.
+ 		 */
+@@ -4182,9 +4183,10 @@ check_progress:
+ 		/* Maybe racing with array shutdown - check state */
+ 		if (fd >= 0)
+ 			close(fd);
+-		if (sysfs_get_str(info, NULL, "array_state", buf, sizeof(buf)) < 0
+-		    || strncmp(buf, "inactive", 8) == 0
+-		    || strncmp(buf, "clear",5) == 0)
++		if (sysfs_get_str(info, NULL, "array_state", buf,
++				  sizeof(buf)) < 0 ||
++		    strncmp(buf, "inactive", 8) == 0 ||
++		    strncmp(buf, "clear",5) == 0)
+ 			return -2; /* abort */
+ 		return -1; /* complete */
+ 	}
+diff --git a/Manage.c b/Manage.c
+index cee5dad..04b9398 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -655,8 +655,8 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
+ 		if (dv->failfast == FlagClear)
+ 			disc.state &= ~(1 << MD_DISK_FAILFAST);
+ 		remove_partitions(tfd);
+-		if (update || dv->writemostly != FlagDefault
+-			|| dv->failfast != FlagDefault) {
++		if (update || dv->writemostly != FlagDefault ||
++		    dv->failfast != FlagDefault) {
+ 			int rv = -1;
+ 			tfd = dev_open(dv->devname, O_RDWR);
+ 			if (tfd < 0) {
+diff --git a/Monitor.c b/Monitor.c
+index 0198a34..725f47d 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -530,7 +530,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
+ 	    st->working == sra->array.working_disks &&
+ 	    st->spare == sra->array.spare_disks &&
+-	    (mse == NULL  || (mse->percent == st->percent))) {
++	    (mse == NULL || (mse->percent == st->percent))) {
+ 		if ((st->active < st->raid) && st->spare == 0)
+ 			retval = 1;
+ 		goto out;
+@@ -672,7 +672,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
+ 	char *name;
+ 
+ 	for (mse = mdstat; mse; mse = mse->next)
+-		if (mse->devnm[0] && (!mse->level  || /* retrieve containers */
++		if (mse->devnm[0] && (!mse->level || /* retrieve containers */
+ 				      (strcmp(mse->level, "raid0") != 0 &&
+ 				       strcmp(mse->level, "linear") != 0))) {
+ 			struct state *st = xcalloc(1, sizeof *st);
+diff --git a/mapfile.c b/mapfile.c
+index c89d403..f3c8191 100644
+--- a/mapfile.c
++++ b/mapfile.c
+@@ -439,8 +439,8 @@ void RebuildMap(void)
+ 					if ((homehost == NULL ||
+ 					     st->ss->match_home(st, homehost) != 1) &&
+ 					    st->ss->match_home(st, "any") != 1 &&
+-					    (require_homehost
+-					     || ! conf_name_is_free(info->name)))
++					    (require_homehost ||
++					     !conf_name_is_free(info->name)))
+ 						/* require a numeric suffix */
+ 						unum = 0;
+ 					else
+diff --git a/mdstat.c b/mdstat.c
+index 3962896..0d44050 100644
+--- a/mdstat.c
++++ b/mdstat.c
+@@ -166,8 +166,8 @@ struct mdstat_ent *mdstat_read(int hold, int start)
+ 			continue;
+ 		insert_here = NULL;
+ 		/* Better be an md line.. */
+-		if (strncmp(line, "md", 2)!= 0 || strlen(line) >= 32
+-		    || (line[2] != '_' && !isdigit(line[2])))
++		if (strncmp(line, "md", 2)!= 0 || strlen(line) >= 32 ||
++		    (line[2] != '_' && !isdigit(line[2])))
+ 			continue;
+ 		strcpy(devnm, line);
+ 
+@@ -212,8 +212,10 @@ struct mdstat_ent *mdstat_read(int hold, int start)
+ 					struct mdstat_ent **ih;
+ 					ih = &all;
+ 					while (ih != insert_here && *ih &&
+-					       ((int)strlen((*ih)->devnm) != ep-w
+-						|| strncmp((*ih)->devnm, w, ep-w) != 0))
++					       ((int)strlen((*ih)->devnm) !=
++						ep-w ||
++						strncmp((*ih)->devnm, w,
++							ep-w) != 0))
+ 						ih = & (*ih)->next;
+ 					insert_here = ih;
+ 				}
+diff --git a/platform-intel.c b/platform-intel.c
+index 9867697..a11101d 100644
+--- a/platform-intel.c
++++ b/platform-intel.c
+@@ -548,8 +548,8 @@ static int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name
+ 
+ 	errno = 0;
+ 	var_data_len = strtoul(buf, NULL, 16);
+-	if ((errno == ERANGE && (var_data_len == LONG_MAX))
+-	    || (errno != 0 && var_data_len == 0))
++	if ((errno == ERANGE && (var_data_len == LONG_MAX)) ||
++	    (errno != 0 && var_data_len == 0))
+ 		return 1;
+ 
+ 	/* get data */
+diff --git a/restripe.c b/restripe.c
+index de85ee4..6b31695 100644
+--- a/restripe.c
++++ b/restripe.c
+@@ -731,8 +731,8 @@ int restore_stripes(int *dest, unsigned long long *offsets,
+ 		zero_size = chunk_size;
+ 	}
+ 
+-	if (stripe_buf == NULL || stripes == NULL || blocks == NULL
+-	    || zero == NULL) {
++	if (stripe_buf == NULL || stripes == NULL || blocks == NULL ||
++	    zero == NULL) {
+ 		rv = -2;
+ 		goto abort;
+ 	}
+diff --git a/super-ddf.c b/super-ddf.c
+index 769eded..4da7c09 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -932,14 +932,13 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
+ 	if (load_ddf_header(fd, be64_to_cpu(super->anchor.secondary_lba),
+ 			    dsize >> 9,  2,
+ 			    &super->secondary, &super->anchor)) {
+-		if (super->active == NULL
+-		    || (be32_to_cpu(super->primary.seq)
+-			< be32_to_cpu(super->secondary.seq) &&
+-			!super->secondary.openflag)
+-		    || (be32_to_cpu(super->primary.seq)
+-			== be32_to_cpu(super->secondary.seq) &&
+-			super->primary.openflag && !super->secondary.openflag)
+-			)
++		if (super->active == NULL ||
++		    (be32_to_cpu(super->primary.seq)
++		     < be32_to_cpu(super->secondary.seq) &&
++			!super->secondary.openflag) ||
++		    (be32_to_cpu(super->primary.seq) ==
++		     be32_to_cpu(super->secondary.seq) &&
++			super->primary.openflag && !super->secondary.openflag))
+ 			super->active = &super->secondary;
+ 	} else if (devname &&
+ 		   be64_to_cpu(super->anchor.secondary_lba) != ~(__u64)0)
+diff --git a/super-intel.c b/super-intel.c
+index c84e755..3d0a37c 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -10874,8 +10874,7 @@ static int imsm_create_metadata_update_for_reshape(
+ 	 */
+ 	spares = get_spares_for_grow(st);
+ 
+-	if (spares == NULL
+-	    || delta_disks > spares->array.spare_disks) {
++	if (spares == NULL || delta_disks > spares->array.spare_disks) {
+ 		pr_err("imsm: ERROR: Cannot get spare devices for %s.\n", geo->dev_name);
+ 		i = -1;
+ 		goto abort;
+diff --git a/util.c b/util.c
+index 0564c0b..d89438c 100644
+--- a/util.c
++++ b/util.c
+@@ -2213,8 +2213,7 @@ void enable_fds(int devices)
+ {
+ 	unsigned int fds = 20 + devices;
+ 	struct rlimit lim;
+-	if (getrlimit(RLIMIT_NOFILE, &lim) != 0
+-	    || lim.rlim_cur >= fds)
++	if (getrlimit(RLIMIT_NOFILE, &lim) != 0 || lim.rlim_cur >= fds)
+ 		return;
+ 	if (lim.rlim_max < fds)
+ 		lim.rlim_max = fds;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Forced-type-conversion-to-avoid-truncation.patch b/SOURCES/mdadm-Forced-type-conversion-to-avoid-truncation.patch
new file mode 100644
index 0000000..f2f6712
--- /dev/null
+++ b/SOURCES/mdadm-Forced-type-conversion-to-avoid-truncation.patch
@@ -0,0 +1,33 @@
+From 5b97512954e9710fd45ab5778bf679205c35892d Mon Sep 17 00:00:00 2001
+From: Xiao Ni <xni@redhat.com>
+Date: Sat, 18 Mar 2017 10:33:45 +0800
+Subject: [RHEL7.5 PATCH 016/169] mdadm: Forced type conversion to avoid
+ truncation
+
+Gcc reports it needs 19 bytes to right to disk->serial. Because the
+type of argument i is int. But the meaning of i is failed disk
+number. So it doesn't need to use 19 bytes.  Just add a type
+conversion to avoid this building error
+
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ super-intel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/super-intel.c b/super-intel.c
+index 343f20d..e1618f1 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -5228,7 +5228,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
+ 			disk->status = CONFIGURED_DISK | FAILED_DISK;
+ 			disk->scsi_id = __cpu_to_le32(~(__u32)0);
+ 			snprintf((char *) disk->serial, MAX_RAID_SERIAL_LEN,
+-				 "missing:%d", i);
++				 "missing:%d", (__u8)i);
+ 		}
+ 		find_missing(super);
+ 	} else {
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch b/SOURCES/mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch
new file mode 100644
index 0000000..376d374
--- /dev/null
+++ b/SOURCES/mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch
@@ -0,0 +1,47 @@
+From 75dd32a185871fead13cd3586e00980b35410ff0 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 20 Mar 2017 13:21:41 +0800
+Subject: [RHEL7.5 PATCH 014/169] mdadm/Monitor: Fix NULL pointer
+ dereference when stat2devnm return NULL
+
+Wait(): stat2devnm() returns NULL for non block devices. Check the
+pointer is valid derefencing it. This can happen when using --wait,
+such as the 'f' and 'd' file type, causing a core dump.
+such as: ./mdadm --wait /dev/md/
+
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Monitor.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/Monitor.c b/Monitor.c
+index 802a9d9..bdd3e63 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -994,6 +994,7 @@ int Wait(char *dev)
+ {
+ 	struct stat stb;
+ 	char devnm[32];
++	char *tmp;
+ 	int rv = 1;
+ 	int frozen_remaining = 3;
+ 
+@@ -1002,7 +1003,12 @@ int Wait(char *dev)
+ 			strerror(errno));
+ 		return 2;
+ 	}
+-	strcpy(devnm, stat2devnm(&stb));
++	tmp = stat2devnm(&stb);
++	if (!tmp) {
++		pr_err("%s is not a block device.\n", dev);
++		return 2;
++	}
++	strcpy(devnm, tmp);
+ 
+ 	while(1) {
+ 		struct mdstat_ent *ms = mdstat_read(1, 0);
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-Uninitialized-variable-rdev.patch b/SOURCES/mdadm-Uninitialized-variable-rdev.patch
new file mode 100644
index 0000000..c4b7977
--- /dev/null
+++ b/SOURCES/mdadm-Uninitialized-variable-rdev.patch
@@ -0,0 +1,29 @@
+From a3476c9223e55ebb6063e7c5ee057647c70da0d2 Mon Sep 17 00:00:00 2001
+From: James Puthukattukaran <joejames70@gmail.com>
+Date: Tue, 16 May 2017 11:57:00 -0400
+Subject: [RHEL7.5 PATCH 140/169] mdadm: Uninitialized variable rdev
+
+rdev is not initialized properly causing compiler complaint.
+
+Signed-off-by: James Puthukattukaran <joejames70@gmail.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-ddf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/super-ddf.c b/super-ddf.c
+index 9c82f4f..ac14017 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -3526,7 +3526,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
+ 		return 1;
+ 	}
+ 	/* This device must be a member of the set */
+-	if (!stat_is_blkdev(dev, NULL))
++	if (!stat_is_blkdev(dev, &rdev))
+ 		return 0;
+ 	for (dl = ddf->dlist ; dl ; dl = dl->next) {
+ 		if (dl->major == (int)major(rdev) &&
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch b/SOURCES/mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch
new file mode 100644
index 0000000..4ecaa95
--- /dev/null
+++ b/SOURCES/mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch
@@ -0,0 +1,36 @@
+From 72b616aff26e64079727ea908073027c08f99c07 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Tue, 7 Mar 2017 11:13:03 +0800
+Subject: [RHEL7.5 PATCH 008/169] mdadm:add checking clustered bitmap in
+ assemble mode
+
+mdadm:Both clustered and internal array don't need
+to specify --bitmap when assembling array.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Acked-by: Coly Li <colyli@suse.de>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index b5ac061..d6ad8dc 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1095,8 +1095,10 @@ int main(int argc, char *argv[])
+ 				pr_err("bitmap file needed with -b in --assemble mode\n");
+ 				exit(2);
+ 			}
+-			if (strcmp(optarg, "internal") == 0) {
+-				pr_err("there is no need to specify --bitmap when assembling arrays with internal bitmaps\n");
++			if (strcmp(optarg, "internal") == 0 ||
++			    strcmp(optarg, "clustered") == 0) {
++				pr_err("no need to specify --bitmap when assembling"
++					" arrays with internal or clustered bitmap\n");
+ 				continue;
+ 			}
+ 			bitmap_fd = open(optarg, O_RDWR);
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch b/SOURCES/mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch
new file mode 100644
index 0000000..d40197a
--- /dev/null
+++ b/SOURCES/mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch
@@ -0,0 +1,60 @@
+From 8cc56e8b3269305ec5483527d853464eac3bf690 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 28 Aug 2017 17:24:27 +0800
+Subject: [RHEL7.5 PATCH 04/13] mdadm/bitmap: examine-bitmap failed when bitmap
+ is external mode
+
+--examine-bitmap: the bitmap_file_open() shouldn't omit the
+regular file descriptor when the bitmap is external mode.
+Such as: ./mdadm -X /mnt/3
+
+This commit is partial revert of commit 0a6bff09d416
+(mdadm/util: unify fstat checking blkdev into function)
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ bitmap.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/bitmap.c b/bitmap.c
+index 3653660..e38cb96 100644
+--- a/bitmap.c
++++ b/bitmap.c
+@@ -183,6 +183,7 @@ static int
+ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
+ {
+ 	int fd;
++	struct stat stb;
+ 	struct supertype *st = *stp;
+ 
+ 	fd = open(filename, O_RDONLY|O_DIRECT);
+@@ -192,7 +193,12 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
+ 		return -1;
+ 	}
+ 
+-	if (fstat_is_blkdev(fd, filename, NULL)) {
++	if (fstat(fd, &stb) < 0) {
++		pr_err("fstat failed for %s: %s\n", filename, strerror(errno));
++		close(fd);
++		return -1;
++	}
++	if ((stb.st_mode & S_IFMT) == S_IFBLK) {
+ 		/* block device, so we are probably after an internal bitmap */
+ 		if (!st)
+ 			st = guess_super(fd);
+@@ -211,11 +217,7 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
+ 				fd = -1;
+ 			}
+ 		}
+-
+ 		*stp = st;
+-	} else {
+-		close(fd);
+-		return -1;
+ 	}
+ 
+ 	return fd;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch b/SOURCES/mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch
new file mode 100644
index 0000000..bbc62fc
--- /dev/null
+++ b/SOURCES/mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch
@@ -0,0 +1,39 @@
+From 4c829c2252d2a6fb4871ec0cdad58b6c3a0218fd Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 20 Mar 2017 18:46:39 +0800
+Subject: [RHEL7.5 PATCH 018/169] mdadm/bitmap:fixed typos in comments of
+ bitmap.h
+
+bitmap.h: fixed trivial typos in comments
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ bitmap.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/bitmap.h b/bitmap.h
+index b8fb071..7b1f80f 100644
+--- a/bitmap.h
++++ b/bitmap.h
+@@ -46,7 +46,7 @@
+  *
+  * The counter counts pending write requests, plus the on-disk bit.
+  * When the counter is '1' and the resync bits are clear, the on-disk
+- * bit can be cleared aswell, thus setting the counter to 0.
++ * bit can be cleared as well, thus setting the counter to 0.
+  * When we set a bit, or in the counter (to start a write), if the fields is
+  * 0, we first set the disk bit and set the counter to 1.
+  *
+@@ -185,7 +185,7 @@ struct bitmap_page {
+ 	 */
+ 	char *map;
+ 	/*
+-	 * in emergencies (when map cannot be alloced), hijack the map
++	 * in emergencies (when map cannot be allocated), hijack the map
+ 	 * pointer and use it as two counters itself
+ 	 */
+ 	unsigned int hijacked;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-check-the-nodes-when-operate-clustered1-array.patch b/SOURCES/mdadm-check-the-nodes-when-operate-clustered1-array.patch
new file mode 100644
index 0000000..9c679e6
--- /dev/null
+++ b/SOURCES/mdadm-check-the-nodes-when-operate-clustered1-array.patch
@@ -0,0 +1,55 @@
+From 9d67f6496c71efbc68b33aea663dbcc1597a0828 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 1 Mar 2017 18:42:33 +0800
+Subject: [RHEL7.5 PATCH 005/169] mdadm:check the nodes when operate
+ clustered array
+
+It doesn't make sense to write_bitmap with less than 2 nodes,
+in order to avoid 'write_bitmap' received invalid nodes number,
+it would be better to do checking nodes in getopt operations.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c  | 4 ++--
+ super1.c | 9 +--------
+ 2 files changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 16fd49a..b5ac061 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -603,8 +603,8 @@ int main(int argc, char *argv[])
+ 		case O(GROW, Nodes):
+ 		case O(CREATE, Nodes):
+ 			c.nodes = parse_num(optarg);
+-			if (c.nodes <= 0) {
+-				pr_err("invalid number for the number of cluster nodes: %s\n",
++			if (c.nodes < 2) {
++				pr_err("clustered array needs two nodes at least: %s\n",
+ 					optarg);
+ 				exit(2);
+ 			}
+diff --git a/super1.c b/super1.c
+index 87a74cb..882cd61 100644
+--- a/super1.c
++++ b/super1.c
+@@ -2380,14 +2380,7 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
+ 		}
+ 
+ 		if (bms->version == BITMAP_MAJOR_CLUSTERED) {
+-			if (st->nodes == 1) {
+-				/* the parameter for nodes is not valid */
+-				pr_err("Warning: cluster-md at least needs two nodes\n");
+-				return -EINVAL;
+-			} else if (st->nodes == 0)
+-				/* --nodes is not specified */
+-				break;
+-			else if (__cpu_to_le32(st->nodes) < bms->nodes) {
++			if (__cpu_to_le32(st->nodes) < bms->nodes) {
+ 				/* Since the nodes num is not increased, no need to check the space
+ 				 * is enough or not, just update bms->nodes */
+ 				bms->nodes = __cpu_to_le32(st->nodes);
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-fix-typo1-in-comment.patch b/SOURCES/mdadm-fix-typo1-in-comment.patch
new file mode 100644
index 0000000..b3a9c2f
--- /dev/null
+++ b/SOURCES/mdadm-fix-typo1-in-comment.patch
@@ -0,0 +1,27 @@
+From e93bb91b12b5c8a799a04e314d376da38d007e9d Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 1 Mar 2017 16:44:33 +0800
+Subject: [RHEL7.5 PATCH 004/169] mdadm:fix typo in comment
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index b5d89e4..16fd49a 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1268,7 +1268,7 @@ int main(int argc, char *argv[])
+ 	 * hopefully it's mostly right but there might be some stuff
+ 	 * missing
+ 	 *
+-	 * That is mosty checked in the per-mode stuff but...
++	 * That is mostly checked in the per-mode stuff but...
+ 	 *
+ 	 * For @,B,C and A without -s, the first device listed must be
+ 	 * an md device.  We check that here and open it.
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch b/SOURCES/mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch
new file mode 100644
index 0000000..f3af424
--- /dev/null
+++ b/SOURCES/mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch
@@ -0,0 +1,39 @@
+From 7054da69c778a69ea5e83965bb15620ad5e9e053 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 20 Mar 2017 13:20:06 +0800
+Subject: [RHEL7.5 PATCH 011/169] mdadm:fixed some trivial typos in
+ comments of mdadm.h
+
+mdadm.h: fixed some trivial typos in comments
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index 71b8afb..91fd9eb 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -552,7 +552,7 @@ struct mdstat_ent {
+ 	char		devnm[32];
+ 	int		active;
+ 	char		*level;
+-	char		*pattern; /* U or up, _ for down */
++	char		*pattern; /* U for up, _ for down */
+ 	int		percent; /* -1 if no resync */
+ 	int		resync; /* 3 if check, 2 if reshape, 1 if resync, 0 if recovery */
+ 	int		devcnt;
+@@ -742,7 +742,7 @@ struct reshape {
+ 	unsigned long long new_size; /* New size of array in sectors */
+ };
+ 
+-/* A superswitch provides entry point the a metadata handler.
++/* A superswitch provides entry point to a metadata handler.
+  *
+  * The superswitch primarily operates on some "metadata" that
+  * is accessed via the 'supertype'.
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch b/SOURCES/mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch
new file mode 100644
index 0000000..0492bf1
--- /dev/null
+++ b/SOURCES/mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch
@@ -0,0 +1,38 @@
+From 5b2846684ef5172eccc432e3520b79efbc2abba5 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Thu, 30 Mar 2017 15:38:08 +0800
+Subject: [RHEL7.5 PATCH 044/169] mdadm/grow: reshape would be stuck from
+ raid1 to raid5
+
+systemctl doesn't interpret mdadm-grow-continue@.service
+correctly due to the wrong argument provided in [service],
+it should be corrected %I as %i. Otherwise, if the service
+cannot start by systemctl and the reshap progress would be
+stuck all time when grows array from raid1 to raid5.
+
+reproduce steps:
+./mdadm -CR /dev/md0 -l1 -b internal -n2 /dev/loop[0-1]
+./mdadm --grow /dev/md0 -l5 -n3 -a /dev/loop2
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ systemd/mdadm-grow-continue@.service | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
+index 5c667d2..882bc0b 100644
+--- a/systemd/mdadm-grow-continue@.service
++++ b/systemd/mdadm-grow-continue@.service
+@@ -10,7 +10,7 @@ Description=Manage MD Reshape on /dev/%I
+ DefaultDependencies=no
+ 
+ [Service]
+-ExecStart=BINDIR/mdadm --grow --continue /dev/%I
++ExecStart=BINDIR/mdadm --grow --continue /dev/%i
+ StandardInput=null
+ StandardOutput=null
+ StandardError=null
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-install-twomore-udev-rules-in-mdadm.spec.patch b/SOURCES/mdadm-install-twomore-udev-rules-in-mdadm.spec.patch
new file mode 100644
index 0000000..935537c
--- /dev/null
+++ b/SOURCES/mdadm-install-twomore-udev-rules-in-mdadm.spec.patch
@@ -0,0 +1,32 @@
+From 52f6a11ec800114164a5b6866548109e0cbf8578 Mon Sep 17 00:00:00 2001
+From: Song Liu <songliubraving@fb.com>
+Date: Mon, 28 Aug 2017 15:20:35 -0700
+Subject: [RHEL7.5 PATCH 02/13] mdadm: install two more udev rules in
+ mdadm.spec
+
+To avoid rpmbuild error.
+
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.spec | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/mdadm.spec b/mdadm.spec
+index 4e97efb..4e6f870 100644
+--- a/mdadm.spec
++++ b/mdadm.spec
+@@ -37,8 +37,10 @@ rm -rf $RPM_BUILD_ROOT
+ %doc TODO ChangeLog mdadm.conf-example COPYING
+ %{_sbindir}/mdadm
+ %{_sbindir}/mdmon
++/usr/lib/udev/rules.d/01-md-raid-creating.rules
+ /usr/lib/udev/rules.d/63-md-raid-arrays.rules
+ /usr/lib/udev/rules.d/64-md-raid-assembly.rules
++/usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules
+ %config(noreplace,missingok)/%{_sysconfdir}/mdadm.conf
+ %{_mandir}/man*/md*
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch b/SOURCES/mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch
new file mode 100644
index 0000000..88f2178
--- /dev/null
+++ b/SOURCES/mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch
@@ -0,0 +1,32 @@
+From 27c48b375d8fb6b4835fd9b11593c75d247ea1c1 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 20 Mar 2017 13:21:03 +0800
+Subject: [RHEL7.5 PATCH 012/169] mdadm:it doesn't make sense to set
+ --bitmap twice
+
+mdadm.c: it doesn't make sense to set --bitmap twice.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/mdadm.c b/mdadm.c
+index d6ad8dc..08ddcab 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1139,6 +1139,10 @@ int main(int argc, char *argv[])
+ 		case O(CREATE,Bitmap): /* here we create the bitmap */
+ 		case O(GROW,'b'):
+ 		case O(GROW,Bitmap):
++			if (s.bitmap_file) {
++				pr_err("bitmap cannot be set twice. Second value: %s.\n", optarg);
++				exit(2);
++			}
+ 			if (strcmp(optarg, "internal") == 0 ||
+ 			    strcmp(optarg, "none") == 0 ||
+ 			    strchr(optarg, '/') != NULL) {
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch b/SOURCES/mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch
new file mode 100644
index 0000000..08bba0b
--- /dev/null
+++ b/SOURCES/mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch
@@ -0,0 +1,31 @@
+From e39c76b9b72db00d32780e9f30dfba25f58922d2 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 12 Apr 2017 16:37:27 +0800
+Subject: [RHEL7.5 PATCH 074/169] mdadm/manpage:clustered arrays don't
+ support array-size yet
+
+Update manpage for array-size section:
+Clustered arrays don't support the --array-size yet.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index f10a8b8..fb99a5c 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -541,6 +541,8 @@ A value of
+ restores the apparent size of the array to be whatever the real
+ amount of available space is.
+ 
++Clustered arrays do not support this parameter yet.
++
+ .TP
+ .BR \-c ", " \-\-chunk=
+ Specify chunk size of kilobytes.  The default when creating an
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-manpage-update-manpage-for-readonly-parameter.patch b/SOURCES/mdadm-manpage-update-manpage-for-readonly-parameter.patch
new file mode 100644
index 0000000..7c248b3
--- /dev/null
+++ b/SOURCES/mdadm-manpage-update-manpage-for-readonly-parameter.patch
@@ -0,0 +1,44 @@
+From 8a70632fc2f9026e0f4895f5348cc7cd20d9fbb3 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 12 Apr 2017 16:36:38 +0800
+Subject: [RHEL7.5 PATCH 073/169] mdadm/manpage:update manpage for readonly
+ parameter
+
+update readonly in manpage:
+Currently both the readwrite and readonly are worked well,
+update the readonly section.
+One commit in linux/driver/md. Cleared "MD_CLOSING bit" to
+Fixes: af8d8e6f0315 ("md: changes for MD_STILL_CLOSED flag")
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.8.in | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 744c12b..f10a8b8 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -925,7 +925,8 @@ will not try to be so clever.
+ Start the array
+ .B read only
+ rather than read-write as normal.  No writes will be allowed to the
+-array, and no resync, recovery, or reshape will be started.
++array, and no resync, recovery, or reshape will be started. It works with
++Create, Assemble, Manage and Misc mode.
+ 
+ .TP
+ .BR \-a ", " "\-\-auto{=yes,md,mdp,part,p}{NN}"
+@@ -2232,7 +2233,7 @@ be in use.
+ 
+ .TP
+ .B \-\-readonly
+-start the array readonly \(em not supported yet.
++start the array in readonly mode.
+ 
+ .SH MANAGE MODE
+ .HP 12
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch b/SOURCES/mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch
new file mode 100644
index 0000000..0b1b9e4
--- /dev/null
+++ b/SOURCES/mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch
@@ -0,0 +1,36 @@
+From 17645275ca30a8ca8024f03672aae45d455bbc4b Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Tue, 9 May 2017 14:25:17 +0800
+Subject: [RHEL7.5 PATCH 119/169] mdadm/md.4: set page-length as 1000 to
+ avoid warnings from grotty
+
+"nroff" ("man") or ("tbl") needs a long page to avoid warnings
+from "grotty", set 'pl' as 1000 to fix the following issue.
+
+This command invokes by Makefile rule.
+linux-tjrh:~/mdadm # man -l md.4 > test
+grotty:<standard input> (<standard input>):5967:
+character above first line discarded
+... ...
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ md.4 | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/md.4 b/md.4
+index 5bdf7a7..3a1d677 100644
+--- a/md.4
++++ b/md.4
+@@ -4,6 +4,7 @@
+ .\"   the Free Software Foundation; either version 2 of the License, or
+ .\"   (at your option) any later version.
+ .\" See file COPYING in distribution for details.
++.if n .pl 1000v
+ .TH MD 4
+ .SH NAME
+ md \- Multiple Device driver aka Linux Software RAID
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch b/SOURCES/mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch
new file mode 100644
index 0000000..34aae18
--- /dev/null
+++ b/SOURCES/mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch
@@ -0,0 +1,34 @@
+From e81070a69bf0c6e20f95806b6c60f6ec5c952a20 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 20 Mar 2017 13:21:24 +0800
+Subject: [RHEL7.5 PATCH 013/169] mdadm/mdmon:deleted the abort_reshape
+ never invoked
+
+mdmon.c: abort_reshape() has implemented in Grow.c,
+this function doesn't make a lot of sense here.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdmon.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/mdmon.c b/mdmon.c
+index e4b73d9..95e9bba 100644
+--- a/mdmon.c
++++ b/mdmon.c
+@@ -580,11 +580,6 @@ int restore_stripes(int *dest, unsigned long long *offsets,
+ 	return 1;
+ }
+ 
+-void abort_reshape(struct mdinfo *sra)
+-{
+-	return;
+-}
+-
+ int save_stripes(int *source, unsigned long long *offsets,
+ 		 int raid_disks, int chunk_size, int level, int layout,
+ 		 int nwrites, int *dest,
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-r5cache-allow-adding-journal-to-array-without-.patch b/SOURCES/mdadm-r5cache-allow-adding-journal-to-array-without-.patch
new file mode 100644
index 0000000..1889f38
--- /dev/null
+++ b/SOURCES/mdadm-r5cache-allow-adding-journal-to-array-without-.patch
@@ -0,0 +1,63 @@
+From 3373d49f32b2bd8149f633727eba453708a9bf9c Mon Sep 17 00:00:00 2001
+From: Song Liu <songliubraving@fb.com>
+Date: Tue, 28 Mar 2017 11:04:44 -0700
+Subject: [RHEL7.5 PATCH 160/169] mdadm/r5cache: allow adding journal to
+ array without journal
+
+Currently, --add-journal can be only used to recreate broken journal
+for arrays with journal since  creation. As the kernel code getting
+more mature, this constraint is no longer necessary.
+
+This patch allows --add-journal to add journal to array without
+journal.
+
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c   | 6 ------
+ mdadm.8.in | 5 ++---
+ 2 files changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index 04b9398..b82a729 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -911,7 +911,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 
+ 	/* only add journal to array that supports journaling */
+ 	if (dv->disposition == 'j') {
+-		struct mdinfo mdi;
+ 		struct mdinfo *mdp;
+ 
+ 		mdp = sysfs_read(fd, NULL, GET_ARRAY_STATE);
+@@ -928,11 +927,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 
+ 		sysfs_free(mdp);
+ 
+-		tst->ss->getinfo_super(tst, &mdi, NULL);
+-		if (mdi.journal_device_required == 0) {
+-			pr_err("%s does not support journal device.\n", devname);
+-			return -1;
+-		}
+ 		disc.raid_disk = 0;
+ 	}
+ 
+diff --git a/mdadm.8.in b/mdadm.8.in
+index ecfe9da..461c5de 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -1526,9 +1526,8 @@ the device is found or <slot>:missing in case the device is not found.
+ 
+ .TP
+ .BR \-\-add-journal
+-Recreate journal for RAID-4/5/6 array that lost a journal device. In the
+-current implementation, this command cannot add a journal to an array
+-that had a failed journal. To avoid interrupting on-going write opertions,
++Add journal to an existing array, or recreate journal for RAID-4/5/6 array
++that lost a journal device. To avoid interrupting on-going write opertions,
+ .B \-\-add-journal
+ only works for array in Read-Only state.
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-retire-mdassemble-in-make-everything.patch b/SOURCES/mdadm-retire-mdassemble-in-make-everything.patch
new file mode 100644
index 0000000..e394a22
--- /dev/null
+++ b/SOURCES/mdadm-retire-mdassemble-in-make-everything.patch
@@ -0,0 +1,58 @@
+From b63804583e25fbc00b96c7f37f97d568b5b1ba9c Mon Sep 17 00:00:00 2001
+From: Coly Li <colyli@suse.de>
+Date: Sun, 16 Apr 2017 15:01:29 +0800
+Subject: [RHEL7.5 PATCH 086/169] mdadm: retire mdassemble in make
+ everything
+
+make everything reports no rule to make mdassemble, because mdassemble
+is removed from mdadm. This patch removes mdassemble from "everything"
+in Makefile, now there is no failure when compiling a static mdadm binary.
+
+Signed-off-by: Coly Li <colyli@suse.de>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Makefile | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index a5d2a0a..5655812 100644
+--- a/Makefile
++++ b/Makefile
+@@ -169,12 +169,10 @@ check_rundir:
+ 	fi
+ 
+ everything: all mdadm.static swap_super test_stripe raid6check \
+-	mdassemble mdassemble.auto mdassemble.static mdassemble.man \
+ 	mdadm.Os mdadm.O2 man
+ everything-test: all mdadm.static swap_super test_stripe \
+-	mdassemble.auto mdassemble.static mdassemble.man \
+ 	mdadm.Os mdadm.O2 man
+-# mdadm.uclibc and mdassemble.uclibc don't work on x86-64
++# mdadm.uclibc doesn't work on x86-64
+ # mdadm.tcc doesn't work..
+ 
+ mdadm : $(OBJS) | check_rundir
+@@ -226,9 +224,6 @@ md.man : md.4
+ mdadm.conf.man : mdadm.conf.5
+ 	man -l mdadm.conf.5 > mdadm.conf.man
+ 
+-mdassemble.man : mdassemble.8
+-	man -l mdassemble.8 > mdassemble.man
+-
+ raid6check.man : raid6check.8
+ 	man -l raid6check.8 > raid6check.man
+ 
+@@ -293,9 +288,7 @@ test: mdadm mdmon test_stripe swap_super raid6check
+ clean :
+ 	rm -f mdadm mdmon $(OBJS) $(MON_OBJS) $(STATICOBJS) core *.man \
+ 	mdadm.tcc mdadm.uclibc mdadm.static *.orig *.porig *.rej *.alt .merge_file_* \
+-	mdadm.Os mdadm.O2 mdmon.O2 \
+-	mdassemble mdassemble.static mdassemble.auto mdassemble.uclibc \
+-	mdassemble.klibc swap_super \
++	mdadm.Os mdadm.O2 mdmon.O2 swap_super \
+ 	init.cpio.gz mdadm.uclibc.static test_stripe raid6check raid6check.o mdmon \
+ 	mdadm.8
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-set-journal_clean-after-scanning-all-disks.patch b/SOURCES/mdadm-set-journal_clean-after-scanning-all-disks.patch
new file mode 100644
index 0000000..24cadfe
--- /dev/null
+++ b/SOURCES/mdadm-set-journal_clean-after-scanning-all-disks.patch
@@ -0,0 +1,60 @@
+From 3b8c7127558bad386c8350e039061107c9cf6cde Mon Sep 17 00:00:00 2001
+From: Song Liu <songliubraving@fb.com>
+Date: Tue, 29 Aug 2017 09:53:02 -0700
+Subject: [RHEL7.5 PATCH 03/13] mdadm: set journal_clean after scanning all
+ disks
+
+Summary:
+In Incremental.c:count_active(), max_events is tracked to show to
+which devices are up to date. If a device has events==max_events+1,
+getinfo_super() is called to reload the superblock from this
+device. getinfo_super1() blindly set journal_clean to 0, which is
+wrong.
+
+This patch fixes this by tracking max_journal_events for all the
+disks. After scanning all disks, journal_clean is set if
+max_journal_events >= max_events-1.
+
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Incremental.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/Incremental.c b/Incremental.c
+index 6cf2174..91301eb 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -684,6 +684,7 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
+ 	int cnt = 0;
+ 	int replcnt = 0;
+ 	__u64 max_events = 0;
++	__u64 max_journal_events = 0;
+ 	char *avail = NULL;
+ 	int *best = NULL;
+ 	char *devmap = NULL;
+@@ -714,8 +715,9 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
+ 
+ 		info.array.raid_disks = raid_disks;
+ 		st->ss->getinfo_super(st, &info, devmap + raid_disks * devnum);
+-		if (info.disk.raid_disk == MD_DISK_ROLE_JOURNAL)
+-			bestinfo->journal_clean = 1;
++		if (info.disk.raid_disk == MD_DISK_ROLE_JOURNAL &&
++		    info.events > max_journal_events)
++			max_journal_events = info.events;
+ 		if (!avail) {
+ 			raid_disks = info.array.raid_disks;
+ 			avail = xcalloc(raid_disks, 1);
+@@ -765,6 +767,8 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
+ 			replcnt++;
+ 		st->ss->free_super(st);
+ 	}
++	if (max_journal_events >= max_events - 1)
++		bestinfo->journal_clean = 1;
+ 
+ 	if (!avail)
+ 		return 0;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-test-Add-disks-to-support-testing-phsical-devi.patch b/SOURCES/mdadm-test-Add-disks-to-support-testing-phsical-devi.patch
new file mode 100644
index 0000000..3617c77
--- /dev/null
+++ b/SOURCES/mdadm-test-Add-disks-to-support-testing-phsical-devi.patch
@@ -0,0 +1,139 @@
+From 25357919d227fd907e4da167d0e07f33f9c94bca Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 14 Jun 2017 21:02:53 +0800
+Subject: [RHEL7.5 PATCH 157/169] mdadm/test: Add '--disks=' to support
+ testing phsical devices
+
+If test mode has set as '--dev=disk', then users can specify
+the argument of "--disks" to test a bunch of physical devices.
+For example: ./test --dev=disk --disks=/dev/sda{2..15}
+could execute all test cases on physical devices.
+
+Currently, the --dev=disk mode would confilct with testdev()
+in current test cases, thus ignore testing testdev() if has
+set --dev=disk mode.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ test | 37 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 32 insertions(+), 5 deletions(-)
+
+diff --git a/test b/test
+index df2eeab..87e2df2 100755
+--- a/test
++++ b/test
+@@ -73,11 +73,11 @@ save_log() {
+ 	then
+ 		# not supported lvm type yet
+ 		echo
+-	elif [ $DEVTYPE == 'loop' ]
++	elif [ "$DEVTYPE" == 'loop' -o "$DEVTYPE" == 'disk' ]
+ 	then
+ 		if [ ! -z ${array[@]} -a ${#array[@]} -ge 1 ]
+ 		then
+-			md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/$DEVTYPE" | cut -d'=' -f2))
++			md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/" | cut -d'=' -f2))
+ 			cat /proc/mdstat | grep -q "bitmap"
+ 			if [ $? -eq 0 ]
+ 			then
+@@ -114,6 +114,9 @@ cleanup() {
+ 			eval "lvremove --quiet -f \$dev$d"
+ 		done
+ 		;;
++	disk )
++		$mdadm --zero ${disks[@]} &> /dev/null
++		;;
+ 	esac
+ }
+ 
+@@ -128,6 +131,7 @@ do_setup() {
+ 	[ -d $logdir ] || mkdir -p $logdir
+ 	dmesg -c > /dev/null
+ 
++	devlist=
+ 	if [ "$DEVTYPE" == "loop" ]
+ 	then
+ 		# make sure there are no loop devices remaining.
+@@ -139,8 +143,22 @@ do_setup() {
+ 			losetup -d /dev/loop[0-9]* 2> /dev/null
+ 			sleep 0.2
+ 		done
++	elif [ "$DEVTYPE" == "disk" ]
++	then
++		if [ ! -z "$disks" ]
++		then
++			for d in $(seq 0 ${#disks[@]})
++			do
++				eval "dev$d=${disks[$d]}"
++				eval devlist=\"\$devlist \$dev$d\"
++				eval devlist$d=\"\$devlist\"
++			done
++			$mdadm --zero ${disks[@]} &> /dev/null
++		else
++			echo "Forget to provide physical devices for disk mode."
++			exit 1
++		fi
+ 	fi
+-	devlist=
+ 	for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ 	do
+ 		sz=$size
+@@ -320,6 +338,7 @@ no_errors() {
+ # basic device test
+ testdev() {
+ 	[ -b $1 ] || die "$1 isn't a block device."
++	[ "$DEVTYPE" == "disk" ] && return 0
+ 	udevadm settle
+ 	dev=$1
+ 	cnt=$2
+@@ -383,6 +402,7 @@ do_test() {
+ do_help() {
+ 	cat <<-EOF
+ 	Usage: $0 [options]
++	Example for disk mode: ./test --dev=disk --disks=/dev/sda{2..15}
+ 	Options:
+ 		--tests=test1,test2,...     Comma separated list of tests to run
+ 		--raidtype=                 raid0|linear|raid1|raid456|raid10|ddf|imsm
+@@ -391,7 +411,8 @@ do_help() {
+ 		--logdir=directory          Directory to save all logfiles in
+ 		--save-logs                 Usually use with --logdir together
+ 		--keep-going | --no-error   Don't stop on error, ie. run all tests
+-		--dev=loop|lvm|ram          Use loop devices (default), LVM, or RAM disk
++		--dev=loop|lvm|ram|disk     Use loop devices (default), LVM, RAM or disk
++		--disks=                    Provide a bunch of physical devices for test
+ 		--volgroup=name             LVM volume group for LVM test
+ 		setup                       Setup test environment and exit
+ 		cleanup                     Cleanup test environment
+@@ -476,6 +497,9 @@ parse_args() {
+ 			ram )
+ 				DEVTYPE=ram
+ 				;;
++			disk )
++				DEVTYPE=disk
++				;;
+ 			* )
+ 				echo "Unknown argument: $i"
+ 				do_help
+@@ -483,6 +507,9 @@ parse_args() {
+ 				;;
+ 			esac
+ 			;;
++		--disks=* )
++			disks=(${disks[*]} ${i##*=})
++			;;
+ 		--volgroup=* )
+ 			LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'`
+ 			;;
+@@ -509,7 +536,7 @@ check_env() {
+ 		echo "test: please run 'make everything' before perform testing."
+ 		exit 1
+ 	}
+-	cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck)
++	cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck seq)
+ 	for cmd in ${cmds[@]}
+ 	do
+ 		which $cmd > /dev/null || {
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch b/SOURCES/mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch
new file mode 100644
index 0000000..603f9e1
--- /dev/null
+++ b/SOURCES/mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch
@@ -0,0 +1,70 @@
+From 8403b202ca3cd390589a26a85a7ee9af1cc7c69b Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 14 Jun 2017 21:02:52 +0800
+Subject: [RHEL7.5 PATCH 156/169] mdadm/test: Add '--raidtype=' to run
+ different raidlevel cases
+
+It supports to specify the argument of "--raidtype"
+to run the different raid level cases. Details refer
+to the do_help() usage.
+For example: ./test --raidtype=raid1
+could execute all the raid1 test cases under tests/.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ test | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+diff --git a/test b/test
+index 7ee523b..df2eeab 100755
+--- a/test
++++ b/test
+@@ -385,6 +385,7 @@ do_help() {
+ 	Usage: $0 [options]
+ 	Options:
+ 		--tests=test1,test2,...     Comma separated list of tests to run
++		--raidtype=                 raid0|linear|raid1|raid456|raid10|ddf|imsm
+ 		--disable-multipath         Disable any tests involving multipath
+ 		--disable-integrity         Disable slow tests of RAID[56] consistency
+ 		--logdir=directory          Directory to save all logfiles in
+@@ -419,6 +420,36 @@ parse_args() {
+ 		--tests=* )
+ 			TESTLIST=($(echo ${i##*=} | sed -e 's/,/ /g'))
+ 			;;
++		--raidtype=* )
++			case ${i##*=} in
++			raid0 )
++				TESTLIST=($(ls $testdir | grep "[0-9][0-9]r0\|raid0"))
++				;;
++			linear )
++				TESTLIST=($(ls $testdir | grep "linear"))
++				;;
++			raid1 )
++				TESTLIST=($(ls $testdir | grep "[0-9][0-9]r1\|raid1" | grep -vi raid10))
++				;;
++			raid456 )
++				TESTLIST=($(ls $testdir | grep "[0-9][0-9]r[4-6]\|raid[4-6]"))
++				;;
++			raid10 )
++				TESTLIST=($(ls $testdir | grep "[0-9][0-9]r10\|raid10"))
++				;;
++			ddf )
++				TESTLIST=($(ls $testdir | grep "[0-9][0-9]ddf"))
++				;;
++			imsm )
++				TESTLIST=($(ls $testdir | grep "[0-9][0-9]imsm"))
++				;;
++			* )
++				echo "Unknown argument: $i"
++				do_help
++				exit 1
++				;;
++			esac
++			;;
+ 		--logdir=* )
+ 			logdir="${i##*=}"
+ 			;;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-test-Convert-code-formatto-use-Tab.patch b/SOURCES/mdadm-test-Convert-code-formatto-use-Tab.patch
new file mode 100644
index 0000000..80a330d
--- /dev/null
+++ b/SOURCES/mdadm-test-Convert-code-formatto-use-Tab.patch
@@ -0,0 +1,806 @@
+From 662c349a5a995c270c8f7bcf0a4b4a0408c813fd Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 7 Jun 2017 17:31:26 +0800
+Subject: [RHEL7.5 PATCH 154/169] mdadm/test: Convert code format to use
+ Tab
+
+In case to make codes neat, this commit didn't change
+any codes, just tidy up and use Tab as code format.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ test | 702 ++++++++++++++++++++++++++++++++++++-------------------------------
+ 1 file changed, 378 insertions(+), 324 deletions(-)
+
+diff --git a/test b/test
+index 13f1bda..7942d6e 100755
+--- a/test
++++ b/test
+@@ -3,8 +3,9 @@
+ # run test suite for mdadm
+ user=`id -un`
+ if [ " $user" != " root" ]
+-then echo >&2 "test: testing can only be done as 'root'."
+-     exit 1;
++then
++	echo >&2 "test: testing can only be done as 'root'."
++	exit 1
+ fi
+ 
+ prefix='[0-9][0-9]'
+@@ -13,7 +14,7 @@ dir=`pwd`
+ mdadm=$dir/mdadm
+ if [ \! -x $mdadm ]
+ then
+-   echo >&2 "test: $mdadm isn't usable."
++	echo >&2 "test: $mdadm isn't usable."
+ fi
+ 
+ testdir="tests"
+@@ -25,8 +26,9 @@ echo "Testing on linux-$(uname -r) kernel"
+ 
+ # Check whether to run multipath tests
+ modprobe multipath 2> /dev/null
+-if grep -s 'Personalities : .*multipath' > /dev/null /proc/mdstat ; then
+-    MULTIPATH="yes"
++if grep -s 'Personalities : .*multipath' > /dev/null /proc/mdstat
++then
++	MULTIPATH="yes"
+ fi
+ INTEGRITY=yes
+ DEVTYPE=loop
+@@ -36,7 +38,9 @@ LVM_VOLGROUP=mdtest
+ export MDADM_NO_SYSTEMCTL=1
+ 
+ # assume md0, md1, md2 exist in /dev
+-md0=/dev/md0 md1=/dev/md1 md2=/dev/md2
++md0=/dev/md0
++md1=/dev/md1
++md2=/dev/md2
+ mdp0=/dev/md_d0
+ mdp1=/dev/md_d1
+ 
+@@ -69,21 +73,21 @@ config=/tmp/mdadm.conf
+ cleanup() {
+ 	udevadm settle
+ 	$mdadm -Ssq 2> /dev/null
+-        case $DEVTYPE in
+-        loop)
+-	  for d in 0 1 2 3 4 5 6 7  8 9 10 11 12 13
+-	  do
+-	    losetup -d /dev/loop$d ; # rm -f $targetdir/mdtest$d
+-	    rm -f /dev/disk/by-path/loop*
+-	  done
+-          ;;
+-        lvm)
+-	  for d in 0 1 2 3 4 5 6 7  8 9 10 11 12 13
+-	  do
+-	    eval "lvremove --quiet -f \$dev$d"
+-	  done
+-          ;;
+-        esac
++	case $DEVTYPE in
++	loop)
++		for d in 0 1 2 3 4 5 6 7  8 9 10 11 12 13
++		do
++			losetup -d /dev/loop$d # rm -f $targetdir/mdtest$d
++			rm -f /dev/disk/by-path/loop*
++		done
++		;;
++	lvm)
++		for d in 0 1 2 3 4 5 6 7  8 9 10 11 12 13
++		do
++			eval "lvremove --quiet -f \$dev$d"
++		done
++		;;
++	esac
+ }
+ 
+ ctrl_c() {
+@@ -91,329 +95,377 @@ ctrl_c() {
+ }
+ 
+ do_setup() {
+-  trap cleanup 0 1 3 15
+-  trap ctrl_c 2
++	trap cleanup 0 1 3 15
++	trap ctrl_c 2
+ 
+-  # make sure there are no loop devices remaining.
+-  # udev started things can sometimes prevent them being stopped
+-  # immediately
+-  while grep loop /proc/partitions > /dev/null 2>&1
+-  do
+-    mdadm -Ss
+-    losetup -d /dev/loop[0-9]* 2> /dev/null
+-    sleep 1
+-  done
+-  devlist=
+-  for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+-  do
+-    sz=$size
+-    if [ $d -gt 7 ]; then sz=$ddfsize ; fi
+-    case $DEVTYPE in
+-    loop)
+-      [ -f $targetdir/mdtest$d ] || dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1
+-      # make sure udev doesn't touch
+-      mdadm --zero $targetdir/mdtest$d 2> /dev/null
+-      [ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d
+-      if [ $d -eq 7 ]
+-      then
+-        losetup /dev/loop$d $targetdir/mdtest6 # for multipath use
+-      else
+-        losetup /dev/loop$d $targetdir/mdtest$d
+-      fi
+-      eval dev$d=/dev/loop$d
+-      eval file$d=$targetdir/mdtest$d
+-      ;;
+-    lvm)
+-      unset MULTIPATH
+-      eval dev$d=/dev/mapper/${LVM_VOLGROUP}-mdtest$d
+-      if ! lvcreate --quiet -L ${sz}K -n mdtest$d $LVM_VOLGROUP; then
+-	  trap '' 0 # make sure lvremove is not called
+-	  eval echo error creating \$dev$d
+-	  exit 129
+-      fi
+-      ;;
+-    ram)
+-      unset MULTIPATH
+-      eval dev$d=/dev/ram$d
+-      ;;
+-    esac
+-    eval devlist=\"\$devlist \$dev$d\"
+-    eval devlist$d=\"\$devlist\"
+-   #" <-- add this quote to un-confuse vim syntax highlighting
+-  done
+-  path0=$dev6
+-  path1=$dev7
+-
+-  ulimit -c unlimited
+-  [ -f /proc/mdstat ] || modprobe md_mod
+-  echo 2000 > /proc/sys/dev/raid/speed_limit_max
+-  echo 0 > /sys/module/md_mod/parameters/start_ro
++	# make sure there are no loop devices remaining.
++	# udev started things can sometimes prevent them being stopped
++	# immediately
++	while grep loop /proc/partitions > /dev/null 2>&1
++	do
++		mdadm -Ss
++		losetup -d /dev/loop[0-9]* 2> /dev/null
++		sleep 1
++	done
++	devlist=
++	for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
++	do
++		sz=$size
++		if [ $d -gt 7 ]
++		then
++			sz=$ddfsize
++		fi
++		case $DEVTYPE in
++		loop)
++			[ -f $targetdir/mdtest$d ] ||
++				dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1
++			# make sure udev doesn't touch
++			mdadm --zero $targetdir/mdtest$d 2> /dev/null
++			[ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d
++			if [ $d -eq 7 ]
++			then
++				losetup /dev/loop$d $targetdir/mdtest6 # for multipath use
++			else
++				losetup /dev/loop$d $targetdir/mdtest$d
++			fi
++			eval dev$d=/dev/loop$d
++			eval file$d=$targetdir/mdtest$d
++			;;
++		lvm)
++			unset MULTIPATH
++			eval dev$d=/dev/mapper/${LVM_VOLGROUP}-mdtest$d
++			if ! lvcreate --quiet -L ${sz}K -n mdtest$d $LVM_VOLGROUP
++			then
++				trap '' 0 # make sure lvremove is not called
++				eval echo error creating \$dev$d
++				exit 129
++			fi
++			;;
++		ram)
++			unset MULTIPATH
++			eval dev$d=/dev/ram$d
++			;;
++		esac
++		eval devlist=\"\$devlist \$dev$d\"
++		eval devlist$d=\"\$devlist\"
++		#" <-- add this quote to un-confuse vim syntax highlighting
++	done
++	path0=$dev6
++	path1=$dev7
++	ulimit -c unlimited
++	[ -f /proc/mdstat ] || modprobe md_mod
++	echo 2000 > /proc/sys/dev/raid/speed_limit_max
++	echo 0 > /sys/module/md_mod/parameters/start_ro
+ }
+ 
+ # mdadm always adds --quiet, and we want to see any unexpected messages
+ mdadm() {
+-    rm -f $targetdir/stderr
+-    case $* in
+-	*-S* ) udevadm settle
+-	       p=`cat /proc/sys/dev/raid/speed_limit_max`
+-	       echo 20000 > /proc/sys/dev/raid/speed_limit_max
+-    esac
+-    case $* in
+-	*-C* ) $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes;;
+-	* )    $mdadm 2> $targetdir/stderr --quiet "$@"
+-    esac
+-    rv=$?
+-    case $* in
+-	*-S* ) udevadm settle
+-	       echo $p > /proc/sys/dev/raid/speed_limit_max
+-    esac
+-    cat >&2 $targetdir/stderr
+-    return $rv
++	rm -f $targetdir/stderr
++	case $* in
++	*-S* )
++		udevadm settle
++		p=`cat /proc/sys/dev/raid/speed_limit_max`
++		echo 20000 > /proc/sys/dev/raid/speed_limit_max
++		;;
++	esac
++	case $* in
++	*-C* )
++		$mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes
++		;;
++	* )
++		$mdadm 2> $targetdir/stderr --quiet "$@"
++		;;
++	esac
++	rv=$?
++	case $* in
++	*-S* )
++		udevadm settle
++		echo $p > /proc/sys/dev/raid/speed_limit_max
++		;;
++	esac
++	cat >&2 $targetdir/stderr
++	return $rv
+ }
+ 
+ # check various things
+ check() {
+-   case $1 in
+-    spares )
+-       spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0`
+-       if [ $spares -ne $2 ]
+-       then
+-          echo >&2 "ERROR expected $2 spares, found $spares"; exit 1;
+-       fi
+-      ;;
+-    raid* | linear )
+-      grep -s "active $1 " /proc/mdstat > /dev/null || {
+-		echo >&2 "ERROR active $1 not found" ; cat /proc/mdstat ; exit 1;}
+-     ;;
+-    algorithm )
+-      grep -s " algorithm $2 " /proc/mdstat > /dev/null || {
+-	  echo >&2 "ERROR algorithm $2 not found"; cat /proc/mdstat; exit 1;}
+-     ;;
+-    resync | recovery | reshape)
+-	cnt=5
+-	while ! grep -s $1 /proc/mdstat > /dev/null
+-	do
+-	    if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null
+-	    then # Something isn't idle - wait a bit
++	case $1 in
++	spares )
++		spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0`
++		if [ $spares -ne $2 ]
++		then
++			echo >&2 "ERROR expected $2 spares, found $spares"
++			exit 1
++		fi
++		;;
++	raid* | linear )
++		grep -s "active $1 " /proc/mdstat > /dev/null || {
++			echo >&2 "ERROR active $1 not found"
++			cat /proc/mdstat
++			exit 1
++		}
++		;;
++	algorithm )
++		grep -s " algorithm $2 " /proc/mdstat > /dev/null || {
++			echo >&2 "ERROR algorithm $2 not found"
++			cat /proc/mdstat
++			exit 1
++		}
++		;;
++	resync | recovery | reshape )
++		cnt=5
++		while ! grep -s $1 /proc/mdstat > /dev/null
++		do
++			if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null
++			then # Something isn't idle - wait a bit
++				sleep 0.5
++				cnt=$[cnt-1]
++			else
++				echo >&2 ERROR no $1 happening
++				cat /proc/mdstat
++				exit 1
++			fi
++		done
++		;;
++	nosync )
+ 		sleep 0.5
+-		cnt=$[cnt-1]
+-	    else
+-		echo >&2 ERROR no $1 happening; cat /proc/mdstat; exit 1
+-	    fi
+-	done
+-	;;
+-
+-     nosync )
+-       sleep 0.5
+-       # Since 4.2 we delay the close of recovery until there has been a chance for
+-       # spares to be activated.  That means that a recovery that finds nothing
+-       # to do can still take a little longer than expected.
+-       # add an extra check: is sync_completed shows the end is reached, assume
+-       # there is no recovery.
+-       if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat ; then
+-	   incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'`
+-	   if [ -n "$incomplete" ]; then
+-		echo >&2 "ERROR resync or recovery is happening!"; cat /proc/mdstat ; exit 1;
+-	   fi
+-       fi
+-     ;;
+-
+-    wait )
+-      p=`cat /proc/sys/dev/raid/speed_limit_max`
+-      echo 2000000 > /proc/sys/dev/raid/speed_limit_max
+-      sleep 0.1
+-      while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat ||
+-	      grep -v idle > /dev/null /sys/block/md*/md/sync_action
+-      do sleep 0.5;
+-      done
+-      echo $p > /proc/sys/dev/raid/speed_limit_max
+-      ;;
+-
+-    state )
+-       grep -s "blocks.*\[$2\]\$" /proc/mdstat > /dev/null || {
+-		echo >&2 "ERROR state $2 not found!"; cat /proc/mdstat ; exit 1; }
+-       sleep 0.5
+-      ;;
+-
+-    bitmap )
+-       grep -s bitmap > /dev/null /proc/mdstat || {
+-		echo >&2 ERROR no bitmap ; cat /proc/mdstat ; exit 1; }
+-      ;;
+-    nobitmap )
+-       if grep -s "bitmap" > /dev/null /proc/mdstat
+-       then
+-		echo >&2 ERROR bitmap present ; cat /proc/mdstat ; exit 1;
+-       fi
+-      ;;
+-
+-    readonly )
+-       grep -s "read-only" > /dev/null /proc/mdstat || {
+-                echo >&2 "ERROR array is not read-only!"; cat /proc/mdstat ; exit 1; }
+-      ;;
+-
+-    inactive )
+-       grep -s "inactive" > /dev/null /proc/mdstat || {
+-                echo >&2 "ERROR array is not inactive!"; cat /proc/mdstat ; exit 1; }
+-      ;;
+-    * ) echo >&2 ERROR unknown check $1 ; exit 1;
+-   esac
++		# Since 4.2 we delay the close of recovery until there has been a chance for
++		# spares to be activated.  That means that a recovery that finds nothing
++		# to do can still take a little longer than expected.
++		# add an extra check: is sync_completed shows the end is reached, assume
++		# there is no recovery.
++		if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat
++		then
++			incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'`
++			if [ -n "$incomplete" ]
++			then
++				echo >&2 "ERROR resync or recovery is happening!"
++				cat /proc/mdstat
++				exit 1
++			fi
++		fi
++		;;
++	wait )
++		p=`cat /proc/sys/dev/raid/speed_limit_max`
++		echo 2000000 > /proc/sys/dev/raid/speed_limit_max
++		sleep 0.1
++		while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat ||
++			grep -v idle > /dev/null /sys/block/md*/md/sync_action
++		do
++			sleep 0.5
++		done
++		echo $p > /proc/sys/dev/raid/speed_limit_max
++		;;
++	state )
++		grep -s "blocks.*\[$2\]\$" /proc/mdstat > /dev/null || {
++			echo >&2 "ERROR state $2 not found!"
++			cat /proc/mdstat
++			exit 1
++		}
++		sleep 0.5
++		;;
++	bitmap )
++		grep -s bitmap > /dev/null /proc/mdstat || {
++			echo >&2 ERROR no bitmap
++			cat /proc/mdstat
++			exit 1
++		}
++		;;
++	nobitmap )
++		if grep -s "bitmap" > /dev/null /proc/mdstat
++		then
++			echo >&2 ERROR bitmap present
++			cat /proc/mdstat
++			exit 1
++		fi
++		;;
++	readonly )
++		grep -s "read-only" > /dev/null /proc/mdstat || {
++			echo >&2 "ERROR array is not read-only!"
++			cat /proc/mdstat
++			exit 1
++		}
++		;;
++	inactive )
++		grep -s "inactive" > /dev/null /proc/mdstat || {
++			echo >&2 "ERROR array is not inactive!"
++			cat /proc/mdstat
++			exit 1
++		}
++		;;
++	* )
++		echo >&2 ERROR unknown check $1
++		exit 1
++		;;
++	esac
+ }
+ 
+ no_errors() {
+-  if [ -s $targetdir/stderr ]
+-  then echo Bad errors from mdadm: ; cat $targetdir/stderr; exit 2;
+-  fi
++	if [ -s $targetdir/stderr ]
++	then
++		echo Bad errors from mdadm:
++		cat $targetdir/stderr
++		exit 2
++	fi
+ }
+-# basic device test
+ 
++# basic device test
+ testdev() {
+-   udevadm settle
+-   dev=$1
+-   cnt=$2
+-   dvsize=$3
+-   chunk=$4
+-   if [ -z "$5" ]; then
+-      mkfs.ext3 -F -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2
+-   fi
+-   dsize=$[dvsize/chunk]
+-   dsize=$[dsize*chunk]
+-   rasize=$[dsize*2*cnt]
+-   # rasize is in sectors
+-   if [ -n "$DEV_ROUND_K" ]; then
+-      rasize=$[rasize/DEV_ROUND_K/2]
+-      rasize=$[rasize*DEV_ROUND_K*2]
+-   fi
+-   if [ `/sbin/blockdev --getsize $dev` -eq 0 ]; then sleep 2 ; fi
+-   _sz=`/sbin/blockdev --getsize $dev`
+-   if [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ]
+-   then
+-     echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz"
+-     exit 1
+-   fi
++	udevadm settle
++	dev=$1
++	cnt=$2
++	dvsize=$3
++	chunk=$4
++	if [ -z "$5" ]
++	then
++		mkfs.ext3 -F -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2
++	fi
++	dsize=$[dvsize/chunk]
++	dsize=$[dsize*chunk]
++	rasize=$[dsize*2*cnt]
++	# rasize is in sectors
++	if [ -n "$DEV_ROUND_K" ]
++	then
++		rasize=$[rasize/DEV_ROUND_K/2]
++		rasize=$[rasize*DEV_ROUND_K*2]
++	fi
++	if [ `/sbin/blockdev --getsize $dev` -eq 0 ]
++	then
++		sleep 2
++	fi
++	_sz=`/sbin/blockdev --getsize $dev`
++	if [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ]
++	then
++		echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz"
++		exit 1
++	fi
+ }
+ 
+ fast_sync() {
+-  echo 200000 > /proc/sys/dev/raid/speed_limit_max
++	echo 200000 > /proc/sys/dev/raid/speed_limit_max
+ }
+ 
+ rotest() {
+-  dev=$1
+-  fsck -fn $dev >&2
++	dev=$1
++	fsck -fn $dev >&2
+ }
+ 
+ do_test() {
+-  _script=$1
+-  _basename=`basename $_script`
+-  if [ -f "$_script" ]
+-  then
+-    rm -f $targetdir/stderr
+-    # stop all arrays, just incase some script left an array active.
+-    $mdadm -Ssq 2> /dev/null
+-    mdadm --zero $devlist 2> /dev/null
+-    mdadm --zero $devlist 2> /dev/null
+-    # this might have been reset: restore the default.
+-    echo 2000 > /proc/sys/dev/raid/speed_limit_max
+-    # source script in a subshell, so it has access to our
+-    # namespace, but cannot change it.
+-    echo -ne "$_script... "
+-    if ( set -ex ; . $_script ) &> $targetdir/log
+-    then
+-      echo "succeeded"
+-      _fail=0
+-    else
+-      log=log
+-      cat $targetdir/stderr >> $targetdir/log
+-      echo "=======================dmesg=================" >> $targetdir/log
+-      dmesg | tail -n 200 >> $targetdir/log
+-      if [ $exitonerror == 0 ]; then
+-	  log=log-`basename $_script`
+-	  mv $targetdir/log $logdir/$log
+-      fi
+-      echo "FAILED - see $logdir/$log for details"
+-      _fail=1
+-    fi
+-    if [ "$savelogs" == "1" ]; then
+-      cp $targetdir/log $logdir/$_basename.log
+-    fi
+-    if [ "$_fail" == "1" -a "$exitonerror" == "1" ]; then
+-      exit 1
+-    fi
+-  fi
++	_script=$1
++	_basename=`basename $_script`
++	if [ -f "$_script" ]
++	then
++		rm -f $targetdir/stderr
++		# stop all arrays, just incase some script left an array active.
++		$mdadm -Ssq 2> /dev/null
++		mdadm --zero $devlist 2> /dev/null
++		mdadm --zero $devlist 2> /dev/null
++		# this might have been reset: restore the default.
++		echo 2000 > /proc/sys/dev/raid/speed_limit_max
++		# source script in a subshell, so it has access to our
++		# namespace, but cannot change it.
++		echo -ne "$_script... "
++		if ( set -ex ; . $_script ) &> $targetdir/log
++		then
++			echo "succeeded"
++			_fail=0
++		else
++			log=log
++			cat $targetdir/stderr >> $targetdir/log
++			echo "=======================dmesg=================" >> $targetdir/log
++			dmesg | tail -n 200 >> $targetdir/log
++			if [ $exitonerror == 0 ]; then
++				log=log-`basename $_script`
++				mv $targetdir/log $logdir/$log
++			fi
++			echo "FAILED - see $logdir/$log for details"
++			_fail=1
++		fi
++		if [ "$savelogs" == "1" ]
++		then
++			cp $targetdir/log $logdir/$_basename.log
++		fi
++		if [ "$_fail" == "1" -a "$exitonerror" == "1" ]
++		then
++			exit 1
++		fi
++	fi
+ }
+ 
+ do_help() {
+-  echo "Usage: $0 [options]"
+-  echo " Options:"
+-  echo "    --tests=<test1,test2,..>    Comma separated list of tests to run"
+-  echo "    --disable-multipath         Disable any tests involving multipath"
+-  echo "    --disable-integrity         Disable slow tests of RAID[56] consistency"
+-  echo "    --logdir=<directory>        Directory to save logfiles in"
+-  echo "    --save-logs                 Save all logs in <logdir>"
+-  echo "    --keep-going                Don't stop on error, ie. run all tests"
+-  echo "    --dev=[loop|lvm|ram]        Use loop devices (default), LVM, or RAM disk"
+-  echo "    --volgroup=<name>           LVM volume group for LVM test"
+-  echo "    setup                       Setup test environment and exit"
+-  echo "    cleanup                     Cleanup test environment"
+-  echo "    <prefix>                    Run tests with <prefix>"
++	echo "Usage: $0 [options]"
++	echo " Options:"
++	echo "    --tests=<test1,test2,..>    Comma separated list of tests to run"
++	echo "    --disable-multipath         Disable any tests involving multipath"
++	echo "    --disable-integrity         Disable slow tests of RAID[56] consistency"
++	echo "    --logdir=<directory>        Directory to save logfiles in"
++	echo "    --save-logs                 Save all logs in <logdir>"
++	echo "    --keep-going                Don't stop on error, ie. run all tests"
++	echo "    --dev=[loop|lvm|ram]        Use loop devices (default), LVM, or RAM disk"
++	echo "    --volgroup=<name>           LVM volume group for LVM test"
++	echo "    setup                       Setup test environment and exit"
++	echo "    cleanup                     Cleanup test environment"
++	echo "    <prefix>                    Run tests with <prefix>"
+ }
+ 
+ parse_args() {
+-  for i in $*
+-  do
+-    case $i in
+-    [0-9]*)
+-      prefix=$i
+-      ;;
+-    setup)
+-      echo "mdadm test environment setup"
+-      do_setup
+-      trap 0; exit 0
+-      ;;
+-    cleanup)
+-      cleanup
+-      exit 0
+-      ;;
+-    --tests=*)
+-      TESTLIST=`expr "x$i" : 'x[^=]*=\(.*\)' | sed -e 's/,/ /g'`
+-      ;;
+-    --logdir=*)
+-      logdir=`expr "x$i" : 'x[^=]*=\(.*\)'`
+-      ;;
+-    --save-logs)
+-      savelogs=1
+-      ;;
+-    --keep-going | --no-error)
+-      exitonerror=0
+-      ;;
+-    --disable-multipath)
+-      unset MULTIPATH
+-      ;;
+-    --disable-integrity)
+-      unset INTEGRITY
+-      ;;
+-    --dev=loop)
+-      DEVTYPE=loop
+-      ;;
+-    --dev=lvm)
+-      DEVTYPE=lvm
+-      ;;
+-    --dev=ram)
+-      DEVTYPE=ram
+-      ;;
+-    --volgroup=*)
+-      LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'`
+-      ;;
+-    --help)
+-      do_help
+-      exit 0;
+-      ;;
+-    -*)
+-      echo " $0: Unknown argument: $i"
+-      do_help
+-      exit 0;
+-      ;;
+-    esac
+-done
++	for i in $*
++	do
++		case $i in
++		[0-9]* )
++			prefix=$i
++			;;
++		setup )
++			echo "mdadm test environment setup"
++			do_setup
++			trap 0
++			exit 0
++			;;
++		cleanup )
++			cleanup
++			exit 0
++			;;
++		--tests=* )
++			TESTLIST=`expr "x$i" : 'x[^=]*=\(.*\)' | sed -e 's/,/ /g'`
++			;;
++		--logdir=* )
++			logdir=`expr "x$i" : 'x[^=]*=\(.*\)'`
++			;;
++		--save-logs )
++			savelogs=1
++			;;
++		--keep-going | --no-error )
++			exitonerror=0
++			;;
++		--disable-multipath )
++			unset MULTIPATH
++			;;
++		--disable-integrity )
++			unset INTEGRITY
++			;;
++		--dev=loop )
++			DEVTYPE=loop
++			;;
++		--dev=lvm )
++			DEVTYPE=lvm
++			;;
++		--dev=ram )
++			DEVTYPE=ram
++			;;
++		--volgroup=* )
++			LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'`
++			;;
++		--help )
++			do_help
++			exit 0
++			;;
++		-* )
++			echo " $0: Unknown argument: $i"
++			do_help
++			exit 0
++			;;
++		esac
++	done
+ }
+ 
+ logdir=$targetdir
+@@ -422,19 +474,21 @@ parse_args $@
+ do_setup
+ mkdir -p $logdir
+ 
+-if [ "$savelogs" == "1" ]; then
+-  echo "Saving logs to $logdir"
++if [ "$savelogs" == "1" ]
++then
++	echo "Saving logs to $logdir"
+ fi
+ 
+-if [ "x$TESTLIST" != "x" ]; then
+-  for script in $TESTLIST
+-  do
+-    do_test $testdir/$script
+-  done
++if [ "x$TESTLIST" != "x" ]
++then
++	for script in $TESTLIST
++	do
++		do_test $testdir/$script
++	done
+ else
+-  for script in $testdir/$prefix $testdir/$prefix*[^~]
+-  do
+-    do_test $script
+-  done
++	for script in $testdir/$prefix $testdir/$prefix*[^~]
++	do
++		do_test $script
++	done
+ fi
+ exit 0
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-test-Refactor-and-revamp-test-script.patch b/SOURCES/mdadm-test-Refactor-and-revamp-test-script.patch
new file mode 100644
index 0000000..c5cc6ff
--- /dev/null
+++ b/SOURCES/mdadm-test-Refactor-and-revamp-test-script.patch
@@ -0,0 +1,643 @@
+From 20d10b4be873baf6044304702808bd66ce84299c Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Wed, 14 Jun 2017 21:02:51 +0800
+Subject: [RHEL7.5 PATCH 155/169] mdadm/test: Refactor and revamp 'test'
+ script
+
+Adding functions:
+die()
+  uniform the abnormal situations that have to abort.
+check_env()
+  do various basic checking before running test suite.
+save_log()
+  collect array infos, include of dmesg, superblock,
+  bitmap and /proc/mdstat.
+main()
+  the core function of this script.
+
+Improve functions:
+cleanup()
+  clear dmesg and remove the /var/tmp/mdtest* files.
+mdadm()
+  clear superblock once creating or building arrays
+  every time, because it's always creating arrays
+  many times in a test case.
+check()
+  just tidy up with die(), didn't change code meanings.
+testdev()
+  add checking $1 must be a block device, add 'return 0'
+  in final because this function exists in last line of
+  test case, such as tests/05r6tor0.
+do_test()
+  add checking abnormal dmesg and changing log management.
+do_help()
+  just recommend a better way to print Usage.
+parse_args()
+  revamp and improve.
+
+Delete function:
+fast_sync()
+  It's no longer used, so get rid of it.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ test | 408 +++++++++++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 228 insertions(+), 180 deletions(-)
+
+diff --git a/test b/test
+index 7942d6e..7ee523b 100755
+--- a/test
++++ b/test
+@@ -1,37 +1,20 @@
+ #!/bin/bash
+ #
+ # run test suite for mdadm
+-user=`id -un`
+-if [ " $user" != " root" ]
+-then
+-	echo >&2 "test: testing can only be done as 'root'."
+-	exit 1
+-fi
+-
+-prefix='[0-9][0-9]'
+-
+-dir=`pwd`
++dir=$(pwd)
+ mdadm=$dir/mdadm
+-if [ \! -x $mdadm ]
+-then
+-	echo >&2 "test: $mdadm isn't usable."
+-fi
+-
+ testdir="tests"
+-logdir="$testdir/logs"
+-logsave=0
+-exitonerror=1
++targetdir="/var/tmp"
++logdir="$targetdir"
++config=/tmp/mdadm.conf
+ 
+-echo "Testing on linux-$(uname -r) kernel"
++savelogs=0
++exitonerror=1
++prefix='[0-9][0-9]'
+ 
+-# Check whether to run multipath tests
+-modprobe multipath 2> /dev/null
+-if grep -s 'Personalities : .*multipath' > /dev/null /proc/mdstat
+-then
+-	MULTIPATH="yes"
+-fi
+-INTEGRITY=yes
++# use loop devices by default if doesn't specify --dev
+ DEVTYPE=loop
++INTEGRITY=yes
+ LVM_VOLGROUP=mdtest
+ 
+ # make sure to test local mdmon, not system one
+@@ -46,7 +29,6 @@ mdp1=/dev/md_d1
+ 
+ # We test mdadm on loop-back block devices.
+ # dir for storing files should be settable by command line maybe
+-targetdir=/var/tmp
+ size=20000
+ # super0, round down to multiple of 64 and substract 64
+ mdsize0=19904
+@@ -68,20 +50,65 @@ mdsize12=19988
+ # ddf needs bigger devices as 32Meg is reserved!
+ ddfsize=65536
+ 
+-config=/tmp/mdadm.conf
++# $1 is optional parameter, it shows why to save log
++save_log() {
++	status=$1
++	logfile="$status""$_basename".log
++
++	cat $targetdir/stderr >> $targetdir/log
++	cp $targetdir/log $logdir/$_basename.log
++	echo "## $HOSTNAME: saving dmesg." >> $logdir/$logfile
++	dmesg -c >> $logdir/$logfile
++	$mdadm -As 2> /dev/null
++	echo "## $HOSTNAME: saving proc mdstat." >> $logdir/$logfile
++	cat /proc/mdstat >> $logdir/$logfile
++	array=($(mdadm -Ds | cut -d' ' -f2))
++	echo "## $HOSTNAME: mdadm -D ${array[@]}" >> $logdir/$logfile
++	$mdadm -D ${array[@]} >> $logdir/$logfile
++	[ "$1" == "fail" ] &&
++		echo "FAILED - see $logdir/$_basename.log and $logdir/$logfile for details"
++	# ignore saving external(external file, imsm...) bitmap
++	cat /proc/mdstat | grep -q "linear\|external" && return 0
++	if [ $DEVTYPE == 'lvm' ]
++	then
++		# not supported lvm type yet
++		echo
++	elif [ $DEVTYPE == 'loop' ]
++	then
++		if [ ! -z ${array[@]} -a ${#array[@]} -ge 1 ]
++		then
++			md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/$DEVTYPE" | cut -d'=' -f2))
++			cat /proc/mdstat | grep -q "bitmap"
++			if [ $? -eq 0 ]
++			then
++				echo "## $HOSTNAME: mdadm -X ${md_disks[@]}" >> $logdir/$logfile
++				$mdadm -X ${md_disks[@]} >> $logdir/$logfile
++			fi
++		else
++			echo "## $HOSTNAME: no array assembled!" >> $logdir/$logfile
++		fi
++	fi
++}
++
++die() {
++	echo -e "\n\tERROR: $* \n"
++	save_log fail
++	exit 2
++}
+ 
+ cleanup() {
+ 	udevadm settle
+ 	$mdadm -Ssq 2> /dev/null
+ 	case $DEVTYPE in
+-	loop)
++	loop )
+ 		for d in 0 1 2 3 4 5 6 7  8 9 10 11 12 13
+ 		do
+-			losetup -d /dev/loop$d # rm -f $targetdir/mdtest$d
++			losetup -d /dev/loop$d
+ 			rm -f /dev/disk/by-path/loop*
++			rm -f /var/tmp/mdtest$d
+ 		done
+ 		;;
+-	lvm)
++	lvm )
+ 		for d in 0 1 2 3 4 5 6 7  8 9 10 11 12 13
+ 		do
+ 			eval "lvremove --quiet -f \$dev$d"
+@@ -98,23 +125,26 @@ do_setup() {
+ 	trap cleanup 0 1 3 15
+ 	trap ctrl_c 2
+ 
+-	# make sure there are no loop devices remaining.
+-	# udev started things can sometimes prevent them being stopped
+-	# immediately
+-	while grep loop /proc/partitions > /dev/null 2>&1
+-	do
+-		mdadm -Ss
+-		losetup -d /dev/loop[0-9]* 2> /dev/null
+-		sleep 1
+-	done
++	[ -d $logdir ] || mkdir -p $logdir
++	dmesg -c > /dev/null
++
++	if [ "$DEVTYPE" == "loop" ]
++	then
++		# make sure there are no loop devices remaining.
++		# udev started things can sometimes prevent them being stopped
++		# immediately
++		while grep loop /proc/partitions > /dev/null 2>&1
++		do
++			$mdadm -Ssq
++			losetup -d /dev/loop[0-9]* 2> /dev/null
++			sleep 0.2
++		done
++	fi
+ 	devlist=
+ 	for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ 	do
+ 		sz=$size
+-		if [ $d -gt 7 ]
+-		then
+-			sz=$ddfsize
+-		fi
++		[ $d -gt 7 ] && sz=$ddfsize
+ 		case $DEVTYPE in
+ 		loop)
+ 			[ -f $targetdir/mdtest$d ] ||
+@@ -169,7 +199,17 @@ mdadm() {
+ 		;;
+ 	esac
+ 	case $* in
+-	*-C* )
++	*-C* | *--create* | *-B* | *--build* )
++		# clear superblock every time once creating or
++		# building arrays, because it's always creating
++		# and building array many times in a test case.
++		for args in $*
++		do
++			[[ $args =~ "/dev/" ]] && {
++				[[ $args =~ "md" ]] ||
++					$mdadm --zero $args > /dev/null
++			}
++		done
+ 		$mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes
+ 		;;
+ 	* )
+@@ -191,39 +231,28 @@ mdadm() {
+ check() {
+ 	case $1 in
+ 	spares )
+-		spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0`
+-		if [ $spares -ne $2 ]
+-		then
+-			echo >&2 "ERROR expected $2 spares, found $spares"
+-			exit 1
+-		fi
++		spares=$(tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0)
++		[ $spares -ne $2 ] &&
++			die "expected $2 spares, found $spares"
+ 		;;
+ 	raid* | linear )
+-		grep -s "active $1 " /proc/mdstat > /dev/null || {
+-			echo >&2 "ERROR active $1 not found"
+-			cat /proc/mdstat
+-			exit 1
+-		}
++		grep -sq "active $1 " /proc/mdstat ||
++			die "active $1 not found"
+ 		;;
+ 	algorithm )
+-		grep -s " algorithm $2 " /proc/mdstat > /dev/null || {
+-			echo >&2 "ERROR algorithm $2 not found"
+-			cat /proc/mdstat
+-			exit 1
+-		}
++		grep -sq " algorithm $2 " /proc/mdstat ||
++			die "algorithm $2 not found"
+ 		;;
+ 	resync | recovery | reshape )
+ 		cnt=5
+-		while ! grep -s $1 /proc/mdstat > /dev/null
++		while ! grep -sq $1 /proc/mdstat
+ 		do
+ 			if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null
+ 			then # Something isn't idle - wait a bit
+ 				sleep 0.5
+ 				cnt=$[cnt-1]
+ 			else
+-				echo >&2 ERROR no $1 happening
+-				cat /proc/mdstat
+-				exit 1
++				die "no $1 happening"
+ 			fi
+ 		done
+ 		;;
+@@ -234,22 +263,18 @@ check() {
+ 		# to do can still take a little longer than expected.
+ 		# add an extra check: is sync_completed shows the end is reached, assume
+ 		# there is no recovery.
+-		if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat
++		if grep -sq -E '(resync|recovery|reshape) *=' /proc/mdstat
+ 		then
+ 			incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'`
+-			if [ -n "$incomplete" ]
+-			then
+-				echo >&2 "ERROR resync or recovery is happening!"
+-				cat /proc/mdstat
+-				exit 1
+-			fi
++			[ -n "$incomplete" ] &&
++				die "resync or recovery is happening!"
+ 		fi
+ 		;;
+ 	wait )
+ 		p=`cat /proc/sys/dev/raid/speed_limit_max`
+ 		echo 2000000 > /proc/sys/dev/raid/speed_limit_max
+ 		sleep 0.1
+-		while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat ||
++		while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat ||
+ 			grep -v idle > /dev/null /sys/block/md*/md/sync_action
+ 		do
+ 			sleep 0.5
+@@ -257,45 +282,28 @@ check() {
+ 		echo $p > /proc/sys/dev/raid/speed_limit_max
+ 		;;
+ 	state )
+-		grep -s "blocks.*\[$2\]\$" /proc/mdstat > /dev/null || {
+-			echo >&2 "ERROR state $2 not found!"
+-			cat /proc/mdstat
+-			exit 1
+-		}
++		grep -sq "blocks.*\[$2\]\$" /proc/mdstat ||
++			die "state $2 not found!"
+ 		sleep 0.5
+ 		;;
+ 	bitmap )
+-		grep -s bitmap > /dev/null /proc/mdstat || {
+-			echo >&2 ERROR no bitmap
+-			cat /proc/mdstat
+-			exit 1
+-		}
++		grep -sq bitmap /proc/mdstat ||
++			die "no bitmap"
+ 		;;
+ 	nobitmap )
+-		if grep -s "bitmap" > /dev/null /proc/mdstat
+-		then
+-			echo >&2 ERROR bitmap present
+-			cat /proc/mdstat
+-			exit 1
+-		fi
++		grep -sq "bitmap" /proc/mdstat &&
++			die "bitmap present"
+ 		;;
+ 	readonly )
+-		grep -s "read-only" > /dev/null /proc/mdstat || {
+-			echo >&2 "ERROR array is not read-only!"
+-			cat /proc/mdstat
+-			exit 1
+-		}
++		grep -sq "read-only" /proc/mdstat ||
++			die "array is not read-only!"
+ 		;;
+ 	inactive )
+-		grep -s "inactive" > /dev/null /proc/mdstat || {
+-			echo >&2 "ERROR array is not inactive!"
+-			cat /proc/mdstat
+-			exit 1
+-		}
++		grep -sq "inactive" /proc/mdstat ||
++			die "array is not inactive!"
+ 		;;
+ 	* )
+-		echo >&2 ERROR unknown check $1
+-		exit 1
++		die "unknown check $1"
+ 		;;
+ 	esac
+ }
+@@ -311,6 +319,7 @@ no_errors() {
+ 
+ # basic device test
+ testdev() {
++	[ -b $1 ] || die "$1 isn't a block device."
+ 	udevadm settle
+ 	dev=$1
+ 	cnt=$2
+@@ -329,20 +338,11 @@ testdev() {
+ 		rasize=$[rasize/DEV_ROUND_K/2]
+ 		rasize=$[rasize*DEV_ROUND_K*2]
+ 	fi
+-	if [ `/sbin/blockdev --getsize $dev` -eq 0 ]
+-	then
+-		sleep 2
+-	fi
++	[ `/sbin/blockdev --getsize $dev` -eq 0 ] && sleep 2
+ 	_sz=`/sbin/blockdev --getsize $dev`
+-	if [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ]
+-	then
+-		echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz"
+-		exit 1
+-	fi
+-}
+-
+-fast_sync() {
+-	echo 200000 > /proc/sys/dev/raid/speed_limit_max
++	[ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ] &&
++		die "size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz"
++	return 0
+ }
+ 
+ rotest() {
+@@ -359,7 +359,6 @@ do_test() {
+ 		# stop all arrays, just incase some script left an array active.
+ 		$mdadm -Ssq 2> /dev/null
+ 		mdadm --zero $devlist 2> /dev/null
+-		mdadm --zero $devlist 2> /dev/null
+ 		# this might have been reset: restore the default.
+ 		echo 2000 > /proc/sys/dev/raid/speed_limit_max
+ 		# source script in a subshell, so it has access to our
+@@ -367,52 +366,44 @@ do_test() {
+ 		echo -ne "$_script... "
+ 		if ( set -ex ; . $_script ) &> $targetdir/log
+ 		then
++			dmesg | grep -iq "error\|call trace\|segfault" &&
++				die "dmesg prints errors when testing $_basename!"
+ 			echo "succeeded"
+ 			_fail=0
+ 		else
+-			log=log
+-			cat $targetdir/stderr >> $targetdir/log
+-			echo "=======================dmesg=================" >> $targetdir/log
+-			dmesg | tail -n 200 >> $targetdir/log
+-			if [ $exitonerror == 0 ]; then
+-				log=log-`basename $_script`
+-				mv $targetdir/log $logdir/$log
+-			fi
+-			echo "FAILED - see $logdir/$log for details"
++			save_log fail
+ 			_fail=1
+ 		fi
+-		if [ "$savelogs" == "1" ]
+-		then
+-			cp $targetdir/log $logdir/$_basename.log
+-		fi
+-		if [ "$_fail" == "1" -a "$exitonerror" == "1" ]
+-		then
+-			exit 1
+-		fi
++		[ "$savelogs" == "1" ] &&
++			mv -f $targetdir/log $logdir/$_basename.log
++		[ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1
+ 	fi
+ }
+ 
+ do_help() {
+-	echo "Usage: $0 [options]"
+-	echo " Options:"
+-	echo "    --tests=<test1,test2,..>    Comma separated list of tests to run"
+-	echo "    --disable-multipath         Disable any tests involving multipath"
+-	echo "    --disable-integrity         Disable slow tests of RAID[56] consistency"
+-	echo "    --logdir=<directory>        Directory to save logfiles in"
+-	echo "    --save-logs                 Save all logs in <logdir>"
+-	echo "    --keep-going                Don't stop on error, ie. run all tests"
+-	echo "    --dev=[loop|lvm|ram]        Use loop devices (default), LVM, or RAM disk"
+-	echo "    --volgroup=<name>           LVM volume group for LVM test"
+-	echo "    setup                       Setup test environment and exit"
+-	echo "    cleanup                     Cleanup test environment"
+-	echo "    <prefix>                    Run tests with <prefix>"
++	cat <<-EOF
++	Usage: $0 [options]
++	Options:
++		--tests=test1,test2,...     Comma separated list of tests to run
++		--disable-multipath         Disable any tests involving multipath
++		--disable-integrity         Disable slow tests of RAID[56] consistency
++		--logdir=directory          Directory to save all logfiles in
++		--save-logs                 Usually use with --logdir together
++		--keep-going | --no-error   Don't stop on error, ie. run all tests
++		--dev=loop|lvm|ram          Use loop devices (default), LVM, or RAM disk
++		--volgroup=name             LVM volume group for LVM test
++		setup                       Setup test environment and exit
++		cleanup                     Cleanup test environment
++		prefix                      Run tests with <prefix>
++		--help | -h                 Print this usage
++	EOF
+ }
+ 
+ parse_args() {
+ 	for i in $*
+ 	do
+ 		case $i in
+-		[0-9]* )
++		[0-9][0-9] )
+ 			prefix=$i
+ 			;;
+ 		setup )
+@@ -426,10 +417,10 @@ parse_args() {
+ 			exit 0
+ 			;;
+ 		--tests=* )
+-			TESTLIST=`expr "x$i" : 'x[^=]*=\(.*\)' | sed -e 's/,/ /g'`
++			TESTLIST=($(echo ${i##*=} | sed -e 's/,/ /g'))
+ 			;;
+ 		--logdir=* )
+-			logdir=`expr "x$i" : 'x[^=]*=\(.*\)'`
++			logdir="${i##*=}"
+ 			;;
+ 		--save-logs )
+ 			savelogs=1
+@@ -443,52 +434,109 @@ parse_args() {
+ 		--disable-integrity )
+ 			unset INTEGRITY
+ 			;;
+-		--dev=loop )
+-			DEVTYPE=loop
+-			;;
+-		--dev=lvm )
+-			DEVTYPE=lvm
+-			;;
+-		--dev=ram )
+-			DEVTYPE=ram
++		--dev=* )
++			case ${i##*=} in
++			loop )
++				DEVTYPE=loop
++				;;
++			lvm )
++				DEVTYPE=lvm
++				;;
++			ram )
++				DEVTYPE=ram
++				;;
++			* )
++				echo "Unknown argument: $i"
++				do_help
++				exit 1
++				;;
++			esac
+ 			;;
+ 		--volgroup=* )
+ 			LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'`
+ 			;;
+-		--help )
++		--help | -h )
+ 			do_help
+ 			exit 0
+ 			;;
+-		-* )
++		* )
+ 			echo " $0: Unknown argument: $i"
+ 			do_help
+-			exit 0
++			exit 1
+ 			;;
+ 		esac
+ 	done
+ }
+ 
+-logdir=$targetdir
+-parse_args $@
++check_env() {
++	user=$(id -un)
++	[ "X$user" != "Xroot" ] && {
++		echo "test: testing can only be done as 'root'."
++		exit 1
++	}
++	[ -x "raid6check" -a -x $mdadm ] || {
++		echo "test: please run 'make everything' before perform testing."
++		exit 1
++	}
++	cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck)
++	for cmd in ${cmds[@]}
++	do
++		which $cmd > /dev/null || {
++			echo "$cmd command not found!"
++			exit 1
++		}
++	done
++	mdadm_src_ver="$($mdadm -V 2>&1)"
++	mdadm_sbin_ver="$($(which mdadm) -V 2>&1)"
++	if [ "$mdadm_src_ver" != "$mdadm_sbin_ver" ]
++	then
++		# it's nessesary to 'make install' mdadm to /SBIN/DIR,
++		# such as systemd/mdadm-grow-continue@.service, would
++		# run as an instance by systemd when reshape happens,
++		# thus ensure that the correct mdadm is in testing.
++		echo "test: please run 'make install' before testing."
++		exit 1
++	fi
++	if ! $(df -T . | grep -iq ext)
++	then
++		# 'external file' bitmap only supports with ext[2-4] file system
++		echo "test: please run test suite with ext[2-4] file system."
++		exit 1
++	fi
++	if $(lsblk -a | grep -iq raid)
++	then
++		# donot run mdadm -Ss directly if there are RAIDs working.
++		echo "test: please run test suite without running RAIDs environment."
++		exit 1
++	fi
++	# Check whether to run multipath tests
++	modprobe multipath 2> /dev/null
++	grep -sq 'Personalities : .*multipath' /proc/mdstat &&
++		MULTIPATH="yes"
++}
+ 
+-do_setup
+-mkdir -p $logdir
++main() {
++	check_env
++	do_setup
+ 
+-if [ "$savelogs" == "1" ]
+-then
+-	echo "Saving logs to $logdir"
+-fi
++	echo "Testing on linux-$(uname -r) kernel"
++	[ "$savelogs" == "1" ] &&
++		echo "Saving logs to $logdir"
++	if [ "x$TESTLIST" != "x" ]
++	then
++		for script in ${TESTLIST[@]}
++		do
++			do_test $testdir/$script
++		done
++	else
++		for script in $testdir/$prefix $testdir/$prefix*[^~]
++		do
++			do_test $script
++		done
++	fi
+ 
+-if [ "x$TESTLIST" != "x" ]
+-then
+-	for script in $TESTLIST
+-	do
+-		do_test $testdir/$script
+-	done
+-else
+-	for script in $testdir/$prefix $testdir/$prefix*[^~]
+-	do
+-		do_test $script
+-	done
+-fi
+-exit 0
++	exit 0
++}
++
++parse_args $@
++main
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-util-unify-fstat-checking-blkdev1-into-function.patch b/SOURCES/mdadm-util-unify-fstat-checking-blkdev1-into-function.patch
new file mode 100644
index 0000000..cd66d54
--- /dev/null
+++ b/SOURCES/mdadm-util-unify-fstat-checking-blkdev1-into-function.patch
@@ -0,0 +1,439 @@
+From 0a6bff09d41650f27136d56a0604c9af46b6f583 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Thu, 4 May 2017 20:16:21 +0800
+Subject: [RHEL7.5 PATCH 109/169] mdadm/util: unify fstat checking blkdev
+ into function
+
+declare function fstat_is_blkdev() to integrate repeated fstat
+checking block device operations, it returns true/1 when it is
+a block device, and returns false/0 when it isn't.
+The fd and devname are necessary parameters, *rdev is optional,
+parse the pointer of dev_t *rdev, if valid, assigned the device
+number to dev_t *rdev, if NULL, ignores.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c    | 19 +++++++------------
+ Build.c       |  5 +++--
+ Create.c      | 23 ++++++++++-------------
+ Grow.c        | 10 ++++------
+ Incremental.c | 33 ++++++++++++---------------------
+ Manage.c      |  2 +-
+ bitmap.c      | 13 ++++---------
+ mdadm.h       |  1 +
+ super-intel.c | 13 +++----------
+ util.c        | 17 +++++++++++++++++
+ 10 files changed, 62 insertions(+), 74 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index a9442c8..9d0a89f 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -149,6 +149,7 @@ static int select_devices(struct mddev_dev *devlist,
+ 	struct mdinfo *content = NULL;
+ 	int report_mismatch = ((inargv && c->verbose >= 0) || c->verbose > 0);
+ 	struct domainlist *domains = NULL;
++	dev_t rdev;
+ 
+ 	tmpdev = devlist; num_devs = 0;
+ 	while (tmpdev) {
+@@ -169,7 +170,6 @@ static int select_devices(struct mddev_dev *devlist,
+ 	     tmpdev = tmpdev ? tmpdev->next : NULL) {
+ 		char *devname = tmpdev->devname;
+ 		int dfd;
+-		struct stat stb;
+ 		struct supertype *tst;
+ 		struct dev_policy *pol = NULL;
+ 		int found_container = 0;
+@@ -204,14 +204,7 @@ static int select_devices(struct mddev_dev *devlist,
+ 				pr_err("cannot open device %s: %s\n",
+ 				       devname, strerror(errno));
+ 			tmpdev->used = 2;
+-		} else if (fstat(dfd, &stb)< 0) {
+-			/* Impossible! */
+-			pr_err("fstat failed for %s: %s\n",
+-			       devname, strerror(errno));
+-			tmpdev->used = 2;
+-		} else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+-			pr_err("%s is not a block device.\n",
+-			       devname);
++		} else if (!fstat_is_blkdev(dfd, devname, &rdev)) {
+ 			tmpdev->used = 2;
+ 		} else if (must_be_container(dfd)) {
+ 			if (st) {
+@@ -234,7 +227,8 @@ static int select_devices(struct mddev_dev *devlist,
+ 					       devname);
+ 				tmpdev->used = 2;
+ 			} else if (auto_assem &&
+-				   !conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
++				   !conf_test_metadata(tst->ss->name,
++						       (pol = devid_policy(rdev)),
+ 						       tst->ss->match_home(tst, c->homehost) == 1)) {
+ 				if (report_mismatch)
+ 					pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
+@@ -261,7 +255,8 @@ static int select_devices(struct mddev_dev *devlist,
+ 					       tst->ss->name, devname);
+ 				tmpdev->used = 2;
+ 			} else if (auto_assem && st == NULL &&
+-				   !conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
++				   !conf_test_metadata(tst->ss->name,
++						       (pol = devid_policy(rdev)),
+ 						       tst->ss->match_home(tst, c->homehost) == 1)) {
+ 				if (report_mismatch)
+ 					pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
+@@ -484,7 +479,7 @@ static int select_devices(struct mddev_dev *devlist,
+ 		/* Collect domain information from members only */
+ 		if (tmpdev && tmpdev->used == 1) {
+ 			if (!pol)
+-				pol = devid_policy(stb.st_rdev);
++				pol = devid_policy(rdev);
+ 			domain_merge(&domains, pol, tst?tst->ss->name:NULL);
+ 		}
+ 		dev_policy_free(pol);
+diff --git a/Build.c b/Build.c
+index 665d906..2d84b96 100644
+--- a/Build.c
++++ b/Build.c
+@@ -42,6 +42,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	 */
+ 	int i;
+ 	struct stat stb;
++	dev_t rdev;
+ 	int subdevs = 0, missing_disks = 0;
+ 	struct mddev_dev *dv;
+ 	int bitmap_fd;
+@@ -126,8 +127,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	array.nr_disks = s->raiddisks;
+ 	array.raid_disks = s->raiddisks;
+ 	array.md_minor = 0;
+-	if (fstat(mdfd, &stb) == 0)
+-		array.md_minor = minor(stb.st_rdev);
++	if (fstat_is_blkdev(mdfd, mddev, &rdev))
++		array.md_minor = minor(rdev);
+ 	array.not_persistent = 1;
+ 	array.state = 0; /* not clean, but no errors */
+ 	if (s->assume_clean)
+diff --git a/Create.c b/Create.c
+index df1bc20..239545f 100644
+--- a/Create.c
++++ b/Create.c
+@@ -89,8 +89,8 @@ int Create(struct supertype *st, char *mddev,
+ 	char *maxdisc = NULL;
+ 	int dnum, raid_disk_num;
+ 	struct mddev_dev *dv;
++	dev_t rdev;
+ 	int fail = 0, warn = 0;
+-	struct stat stb;
+ 	int first_missing = subdevs * 2;
+ 	int second_missing = subdevs * 2;
+ 	int missing_disks = 0;
+@@ -325,11 +325,8 @@ int Create(struct supertype *st, char *mddev,
+ 				dname, strerror(errno));
+ 			exit(2);
+ 		}
+-		if (fstat(dfd, &stb) != 0 ||
+-		    (stb.st_mode & S_IFMT) != S_IFBLK) {
++		if (!fstat_is_blkdev(dfd, dname, NULL)) {
+ 			close(dfd);
+-			pr_err("%s is not a block device\n",
+-				dname);
+ 			exit(2);
+ 		}
+ 		close(dfd);
+@@ -641,8 +638,8 @@ int Create(struct supertype *st, char *mddev,
+ 	 * with, but it chooses to trust me instead. Sigh
+ 	 */
+ 	info.array.md_minor = 0;
+-	if (fstat(mdfd, &stb) == 0)
+-		info.array.md_minor = minor(stb.st_rdev);
++	if (fstat_is_blkdev(mdfd, mddev, &rdev))
++		info.array.md_minor = minor(rdev);
+ 	info.array.not_persistent = 0;
+ 
+ 	if (((s->level == 4 || s->level == 5) &&
+@@ -841,7 +838,6 @@ int Create(struct supertype *st, char *mddev,
+ 		for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
+ 		     dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
+ 			int fd;
+-			struct stat stb2;
+ 			struct mdinfo *inf = &infos[dnum];
+ 
+ 			if (dnum >= total_slots)
+@@ -897,9 +893,10 @@ int Create(struct supertype *st, char *mddev,
+ 							dv->devname);
+ 						goto abort_locked;
+ 					}
+-					fstat(fd, &stb2);
+-					inf->disk.major = major(stb2.st_rdev);
+-					inf->disk.minor = minor(stb2.st_rdev);
++					if (!fstat_is_blkdev(fd, dv->devname, &rdev))
++						return 1;
++					inf->disk.major = major(rdev);
++					inf->disk.minor = minor(rdev);
+ 				}
+ 				if (fd >= 0)
+ 					remove_partitions(fd);
+@@ -920,8 +917,8 @@ int Create(struct supertype *st, char *mddev,
+ 
+ 				if (!have_container) {
+ 					/* getinfo_super might have lost these ... */
+-					inf->disk.major = major(stb2.st_rdev);
+-					inf->disk.minor = minor(stb2.st_rdev);
++					inf->disk.major = major(rdev);
++					inf->disk.minor = minor(rdev);
+ 				}
+ 				break;
+ 			case 2:
+diff --git a/Grow.c b/Grow.c
+index f4bd301..a527436 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -109,7 +109,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 	 */
+ 	struct mdinfo info;
+ 
+-	struct stat stb;
++	dev_t rdev;
+ 	int nfd, fd2;
+ 	int d, nd;
+ 	struct supertype *st = NULL;
+@@ -145,9 +145,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 		free(st);
+ 		return 1;
+ 	}
+-	fstat(nfd, &stb);
+-	if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+-		pr_err("%s is not a block device!\n", newdev);
++	if (!fstat_is_blkdev(nfd, newdev, &rdev)) {
+ 		close(nfd);
+ 		free(st);
+ 		return 1;
+@@ -198,8 +196,8 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 	 */
+ 
+ 	info.disk.number = d;
+-	info.disk.major = major(stb.st_rdev);
+-	info.disk.minor = minor(stb.st_rdev);
++	info.disk.major = major(rdev);
++	info.disk.minor = minor(rdev);
+ 	info.disk.raid_disk = d;
+ 	info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
+ 	st->ss->update_super(st, &info, "linear-grow-new", newdev,
+diff --git a/Incremental.c b/Incremental.c
+index 8909f2f..11a34e7 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -87,6 +87,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	 *   start the array (auto-readonly).
+ 	 */
+ 	struct stat stb;
++	dev_t rdev;
+ 	struct mdinfo info, dinfo;
+ 	struct mdinfo *sra = NULL, *d;
+ 	struct mddev_ident *match;
+@@ -174,21 +175,11 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	/* 2/ Find metadata, reject if none appropriate (check
+ 	 *            version/name from args) */
+ 
+-	if (fstat(dfd, &stb) < 0) {
+-		if (c->verbose >= 0)
+-			pr_err("fstat failed for %s: %s.\n",
+-				devname, strerror(errno));
+-		goto out;
+-	}
+-	if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+-		if (c->verbose >= 0)
+-			pr_err("%s is not a block device.\n",
+-				devname);
++	if (!fstat_is_blkdev(dfd, devname, &rdev))
+ 		goto out;
+-	}
+ 
+-	dinfo.disk.major = major(stb.st_rdev);
+-	dinfo.disk.minor = minor(stb.st_rdev);
++	dinfo.disk.major = major(rdev);
++	dinfo.disk.minor = minor(rdev);
+ 
+ 	policy = disk_policy(&dinfo);
+ 	have_target = policy_check_path(&dinfo, &target_array);
+@@ -339,8 +330,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		}
+ 
+ 		dinfo = info;
+-		dinfo.disk.major = major(stb.st_rdev);
+-		dinfo.disk.minor = minor(stb.st_rdev);
++		dinfo.disk.major = major(rdev);
++		dinfo.disk.minor = minor(rdev);
+ 		if (add_disk(mdfd, st, &info, &dinfo) != 0) {
+ 			pr_err("failed to add %s to new array %s: %s.\n",
+ 				devname, chosen_name, strerror(errno));
+@@ -441,8 +432,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 				goto out_unlock;
+ 			}
+ 		}
+-		info.disk.major = major(stb.st_rdev);
+-		info.disk.minor = minor(stb.st_rdev);
++		info.disk.major = major(rdev);
++		info.disk.minor = minor(rdev);
+ 		/* add disk needs to know about containers */
+ 		if (st->ss->external)
+ 			sra->array.level = LEVEL_CONTAINER;
+@@ -863,12 +854,12 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 	 * Return 0 on success, or some exit code on failure, probably 1.
+ 	 */
+ 	int rv = 1;
+-	struct stat stb;
++	dev_t rdev;
+ 	struct map_ent *mp, *map = NULL;
+ 	struct mdinfo *chosen = NULL;
+ 	int dfd = *dfdp;
+ 
+-	if (fstat(dfd, &stb) != 0)
++	if (!fstat_is_blkdev(dfd, devname, &rdev))
+ 		return 1;
+ 
+ 	/*
+@@ -1038,8 +1029,8 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
+ 			devlist.writemostly = FlagDefault;
+ 			devlist.failfast = FlagDefault;
+ 			devlist.devname = chosen_devname;
+-			sprintf(chosen_devname, "%d:%d", major(stb.st_rdev),
+-				minor(stb.st_rdev));
++			sprintf(chosen_devname, "%d:%d", major(rdev),
++				minor(rdev));
+ 			devlist.disposition = 'a';
+ 			close(dfd);
+ 			*dfdp = -1;
+diff --git a/Manage.c b/Manage.c
+index 230309b..af55266 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1513,7 +1513,7 @@ int Manage_subdevs(char *devname, int fd,
+ 			struct stat stb;
+ 			tfd = dev_open(dv->devname, O_RDONLY);
+ 			if (tfd >= 0) {
+-				fstat(tfd, &stb);
++				fstat_is_blkdev(tfd, dv->devname, &rdev);
+ 				close(tfd);
+ 			} else {
+ 				int open_err = errno;
+diff --git a/bitmap.c b/bitmap.c
+index 16a6b73..3653660 100644
+--- a/bitmap.c
++++ b/bitmap.c
+@@ -183,7 +183,6 @@ static int
+ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
+ {
+ 	int fd;
+-	struct stat stb;
+ 	struct supertype *st = *stp;
+ 
+ 	fd = open(filename, O_RDONLY|O_DIRECT);
+@@ -193,14 +192,7 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
+ 		return -1;
+ 	}
+ 
+-	if (fstat(fd, &stb) < 0) {
+-		pr_err("failed to determine bitmap file/device type: %s\n",
+-			strerror(errno));
+-		close(fd);
+-		return -1;
+-	}
+-
+-	if ((stb.st_mode & S_IFMT) == S_IFBLK) {
++	if (fstat_is_blkdev(fd, filename, NULL)) {
+ 		/* block device, so we are probably after an internal bitmap */
+ 		if (!st)
+ 			st = guess_super(fd);
+@@ -221,6 +213,9 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num)
+ 		}
+ 
+ 		*stp = st;
++	} else {
++		close(fd);
++		return -1;
+ 	}
+ 
+ 	return fd;
+diff --git a/mdadm.h b/mdadm.h
+index 07ee963..4adb840 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1434,6 +1434,7 @@ extern int check_raid(int fd, char *name);
+ extern int check_partitions(int fd, char *dname,
+ 			    unsigned long long freesize,
+ 			    unsigned long long size);
++extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev);
+ 
+ extern int get_mdp_major(void);
+ extern int get_maj_min(char *dev, int *major, int *minor);
+diff --git a/super-intel.c b/super-intel.c
+index 36f77d3..c4196ea 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6562,7 +6562,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
+ 
+ 	for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
+ 		char *devname = tmpdev->devname;
+-		struct stat stb;
++		dev_t rdev;
+ 		struct supertype *tst;
+ 		int dfd;
+ 		if (tmpdev->used > 1)
+@@ -6578,14 +6578,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
+ 			dprintf("cannot open device %s: %s\n",
+ 				devname, strerror(errno));
+ 			tmpdev->used = 2;
+-		} else if (fstat(dfd, &stb)< 0) {
+-			/* Impossible! */
+-			dprintf("fstat failed for %s: %s\n",
+-				devname, strerror(errno));
+-			tmpdev->used = 2;
+-		} else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+-			dprintf("%s is not a block device.\n",
+-				devname);
++		} else if (!fstat_is_blkdev(dfd, devname, &rdev)) {
+ 			tmpdev->used = 2;
+ 		} else if (must_be_container(dfd)) {
+ 			struct supertype *cst;
+@@ -6607,7 +6600,7 @@ count_volumes_list(struct md_list *devlist, char *homehost,
+ 			if (cst)
+ 				cst->ss->free_super(cst);
+ 		} else {
+-			tmpdev->st_rdev = stb.st_rdev;
++			tmpdev->st_rdev = rdev;
+ 			if (tst->ss->load_super(tst,dfd, NULL)) {
+ 				dprintf("no RAID superblock on %s\n",
+ 					devname);
+diff --git a/util.c b/util.c
+index c7585ac..a92faf8 100644
+--- a/util.c
++++ b/util.c
+@@ -730,6 +730,23 @@ int check_raid(int fd, char *name)
+ 	return 1;
+ }
+ 
++int fstat_is_blkdev(int fd, char *devname, dev_t *rdev)
++{
++	struct stat stb;
++
++	if (fstat(fd, &stb) != 0) {
++		pr_err("fstat failed for %s: %s\n", devname, strerror(errno));
++		return 0;
++	}
++	if ((S_IFMT & stb.st_mode) != S_IFBLK) {
++		pr_err("%s is not a block device.\n", devname);
++		return 0;
++	}
++	if (rdev)
++		*rdev = stb.st_rdev;
++	return 1;
++}
++
+ int ask(char *mesg)
+ {
+ 	char *add = "";
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm-util-unify-stat-checking-blkdev-into-function.patch b/SOURCES/mdadm-util-unify-stat-checking-blkdev-into-function.patch
new file mode 100644
index 0000000..b671e28
--- /dev/null
+++ b/SOURCES/mdadm-util-unify-stat-checking-blkdev-into-function.patch
@@ -0,0 +1,335 @@
+From 9e04ac1c43e63eccb68eb196174069e5c23d0270 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Fri, 5 May 2017 11:09:41 +0800
+Subject: [RHEL7.5 PATCH 110/169] mdadm/util: unify stat checking blkdev
+ into function
+
+declare function stat_is_blkdev() to integrate repeated stat
+checking blkdev operations, it returns 'true/1' when it is a
+block device, and returns 'false/0' when it isn't.
+The devname is necessary parameter, *rdev is optional, parse
+the pointer of dev_t *rdev, if valid, assigned device number
+to dev_t *rdev, if NULL, ignores.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Assemble.c    |  7 ++-----
+ Build.c       | 25 ++++---------------------
+ Incremental.c | 21 ++++-----------------
+ Manage.c      | 11 +----------
+ Monitor.c     | 16 ++++------------
+ mdadm.h       |  1 +
+ super-ddf.c   | 10 ++++------
+ super-intel.c | 10 ++++------
+ util.c        | 17 +++++++++++++++++
+ 9 files changed, 41 insertions(+), 77 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 9d0a89f..30d5838 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -512,15 +512,12 @@ static int select_devices(struct mddev_dev *devlist,
+ 
+ 	/* Now reject spares that don't match domains of identified members */
+ 	for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
+-		struct stat stb;
+ 		if (tmpdev->used != 3)
+ 			continue;
+-		if (stat(tmpdev->devname, &stb)< 0) {
+-			pr_err("fstat failed for %s: %s\n",
+-			       tmpdev->devname, strerror(errno));
++		if (!stat_is_blkdev(tmpdev->devname, &rdev)) {
+ 			tmpdev->used = 2;
+ 		} else {
+-			struct dev_policy *pol = devid_policy(stb.st_rdev);
++			struct dev_policy *pol = devid_policy(rdev);
+ 			int dt = domain_test(domains, pol, NULL);
+ 			if (inargv && dt != 0)
+ 				/* take this spare as domains match
+diff --git a/Build.c b/Build.c
+index 2d84b96..ad59867 100644
+--- a/Build.c
++++ b/Build.c
+@@ -41,7 +41,6 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 	 * cc = chunk size factor: 0==4k, 1==8k etc.
+ 	 */
+ 	int i;
+-	struct stat stb;
+ 	dev_t rdev;
+ 	int subdevs = 0, missing_disks = 0;
+ 	struct mddev_dev *dv;
+@@ -65,16 +64,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 			missing_disks++;
+ 			continue;
+ 		}
+-		if (stat(dv->devname, &stb)) {
+-			pr_err("Cannot find %s: %s\n",
+-				dv->devname, strerror(errno));
+-			return 1;
+-		}
+-		if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+-			pr_err("%s is not a block device.\n",
+-				dv->devname);
++		if (!stat_is_blkdev(dv->devname, NULL))
+ 			return 1;
+-		}
+ 	}
+ 
+ 	if (s->raiddisks != subdevs) {
+@@ -162,16 +153,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 
+ 		if (strcmp("missing", dv->devname) == 0)
+ 			continue;
+-		if (stat(dv->devname, &stb)) {
+-			pr_err("Weird: %s has disappeared.\n",
+-				dv->devname);
++		if (!stat_is_blkdev(dv->devname, &rdev))
+ 			goto abort;
+-		}
+-		if ((stb.st_mode & S_IFMT)!= S_IFBLK) {
+-			pr_err("Weird: %s is no longer a block device.\n",
+-				dv->devname);
+-			goto abort;
+-		}
+ 		fd = open(dv->devname, O_RDONLY|O_EXCL);
+ 		if (fd < 0) {
+ 			pr_err("Cannot open %s: %s\n",
+@@ -187,8 +170,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 		disk.state = (1<<MD_DISK_SYNC) | (1<<MD_DISK_ACTIVE);
+ 		if (dv->writemostly == FlagSet)
+ 			disk.state |= 1<<MD_DISK_WRITEMOSTLY;
+-		disk.major = major(stb.st_rdev);
+-		disk.minor = minor(stb.st_rdev);
++		disk.major = major(rdev);
++		disk.minor = minor(rdev);
+ 		if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
+ 			pr_err("ADD_NEW_DISK failed for %s: %s\n",
+ 			       dv->devname, strerror(errno));
+diff --git a/Incremental.c b/Incremental.c
+index 11a34e7..97b2e99 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -86,8 +86,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	 * - if number of OK devices match expected, or -R and there are enough,
+ 	 *   start the array (auto-readonly).
+ 	 */
+-	struct stat stb;
+-	dev_t rdev;
++	dev_t rdev, rdev2;
+ 	struct mdinfo info, dinfo;
+ 	struct mdinfo *sra = NULL, *d;
+ 	struct mddev_ident *match;
+@@ -108,18 +107,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 
+ 	struct createinfo *ci = conf_get_create_info();
+ 
+-	if (stat(devname, &stb) < 0) {
+-		if (c->verbose >= 0)
+-			pr_err("stat failed for %s: %s.\n",
+-				devname, strerror(errno));
+-		return rv;
+-	}
+-	if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+-		if (c->verbose >= 0)
+-			pr_err("%s is not a block device.\n",
+-				devname);
++	if (!stat_is_blkdev(devname, &rdev))
+ 		return rv;
+-	}
+ 	dfd = dev_open(devname, O_RDONLY);
+ 	if (dfd < 0) {
+ 		if (c->verbose >= 0)
+@@ -158,10 +147,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	if (!devlist) {
+ 		devlist = conf_get_devs();
+ 		for (;devlist; devlist = devlist->next) {
+-			struct stat st2;
+-			if (stat(devlist->devname, &st2) == 0 &&
+-			    (st2.st_mode & S_IFMT) == S_IFBLK &&
+-			    st2.st_rdev == stb.st_rdev)
++			if (stat_is_blkdev(devlist->devname, &rdev2) &&
++			    rdev2 == rdev)
+ 				break;
+ 		}
+ 	}
+diff --git a/Manage.c b/Manage.c
+index af55266..14276b7 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1510,24 +1510,16 @@ int Manage_subdevs(char *devname, int fd,
+ 			 */
+ 			rdev = makedev(mj, mn);
+ 		} else {
+-			struct stat stb;
+ 			tfd = dev_open(dv->devname, O_RDONLY);
+ 			if (tfd >= 0) {
+ 				fstat_is_blkdev(tfd, dv->devname, &rdev);
+ 				close(tfd);
+ 			} else {
+ 				int open_err = errno;
+-				if (stat(dv->devname, &stb) != 0) {
+-					pr_err("Cannot find %s: %s\n",
+-					       dv->devname, strerror(errno));
+-					goto abort;
+-				}
+-				if ((stb.st_mode & S_IFMT) != S_IFBLK) {
++				if (!stat_is_blkdev(dv->devname, &rdev)) {
+ 					if (dv->disposition == 'M')
+ 						/* non-fatal. Also improbable */
+ 						continue;
+-					pr_err("%s is not a block device.\n",
+-					       dv->devname);
+ 					goto abort;
+ 				}
+ 				if (dv->disposition == 'r')
+@@ -1544,7 +1536,6 @@ int Manage_subdevs(char *devname, int fd,
+ 					goto abort;
+ 				}
+ 			}
+-			rdev = stb.st_rdev;
+ 		}
+ 		switch(dv->disposition){
+ 		default:
+diff --git a/Monitor.c b/Monitor.c
+index 1f15377..e2b36ff 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -993,23 +993,13 @@ static void link_containers_with_subarrays(struct state *list)
+ /* Not really Monitor but ... */
+ int Wait(char *dev)
+ {
+-	struct stat stb;
+ 	char devnm[32];
+-	char *tmp;
+ 	int rv = 1;
+ 	int frozen_remaining = 3;
+ 
+-	if (stat(dev, &stb) != 0) {
+-		pr_err("Cannot find %s: %s\n", dev,
+-			strerror(errno));
++	if (!stat_is_blkdev(dev, NULL))
+ 		return 2;
+-	}
+-	tmp = stat2devnm(&stb);
+-	if (!tmp) {
+-		pr_err("%s is not a block device.\n", dev);
+-		return 2;
+-	}
+-	strcpy(devnm, tmp);
++	strcpy(devnm, dev);
+ 
+ 	while(1) {
+ 		struct mdstat_ent *ms = mdstat_read(1, 0);
+@@ -1068,6 +1058,8 @@ int WaitClean(char *dev, int sock, int verbose)
+ 	int rv = 1;
+ 	char devnm[32];
+ 
++	if (!stat_is_blkdev(dev, NULL))
++		return 2;
+ 	fd = open(dev, O_RDONLY);
+ 	if (fd < 0) {
+ 		if (verbose)
+diff --git a/mdadm.h b/mdadm.h
+index 4adb840..a92feb2 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1435,6 +1435,7 @@ extern int check_partitions(int fd, char *dname,
+ 			    unsigned long long freesize,
+ 			    unsigned long long size);
+ extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev);
++extern int stat_is_blkdev(char *devname, dev_t *rdev);
+ 
+ extern int get_mdp_major(void);
+ extern int get_maj_min(char *dev, int *major, int *minor);
+diff --git a/super-ddf.c b/super-ddf.c
+index 796eaa5..9c82f4f 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -3490,7 +3490,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
+ 				     char *dev, unsigned long long *freesize,
+ 				     int verbose)
+ {
+-	struct stat stb;
++	dev_t rdev;
+ 	struct ddf_super *ddf = st->sb;
+ 	struct dl *dl;
+ 	unsigned long long maxsize;
+@@ -3526,13 +3526,11 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
+ 		return 1;
+ 	}
+ 	/* This device must be a member of the set */
+-	if (stat(dev, &stb) < 0)
+-		return 0;
+-	if ((S_IFMT & stb.st_mode) != S_IFBLK)
++	if (!stat_is_blkdev(dev, NULL))
+ 		return 0;
+ 	for (dl = ddf->dlist ; dl ; dl = dl->next) {
+-		if (dl->major == (int)major(stb.st_rdev) &&
+-		    dl->minor == (int)minor(stb.st_rdev))
++		if (dl->major == (int)major(rdev) &&
++		    dl->minor == (int)minor(rdev))
+ 			break;
+ 	}
+ 	if (!dl) {
+diff --git a/super-intel.c b/super-intel.c
+index c4196ea..e13c940 100644
+--- a/super-intel.c
++++ b/super-intel.c
+@@ -6855,7 +6855,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
+ 					 unsigned long long *freesize,
+ 					 int verbose)
+ {
+-	struct stat stb;
++	dev_t rdev;
+ 	struct intel_super *super = st->sb;
+ 	struct imsm_super *mpb;
+ 	struct dl *dl;
+@@ -6920,13 +6920,11 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
+ 	}
+ 
+ 	/* This device must be a member of the set */
+-	if (stat(dev, &stb) < 0)
+-		return 0;
+-	if ((S_IFMT & stb.st_mode) != S_IFBLK)
++	if (!stat_is_blkdev(dev, &rdev))
+ 		return 0;
+ 	for (dl = super->disks ; dl ; dl = dl->next) {
+-		if (dl->major == (int)major(stb.st_rdev) &&
+-		    dl->minor == (int)minor(stb.st_rdev))
++		if (dl->major == (int)major(rdev) &&
++		    dl->minor == (int)minor(rdev))
+ 			break;
+ 	}
+ 	if (!dl) {
+diff --git a/util.c b/util.c
+index a92faf8..11ff2cc 100644
+--- a/util.c
++++ b/util.c
+@@ -747,6 +747,23 @@ int fstat_is_blkdev(int fd, char *devname, dev_t *rdev)
+ 	return 1;
+ }
+ 
++int stat_is_blkdev(char *devname, dev_t *rdev)
++{
++	struct stat stb;
++
++	if (stat(devname, &stb) != 0) {
++		pr_err("stat failed for %s: %s\n", devname, strerror(errno));
++		return 0;
++	}
++	if ((S_IFMT & stb.st_mode) != S_IFBLK) {
++		pr_err("%s is not a block device.\n", devname);
++		return 0;
++	}
++	if (rdev)
++		*rdev = stb.st_rdev;
++	return 1;
++}
++
+ int ask(char *mesg)
+ {
+ 	char *add = "";
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm.c-fix-compile-error-switch-condition-has-boole.patch b/SOURCES/mdadm.c-fix-compile-error-switch-condition-has-boole.patch
new file mode 100644
index 0000000..4ee6d76
--- /dev/null
+++ b/SOURCES/mdadm.c-fix-compile-error-switch-condition-has-boole.patch
@@ -0,0 +1,44 @@
+From 13428e2e76e8149336282d514908ced424f878a2 Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@profitbricks.com>
+Date: Thu, 30 Mar 2017 18:58:13 +0200
+Subject: [RHEL7.5 PATCH 046/169] mdadm.c: fix compile error "switch
+ condition has boolean value"
+
+Remove a boolean expression in switch condition
+to prevent compile error of some compilers,
+for example, gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2).
+
+Signed-off-by: Gioh Kim <gi-oh.kim@profitbricks.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 0f32773..d6b5437 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1965,14 +1965,12 @@ static int misc_list(struct mddev_dev *devlist,
+ 			rv |= SetAction(dv->devname, c->action);
+ 			continue;
+ 		}
+-		switch(dv->devname[0] == '/') {
+-			case 0:
+-				mdfd = open_dev(dv->devname);
+-				if (mdfd >= 0)
+-					break;
+-			case 1:
+-				mdfd = open_mddev(dv->devname, 1);  
+-		}
++
++		if (dv->devname[0] != '/')
++			mdfd = open_dev(dv->devname);
++		if (dv->devname[0] == '/' || mdfd < 0)
++			mdfd = open_mddev(dv->devname, 1);
++
+ 		if (mdfd >= 0) {
+ 			switch(dv->disposition) {
+ 			case 'R':
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch b/SOURCES/mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch
new file mode 100644
index 0000000..4c73450
--- /dev/null
+++ b/SOURCES/mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch
@@ -0,0 +1,32 @@
+From 5fbc1f1527ec86ae904739a27c0af4e3bc89084e Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Mon, 10 Apr 2017 12:49:52 +0800
+Subject: [RHEL7.5 PATCH 068/169] mdadm.c:fix compile warning "mdfd is
+ uninitialized"
+
+Initialized the mdfd as -1 to prevent compile error
+of some compilers.
+For example, gcc version 4.8.5(SUSE Linux).
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mdadm.c b/mdadm.c
+index 001ff68..41dae1d 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1916,7 +1916,7 @@ static int misc_list(struct mddev_dev *devlist,
+ 	int rv = 0;
+ 
+ 	for (dv = devlist; dv; dv = (rv & 16) ? NULL : dv->next) {
+-		int mdfd;
++		int mdfd = -1;
+ 
+ 		switch(dv->disposition) {
+ 		case 'D':
+-- 
+2.7.4
+
diff --git a/SOURCES/mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch b/SOURCES/mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch
new file mode 100644
index 0000000..44d8ab2
--- /dev/null
+++ b/SOURCES/mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch
@@ -0,0 +1,31 @@
+From a86b1c8d15dc0aca2eda5276bae088b5f55030a2 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 11:37:27 -0400
+Subject: [RHEL7.5 PATCH 031/169] mdadm.h: struct mdinfo: reorganize ppl
+ elements for better struct packing
+
+Minor optimization putting ints next to ints for better data
+alignment.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index 4891acf..dbf1f92 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -301,8 +301,8 @@ struct mdinfo {
+ 	};
+ 	long			bitmap_offset;	/* 0 == none, 1 == a file */
+ 	unsigned int		ppl_size;
+-	unsigned long long	ppl_sector;
+ 	int			ppl_offset;
++	unsigned long long	ppl_sector;
+ 	unsigned long		safe_mode_delay; /* ms delay to mark clean */
+ 	int			new_level, delta_disks, new_layout, new_chunk;
+ 	int			errors;
+-- 
+2.7.4
+
diff --git a/SOURCES/mdassemble-Kill-off-the-last-remains.patch b/SOURCES/mdassemble-Kill-off-the-last-remains.patch
new file mode 100644
index 0000000..2abe1c3
--- /dev/null
+++ b/SOURCES/mdassemble-Kill-off-the-last-remains.patch
@@ -0,0 +1,108 @@
+From 935795398d52a589598fa13e6cb6272619c5d134 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 4 May 2017 11:57:41 -0400
+Subject: [RHEL7.5 PATCH 108/169] mdassemble: Kill off the last remains
+
+Having gotten rid of mdassemble, lets get rid of the man page too
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ README.initramfs |  9 ++++----
+ mdassemble.8     | 65 --------------------------------------------------------
+ 2 files changed, 4 insertions(+), 70 deletions(-)
+ delete mode 100644 mdassemble.8
+
+diff --git a/README.initramfs b/README.initramfs
+index 8f9b8dd..c5fa668 100644
+--- a/README.initramfs
++++ b/README.initramfs
+@@ -16,11 +16,10 @@ devices.
+ 
+ These mechanisms, while useful, do not provide complete functionality
+ and are unlikely to be extended.  The preferred way to assemble md
+-arrays at boot time is using 'mdadm' or 'mdassemble' (which is a
+-trimmed-down mdadm).  To assemble an array which contains the root
+-filesystem, mdadm needs to be run before that filesystem is mounted,
+-and so needs to be run from an initial-ram-fs.  It is how this can
+-work that is the primary focus of this document.
++arrays at boot time is using 'mdadm'.  To assemble an array which
++contains the root filesystem, mdadm needs to be run before that
++filesystem is mounted, and so needs to be run from an initial-ram-fs.
++It is how this can work that is the primary focus of this document.
+ 
+ It should be noted up front that only the array containing the root
+ filesystem should be assembled from the initramfs.  Any other arrays
+diff --git a/mdassemble.8 b/mdassemble.8
+deleted file mode 100644
+index 33aa977..0000000
+--- a/mdassemble.8
++++ /dev/null
+@@ -1,65 +0,0 @@
+-.\" -*- nroff -*-
+-.TH MDASSEMBLE 8 "" v4.0
+-.SH NAME
+-mdassemble \- assemble MD devices
+-.I aka
+-Linux Software RAID
+-
+-.SH SYNOPSIS
+-
+-.BI mdassemble
+-
+-.SH DESCRIPTION
+-.B mdassemble
+-is a tiny program that can be used to assemble MD devices inside an
+-initial ramdisk (initrd) or initramfs; it is meant to replace the in-kernel
+-automatic RAID detection and activation.
+-It can be built statically and linked against lightweight libc alternatives, like
+-.B dietlibc,
+-.B klibc
+-or
+-.B uClibc.
+-
+-.SH USAGE
+-Invoking
+-.B mdassemble
+-has the same effect as invoking
+-.B mdadm \-\-assemble \-\-scan.
+-.PP
+-Invoking
+-.B mdassemble
+-a second time will make all defined arrays readwrite, this is useful if
+-using the
+-.B start_ro
+-module parameter.
+-
+-.SH OPTIONS
+-
+-There are no options to
+-.B mdassemble.
+-
+-.SH FILES
+-
+-.SS /etc/mdadm.conf
+-
+-The config file lists which devices may be scanned to see if
+-they contain MD super block, and gives identifying information
+-(e.g. UUID) about known MD arrays.  See
+-.BR mdadm.conf (5)
+-for more details.
+-
+-.B mdassemble
+-supports all configuration parameters defined in
+-.B mdadm.conf
+-with the exception of
+-.B auto=
+-which is supported only if mdadm was built with the
+-.B \-DMDASSEMBLE_AUTO
+-define.
+-
+-.SH SEE ALSO
+-.PP
+-.BR mdadm (8),
+-.BR mdadm.conf (5),
+-.BR md (4),
+-.BR diet (1).
+-- 
+2.7.4
+
diff --git a/SOURCES/mdassemble-Use-md_get_array_info-to-check-for-valid-.patch b/SOURCES/mdassemble-Use-md_get_array_info-to-check-for-valid-.patch
new file mode 100644
index 0000000..899ad8a
--- /dev/null
+++ b/SOURCES/mdassemble-Use-md_get_array_info-to-check-for-valid-.patch
@@ -0,0 +1,38 @@
+From 1c9591115d577841522acd245cd2445cb77ee204 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:46:35 -0400
+Subject: [RHEL7.5 PATCH 064/169] mdassemble: Use md_get_array_info() to
+ check for valid array
+
+Get rid of another use of md_get_version()
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdassemble.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/mdassemble.c b/mdassemble.c
+index a24b324..f0833bc 100644
+--- a/mdassemble.c
++++ b/mdassemble.c
+@@ -32,13 +32,12 @@ char const Name[] = "mdassemble";
+ /* from mdopen.c */
+ int open_mddev(char *dev, int report_errors/*unused*/)
+ {
++	struct mdu_array_info_s array;
+ 	int mdfd = open(dev, O_RDONLY);
+ 	if (mdfd < 0)
+-		pr_err("error opening %s: %s\n",
+-			dev, strerror(errno));
+-	else if (md_get_version(mdfd) <= 0) {
+-		pr_err("%s does not appear to be an md device\n",
+-			dev);
++		pr_err("error opening %s: %s\n", dev, strerror(errno));
++	else if (md_get_array_info(mdfd, &array) != 0) {
++		pr_err("%s does not appear to be an md device\n", dev);
+ 		close(mdfd);
+ 		mdfd = -1;
+ 	}
+-- 
+2.7.4
+
diff --git a/SOURCES/mdmon-Stop-bothering-about-md-get-version2.patch b/SOURCES/mdmon-Stop-bothering-about-md-get-version2.patch
new file mode 100644
index 0000000..4679992
--- /dev/null
+++ b/SOURCES/mdmon-Stop-bothering-about-md-get-version2.patch
@@ -0,0 +1,32 @@
+From 15d924d363a2bc02aa4a489241333be3d7820978 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:39:51 -0400
+Subject: [RHEL7.5 PATCH 062/169] mdmon: Stop bothering about
+ md_get_version()
+
+If anyone has a kernel with md driver older than 0.90.03 they will
+also know where to find older versions of mdadm.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdmon.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/mdmon.c b/mdmon.c
+index 95e9bba..0955fcc 100644
+--- a/mdmon.c
++++ b/mdmon.c
+@@ -408,10 +408,6 @@ static int mdmon(char *devnm, int must_fork, int takeover)
+ 		pr_err("%s: %s\n", devnm, strerror(errno));
+ 		return 1;
+ 	}
+-	if (md_get_version(mdfd) < 0) {
+-		pr_err("%s: Not an md device\n", devnm);
+-		return 1;
+-	}
+ 
+ 	/* Fork, and have the child tell us when they are ready */
+ 	if (must_fork) {
+-- 
+2.7.4
+
diff --git a/SOURCES/mdmon-get-safe-mode-delay-file.patch b/SOURCES/mdmon-get-safe-mode-delay-file.patch
new file mode 100644
index 0000000..9332ec8
--- /dev/null
+++ b/SOURCES/mdmon-get-safe-mode-delay-file.patch
@@ -0,0 +1,74 @@
+commit c76242c56efb4d799bb15af1035a5f503cb4b8f3
+Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date:   Wed Oct 4 10:18:21 2017 +0200
+
+    mdmon: get safe mode delay file descriptor early
+    
+    After switch root new mdmon is started. It sends initrd mdmon a signal
+    to terminate. initrd mdmon receives it and switches the safe mode delay
+    to 1 ms in order to get array to clean state and flush last version of
+    metadata. The problem is sysfs filesystem is not available to initrd mdmon
+    after switch root so the original safe mode delay is unchanged. The delay
+    is set to few seconds - if there is a lot of traffic on the filesystem,
+    initrd mdmon doesn't terminate for a long time (no clean state). There
+    are 2 instances of mdmon. initrd mdmon flushes metadata when array goes
+    to clean state but this metadata might be already outdated.
+    
+    Use file descriptor obtained on mdmon start to change safe mode delay.
+    
+    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/managemon.c b/managemon.c
+index cc3c6f1..4e85398 100644
+--- a/managemon.c
++++ b/managemon.c
+@@ -129,6 +129,8 @@ static void close_aa(struct active_array *aa)
+ 		close(aa->metadata_fd);
+ 	if (aa->sync_completed_fd >= 0)
+ 		close(aa->sync_completed_fd);
++	if (aa->safe_mode_delay_fd >= 0)
++		close(aa->safe_mode_delay_fd);
+ }
+ 
+ static void free_aa(struct active_array *aa)
+@@ -532,9 +534,15 @@ static void manage_member(struct mdstat_ent *mdstat,
+ 	if (a->container == NULL)
+ 		return;
+ 
+-	if (sigterm && a->info.safe_mode_delay != 1) {
+-		sysfs_set_safemode(&a->info, 1);
+-		a->info.safe_mode_delay = 1;
++	if (sigterm && a->info.safe_mode_delay != 1 &&
++	    a->safe_mode_delay_fd >= 0) {
++		long int new_delay = 1;
++		char delay[10];
++		ssize_t len;
++
++		len = snprintf(delay, sizeof(delay), "0.%03ld\n", new_delay);
++		if (write(a->safe_mode_delay_fd, delay, len) == len)
++			a->info.safe_mode_delay = new_delay;
+ 	}
+ 
+ 	/* We don't check the array while any update is pending, as it
+@@ -734,6 +742,8 @@ static void manage_new(struct mdstat_ent *mdstat,
+ 	new->resync_start_fd = sysfs_open2(new->info.sys_name, NULL, "resync_start");
+ 	new->metadata_fd = sysfs_open2(new->info.sys_name, NULL, "metadata_version");
+ 	new->sync_completed_fd = sysfs_open2(new->info.sys_name, NULL, "sync_completed");
++	new->safe_mode_delay_fd = sysfs_open2(new->info.sys_name, NULL,
++					      "safe_mode_delay");
+ 
+ 	dprintf("inst: %s action: %d state: %d\n", inst,
+ 		new->action_fd, new->info.state_fd);
+diff --git a/mdmon.h b/mdmon.h
+index 0b08c3d..818367c 100644
+--- a/mdmon.h
++++ b/mdmon.h
+@@ -35,6 +35,7 @@ struct active_array {
+ 	int resync_start_fd;
+ 	int metadata_fd; /* for monitoring rw/ro status */
+ 	int sync_completed_fd; /* for checkpoint notification events */
++	int safe_mode_delay_fd;
+ 	unsigned long long last_checkpoint; /* sync_completed fires for many
+ 					     * reasons this field makes sure the
+ 					     * kernel has made progress before
diff --git a/SOURCES/mdmonitor.service b/SOURCES/mdmonitor.service
index 8c92f82..08cae12 100644
--- a/SOURCES/mdmonitor.service
+++ b/SOURCES/mdmonitor.service
@@ -6,8 +6,9 @@ ConditionPathExists=/etc/mdadm.conf
 [Service]
 Type=forking
 PIDFile=/var/run/mdadm/mdadm.pid
+Environment= MDADM_MONITOR_ARGS=--scan
 EnvironmentFile=-/etc/sysconfig/mdmonitor
-ExecStart=/sbin/mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
+ExecStart=/sbin/mdadm --monitor $MDADM_MONITOR_ARGS -f --pid-file=/var/run/mdadm/mdadm.pid
 
 [Install]
 WantedBy=multi-user.target
diff --git a/SOURCES/mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch b/SOURCES/mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch
new file mode 100644
index 0000000..2c29e51
--- /dev/null
+++ b/SOURCES/mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch
@@ -0,0 +1,46 @@
+From 40b054e1dc9e334621fd2081bf6fc46b01dd7ef4 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:44:20 -0400
+Subject: [RHEL7.5 PATCH 063/169] mdopen/open_mddev: Use
+ md_get_array_info() to determine valid array
+
+md_get_array_info() can be used instead of md_get_version() to
+determine this is in fact a valid array.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdopen.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/mdopen.c b/mdopen.c
+index 685ca32..fe240e5 100644
+--- a/mdopen.c
++++ b/mdopen.c
+@@ -416,19 +416,23 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+  */
+ int open_mddev(char *dev, int report_errors)
+ {
++	struct mdu_array_info_s array;
+ 	int mdfd = open(dev, O_RDONLY);
++
+ 	if (mdfd < 0) {
+ 		if (report_errors)
+ 			pr_err("error opening %s: %s\n",
+ 				dev, strerror(errno));
+ 		return -1;
+ 	}
+-	if (md_get_version(mdfd) <= 0) {
++
++	if (md_get_array_info(mdfd, &array) != 0) {
+ 		close(mdfd);
+ 		if (report_errors)
+ 			pr_err("%s does not appear to be an md device\n", dev);
+ 		return -2;
+ 	}
++
+ 	return mdfd;
+ }
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/mdopen-use-parameters-new_array-to-create-arrays-whe.patch b/SOURCES/mdopen-use-parameters-new_array-to-create-arrays-whe.patch
new file mode 100644
index 0000000..18ea5e5
--- /dev/null
+++ b/SOURCES/mdopen-use-parameters-new_array-to-create-arrays-whe.patch
@@ -0,0 +1,54 @@
+From 039df36231335fabe4da1a22fa3accb160d8bc1b Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Wed, 12 Apr 2017 16:29:04 +1000
+Subject: [RHEL7.5 PATCH 072/169] mdopen: use parameters/new_array to
+ create arrays whenever possible.
+
+In a sufficiently recent kernel, an md%d array can be
+created by writing to .../parameters/new_array.
+If mdadm does this consistently, then another new
+feature, disabling create_on_open, can be enabled.
+This avoids races on shutdown.
+
+An added benefit of using new_array (where available)
+is that it allows md arrays with numbers larger than 511
+(e.g. md999) to be created.  The old create_on_open
+mechanism doesn't support such devices since
+Commit: af5628f05db6 ("md: disable probing for md devices 512 and over.")
+in Linux 3.17.
+
+After a few more mdadm releases it would be good to
+have mdadm disable create_on_open automatically.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdopen.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/mdopen.c b/mdopen.c
+index fe240e5..82b97fc 100644
+--- a/mdopen.c
++++ b/mdopen.c
+@@ -313,6 +313,18 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+ 		if (n < 0)
+ 			devnm[0] = 0;
+ 	}
++	if (num >= 0) {
++		int fd;
++		int n = -1;
++		sprintf(devnm, "md%d", num);
++		fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
++		if (fd >= 0) {
++			n = write(fd, devnm, strlen(devnm));
++			close(fd);
++		}
++		if (n < 0)
++			devnm[0] = 0;
++	}
+ 	if (devnm[0])
+ 		;
+ 	else if (num < 0) {
+-- 
+2.7.4
+
diff --git a/SOURCES/retire-the-APIs-that-driver-nolonger-supports.patch b/SOURCES/retire-the-APIs-that-driver-nolonger-supports.patch
new file mode 100644
index 0000000..c257d16
--- /dev/null
+++ b/SOURCES/retire-the-APIs-that-driver-nolonger-supports.patch
@@ -0,0 +1,51 @@
+From e644902ddbc66d58a3fd4353c9539276ee1fabd7 Mon Sep 17 00:00:00 2001
+From: Zhilong Liu <zlliu@suse.com>
+Date: Thu, 11 May 2017 16:52:41 +0800
+Subject: [RHEL7.5 PATCH 136/169] retire the APIs that driver no longer
+ supports
+
+refer to commit: e6e5f8f1267d ("Build: Stop
+bothering about supporting md driver ...")
+continue to retire the APIs that md driver
+wasn't supported for very long period of time.
+
+Signed-off-by: Zhilong Liu <zlliu@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Build.c  | 4 ----
+ Manage.c | 4 ----
+ 2 files changed, 8 deletions(-)
+
+diff --git a/Build.c b/Build.c
+index ad59867..70ba068 100644
+--- a/Build.c
++++ b/Build.c
+@@ -24,10 +24,6 @@
+ 
+ #include "mdadm.h"
+ 
+-#define REGISTER_DEV		_IO (MD_MAJOR, 1)
+-#define START_MD		_IO (MD_MAJOR, 2)
+-#define STOP_MD			_IO (MD_MAJOR, 3)
+-
+ int Build(char *mddev, struct mddev_dev *devlist,
+ 	  struct shape *s, struct context *c)
+ {
+diff --git a/Manage.c b/Manage.c
+index 14276b7..467efb7 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -27,10 +27,6 @@
+ #include "md_p.h"
+ #include <ctype.h>
+ 
+-#define REGISTER_DEV		_IO (MD_MAJOR, 1)
+-#define START_MD		_IO (MD_MAJOR, 2)
+-#define STOP_MD			_IO (MD_MAJOR, 3)
+-
+ int Manage_ro(char *devname, int fd, int readonly)
+ {
+ 	/* switch to readonly or rw
+-- 
+2.7.4
+
diff --git a/SOURCES/stop-previous-reshape-process-first.patch b/SOURCES/stop-previous-reshape-process-first.patch
new file mode 100644
index 0000000..9314a20
--- /dev/null
+++ b/SOURCES/stop-previous-reshape-process-first.patch
@@ -0,0 +1,35 @@
+commit e1b942b9afa9f3310ea19c57caea896af97b557e
+Author: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+Date:   Thu Sep 7 13:01:16 2017 +0200
+
+    Grow: stop previous reshape process first
+    
+    If array is stopped during reshape and assembled again straight away,
+    reshape process in a background might still be running. systemd doesn't
+    start a new service if one already exists. If there is a race, previous
+    process might terminate and new one is not created. Reshape doesn't
+    continue after assemble.
+    
+    Tell systemd to restart the service rather than just start it. It will
+    assure previous service is stopped first. If it's not running, stopping
+    has no effect and only new process is started.
+    
+    Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@intel.com>
+    Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+
+diff --git a/Grow.c b/Grow.c
+index 534ba80..267b06f 100644
+--- a/Grow.c
++++ b/Grow.c
+@@ -3003,9 +3003,9 @@ static int continue_via_systemd(char *devnm)
+ 		snprintf(pathbuf, sizeof(pathbuf), "mdadm-grow-continue@%s.service",
+ 			 devnm);
+ 		status = execl("/usr/bin/systemctl", "systemctl",
+-			       "start",
++			       "restart",
+ 			       pathbuf, NULL);
+-		status = execl("/bin/systemctl", "systemctl", "start",
++		status = execl("/bin/systemctl", "systemctl", "restart",
+ 			       pathbuf, NULL);
+ 		exit(1);
+ 	case -1: /* Just do it ourselves. */
diff --git a/SOURCES/super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch b/SOURCES/super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch
new file mode 100644
index 0000000..680f406
--- /dev/null
+++ b/SOURCES/super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch
@@ -0,0 +1,27 @@
+From a0628abf2bf87c69bec3384f90aae2398a8e64aa Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 16 May 2017 13:29:46 -0400
+Subject: [RHEL7.5 PATCH 141/169] super-ddf: sysfs_read() takes a pointer
+ as device name argument
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super-ddf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/super-ddf.c b/super-ddf.c
+index ac14017..50197a8 100644
+--- a/super-ddf.c
++++ b/super-ddf.c
+@@ -3557,7 +3557,7 @@ static int load_super_ddf_all(struct supertype *st, int fd,
+ 	char nm[20];
+ 	int dfd;
+ 
+-	sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
++	sra = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
+ 	if (!sra)
+ 		return 1;
+ 	if (sra->array.major_version != -1 ||
+-- 
+2.7.4
+
diff --git a/SOURCES/super1-Always-round-data-offset-to-1M.patch b/SOURCES/super1-Always-round-data-offset-to-1M.patch
new file mode 100644
index 0000000..548e775
--- /dev/null
+++ b/SOURCES/super1-Always-round-data-offset-to-1M.patch
@@ -0,0 +1,33 @@
+From 795bd44ed11aafbed2628ba21216c667371e79a5 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Wed, 26 Jul 2017 16:41:54 +0200
+Subject: [RHEL7.5 PATCH 159/169] super1: Always round data offset to 1M
+
+Currently if metadata requires more then 1M,
+data offset will be rounded down to closest MB.
+This is not correct, since less then required space is reserved.
+Always round data offset up to multiple of 1M.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index 86ec850..b15a1c7 100644
+--- a/super1.c
++++ b/super1.c
+@@ -2796,8 +2796,7 @@ static int validate_geometry1(struct supertype *st, int level,
+ 				headroom >>= 1;
+ 			data_offset = 12*2 + bmspace + headroom;
+ 			#define ONE_MEG (2*1024)
+-			if (data_offset > ONE_MEG)
+-				data_offset = (data_offset / ONE_MEG) * ONE_MEG;
++			data_offset = ROUND_UP(data_offset, ONE_MEG);
+ 			break;
+ 		}
+ 	if (st->data_offset == INVALID_SECTORS)
+-- 
+2.7.4
+
diff --git a/SOURCES/super1-Clean-up-various-style-abuses.patch b/SOURCES/super1-Clean-up-various-style-abuses.patch
new file mode 100644
index 0000000..e7bec44
--- /dev/null
+++ b/SOURCES/super1-Clean-up-various-style-abuses.patch
@@ -0,0 +1,909 @@
+From 46a533a90c01b0492577c61d4e65de2ac4bf220c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 11 Apr 2017 14:25:24 -0400
+Subject: [RHEL7.5 PATCH 071/169] super1: Clean up various style abuses
+
+Code is 80 characters wide, so lets try to respect that. In addition, we
+should never have one-line 'if () action()' statements. Fixup various
+whitespace abuse.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 363 +++++++++++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 223 insertions(+), 140 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index 4db4dff..2fcb814 100644
+--- a/super1.c
++++ b/super1.c
+@@ -227,6 +227,7 @@ static void init_afd(struct align_fd *afd, int fd)
+ }
+ 
+ static char abuf[4096+4096];
++
+ static int aread(struct align_fd *afd, void *buf, int len)
+ {
+ 	/* aligned read.
+@@ -339,7 +340,8 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	    strncmp(sb->set_name, homehost, l) == 0)
+ 		printf("  (local to host %s)", homehost);
+ 	printf("\n");
+-	if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
++	if (bms->nodes > 0 &&
++	    (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
+ 		printf("   Cluster Name : %-64s\n", bms->cluster_name);
+ 	atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL;
+ 	printf("  Creation Time : %.24s\n", ctime(&atime));
+@@ -385,7 +387,8 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	printf("   Super Offset : %llu sectors\n",
+ 	       (unsigned long long)__le64_to_cpu(sb->super_offset));
+ 	if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_RECOVERY_OFFSET)
+-		printf("Recovery Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->recovery_offset));
++		printf("Recovery Offset : %llu sectors\n",
++		       (unsigned long long)__le64_to_cpu(sb->recovery_offset));
+ 
+ 	st->ss->getinfo_super(st, &info, NULL);
+ 	if (info.space_after != 1 &&
+@@ -393,10 +396,12 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 		printf("   Unused Space : before=%llu sectors, after=%llu sectors\n",
+ 		       info.space_before, info.space_after);
+ 
+-	printf("          State : %s\n", (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean");
++	printf("          State : %s\n",
++	       (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean");
+ 	printf("    Device UUID : ");
+ 	for (i=0; i<16; i++) {
+-		if ((i&3)==0 && i != 0) printf(":");
++		if ((i&3)==0 && i != 0)
++			printf(":");
+ 		printf("%02x", sb->device_uuid[i]);
+ 	}
+ 	printf("\n");
+@@ -410,12 +415,15 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 		       __le16_to_cpu(sb->ppl.offset));
+ 	}
+ 	if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) {
+-		printf("  Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2,
++		printf("  Reshape pos'n : %llu%s\n", (unsigned long long)
++		       __le64_to_cpu(sb->reshape_position)/2,
+ 		       human_size(__le64_to_cpu(sb->reshape_position)<<9));
+ 		if (__le32_to_cpu(sb->delta_disks)) {
+-			printf("  Delta Devices : %d", __le32_to_cpu(sb->delta_disks));
++			printf("  Delta Devices : %d",
++			       __le32_to_cpu(sb->delta_disks));
+ 			printf(" (%d->%d)\n",
+-			       __le32_to_cpu(sb->raid_disks)-__le32_to_cpu(sb->delta_disks),
++			       __le32_to_cpu(sb->raid_disks) -
++			       __le32_to_cpu(sb->delta_disks),
+ 			       __le32_to_cpu(sb->raid_disks));
+ 			if ((int)__le32_to_cpu(sb->delta_disks) < 0)
+ 				delta_extra = -__le32_to_cpu(sb->delta_disks);
+@@ -424,13 +432,16 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 			c = map_num(pers, __le32_to_cpu(sb->new_level));
+ 			printf("      New Level : %s\n", c?c:"-unknown-");
+ 		}
+-		if (__le32_to_cpu(sb->new_layout) != __le32_to_cpu(sb->layout)) {
++		if (__le32_to_cpu(sb->new_layout) !=
++		    __le32_to_cpu(sb->layout)) {
+ 			if (__le32_to_cpu(sb->level) == 5) {
+-				c = map_num(r5layout, __le32_to_cpu(sb->new_layout));
++				c = map_num(r5layout,
++					    __le32_to_cpu(sb->new_layout));
+ 				printf("     New Layout : %s\n", c?c:"-unknown-");
+ 			}
+ 			if (__le32_to_cpu(sb->level) == 6) {
+-				c = map_num(r6layout, __le32_to_cpu(sb->new_layout));
++				c = map_num(r6layout,
++					    __le32_to_cpu(sb->new_layout));
+ 				printf("     New Layout : %s\n", c?c:"-unknown-");
+ 			}
+ 			if (__le32_to_cpu(sb->level) == 10) {
+@@ -439,8 +450,10 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 				printf("\n");
+ 			}
+ 		}
+-		if (__le32_to_cpu(sb->new_chunk) != __le32_to_cpu(sb->chunksize))
+-			printf("  New Chunksize : %dK\n", __le32_to_cpu(sb->new_chunk)/2);
++		if (__le32_to_cpu(sb->new_chunk) !=
++		    __le32_to_cpu(sb->chunksize))
++			printf("  New Chunksize : %dK\n",
++			       __le32_to_cpu(sb->new_chunk)/2);
+ 		printf("\n");
+ 	}
+ 	if (sb->devflags) {
+@@ -459,18 +472,20 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 		printf("  Bad Block Log : %d entries available at offset %ld sectors",
+ 		       __le16_to_cpu(sb->bblog_size)*512/8,
+ 		       (long)(int32_t)__le32_to_cpu(sb->bblog_offset));
+-		if (sb->feature_map &
+-		    __cpu_to_le32(MD_FEATURE_BAD_BLOCKS))
++		if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS))
+ 			printf(" - bad blocks present.");
+ 		printf("\n");
+ 	}
+ 
+ 	if (calc_sb_1_csum(sb) == sb->sb_csum)
+-		printf("       Checksum : %x - correct\n", __le32_to_cpu(sb->sb_csum));
++		printf("       Checksum : %x - correct\n",
++		       __le32_to_cpu(sb->sb_csum));
+ 	else
+-		printf("       Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum),
++		printf("       Checksum : %x - expected %x\n",
++		       __le32_to_cpu(sb->sb_csum),
+ 		       __le32_to_cpu(calc_sb_1_csum(sb)));
+-	printf("         Events : %llu\n", (unsigned long long)__le64_to_cpu(sb->events));
++	printf("         Events : %llu\n",
++	       (unsigned long long)__le64_to_cpu(sb->events));
+ 	printf("\n");
+ 	if (__le32_to_cpu(sb->level) == 5) {
+ 		c = map_num(r5layout, __le32_to_cpu(sb->layout));
+@@ -492,26 +507,34 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	case 5:
+ 	case 6:
+ 	case 10:
+-		printf("     Chunk Size : %dK\n", __le32_to_cpu(sb->chunksize)/2);
++		printf("     Chunk Size : %dK\n",
++		       __le32_to_cpu(sb->chunksize)/2);
+ 		break;
+ 	case -1:
+-		printf("       Rounding : %dK\n", __le32_to_cpu(sb->chunksize)/2);
++		printf("       Rounding : %dK\n",
++		       __le32_to_cpu(sb->chunksize)/2);
++		break;
++	default:
+ 		break;
+-	default: break;
+ 	}
+ 	printf("\n");
+ #if 0
+ 	/* This turns out to just be confusing */
+ 	printf("    Array Slot : %d (", __le32_to_cpu(sb->dev_number));
+-	for (i= __le32_to_cpu(sb->max_dev); i> 0 ; i--)
++	for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--)
+ 		if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE)
+ 			break;
+-	for (d=0; d < i; d++) {
++	for (d = 0; d < i; d++) {
+ 		int role = __le16_to_cpu(sb->dev_roles[d]);
+-		if (d) printf(", ");
+-		if (role == MD_DISK_ROLE_SPARE) printf("empty");
+-		else if(role == MD_DISK_ROLE_FAULTY) printf("failed");
+-		else printf("%d", role);
++		if (d)
++			printf(", ");
++		if (role == MD_DISK_ROLE_SPARE)
++			printf("empty");
++		else
++			if(role == MD_DISK_ROLE_FAULTY)
++				printf("failed");
++			else
++				printf("%d", role);
+ 	}
+ 	printf(")\n");
+ #endif
+@@ -527,10 +550,10 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 		printf("Active device %d\n", role);
+ 
+ 	printf("   Array State : ");
+-	for (d=0; d<__le32_to_cpu(sb->raid_disks) + delta_extra; d++) {
++	for (d = 0; d < __le32_to_cpu(sb->raid_disks) + delta_extra; d++) {
+ 		int cnt = 0;
+ 		unsigned int i;
+-		for (i=0; i< __le32_to_cpu(sb->max_dev); i++) {
++		for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
+ 			unsigned int role = __le16_to_cpu(sb->dev_roles[i]);
+ 			if (role == d)
+ 				cnt++;
+@@ -547,12 +570,13 @@ static void examine_super1(struct supertype *st, char *homehost)
+ #if 0
+ 	/* This is confusing too */
+ 	faulty = 0;
+-	for (i=0; i< __le32_to_cpu(sb->max_dev); i++) {
++	for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) {
+ 		int role = __le16_to_cpu(sb->dev_roles[i]);
+ 		if (role == MD_DISK_ROLE_FAULTY)
+ 			faulty++;
+ 	}
+-	if (faulty) printf(" %d failed", faulty);
++	if (faulty)
++		printf(" %d failed", faulty);
+ #endif
+ 	printf(" ('A' == active, '.' == missing, 'R' == replacing)");
+ 	printf("\n");
+@@ -564,7 +588,7 @@ static void brief_examine_super1(struct supertype *st, int verbose)
+ 	int i;
+ 	unsigned long long sb_offset;
+ 	char *nm;
+-	char *c=map_num(pers, __le32_to_cpu(sb->level));
++	char *c = map_num(pers, __le32_to_cpu(sb->level));
+ 
+ 	nm = strchr(sb->set_name, ':');
+ 	if (nm)
+@@ -592,8 +616,9 @@ static void brief_examine_super1(struct supertype *st, int verbose)
+ 	if (verbose)
+ 		printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks));
+ 	printf("UUID=");
+-	for (i=0; i<16; i++) {
+-		if ((i&3)==0 && i != 0) printf(":");
++	for (i = 0; i < 16; i++) {
++		if ((i&3)==0 && i != 0)
++			printf(":");
+ 		printf("%02x", sb->set_uuid[i]);
+ 	}
+ 	if (sb->set_name[0]) {
+@@ -612,9 +637,8 @@ static void export_examine_super1(struct supertype *st)
+ 
+ 	printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level)));
+ 	printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks));
+-	for (i=0; i<32; i++)
+-		if (sb->set_name[i] == '\n' ||
+-		    sb->set_name[i] == '\0') {
++	for (i = 0; i < 32; i++)
++		if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') {
+ 			len = i;
+ 			break;
+ 		}
+@@ -623,10 +647,16 @@ static void export_examine_super1(struct supertype *st)
+ 	if (__le32_to_cpu(sb->level) > 0) {
+ 		int ddsks = 0, ddsks_denom = 1;
+ 		switch(__le32_to_cpu(sb->level)) {
+-			case 1: ddsks=1;break;
++			case 1:
++				ddsks = 1;
++				break;
+ 			case 4:
+-			case 5: ddsks = __le32_to_cpu(sb->raid_disks)-1; break;
+-			case 6: ddsks = __le32_to_cpu(sb->raid_disks)-2; break;
++			case 5:
++				ddsks = __le32_to_cpu(sb->raid_disks)-1;
++				break;
++			case 6:
++				ddsks = __le32_to_cpu(sb->raid_disks)-2;
++				break;
+ 			case 10:
+ 				layout = __le32_to_cpu(sb->layout);
+ 				ddsks = __le32_to_cpu(sb->raid_disks);
+@@ -635,20 +665,23 @@ static void export_examine_super1(struct supertype *st)
+ 		if (ddsks) {
+ 			long long asize = __le64_to_cpu(sb->size);
+ 			asize = (asize << 9) * ddsks / ddsks_denom;
+-			printf("MD_ARRAY_SIZE=%s\n",human_size_brief(asize,JEDEC));
++			printf("MD_ARRAY_SIZE=%s\n",
++			       human_size_brief(asize, JEDEC));
+ 		}
+ 	}
+ 	printf("MD_UUID=");
+-	for (i=0; i<16; i++) {
+-		if ((i&3)==0 && i != 0) printf(":");
++	for (i = 0; i < 16; i++) {
++		if ((i&3) == 0 && i != 0)
++			printf(":");
+ 		printf("%02x", sb->set_uuid[i]);
+ 	}
+ 	printf("\n");
+ 	printf("MD_UPDATE_TIME=%llu\n",
+ 	       __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL);
+ 	printf("MD_DEV_UUID=");
+-	for (i=0; i<16; i++) {
+-		if ((i&3)==0 && i != 0) printf(":");
++	for (i = 0; i < 16; i++) {
++		if ((i&3) == 0 && i != 0)
++			printf(":");
+ 		printf("%02x", sb->device_uuid[i]);
+ 	}
+ 	printf("\n");
+@@ -797,15 +830,16 @@ static void detail_super1(struct supertype *st, char *homehost)
+ 	int l = homehost ? strlen(homehost) : 0;
+ 
+ 	printf("              Name : %.32s", sb->set_name);
+-	if (l > 0 && l < 32 &&
+-	    sb->set_name[l] == ':' &&
++	if (l > 0 && l < 32 && sb->set_name[l] == ':' &&
+ 	    strncmp(sb->set_name, homehost, l) == 0)
+ 		printf("  (local to host %s)", homehost);
+-	if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
+-	    printf("\n      Cluster Name : %-64s", bms->cluster_name);
++	if (bms->nodes > 0 &&
++	    (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET))
++		printf("\n      Cluster Name : %-64s", bms->cluster_name);
+ 	printf("\n              UUID : ");
+-	for (i=0; i<16; i++) {
+-		if ((i&3)==0 && i != 0) printf(":");
++	for (i = 0; i < 16; i++) {
++		if ((i&3) == 0 && i != 0)
++			printf(":");
+ 		printf("%02x", sb->set_uuid[i]);
+ 	}
+ 	printf("\n            Events : %llu\n\n",
+@@ -822,8 +856,9 @@ static void brief_detail_super1(struct supertype *st)
+ 		print_quoted(sb->set_name);
+ 	}
+ 	printf(" UUID=");
+-	for (i=0; i<16; i++) {
+-		if ((i&3)==0 && i != 0) printf(":");
++	for (i = 0; i < 16; i++) {
++		if ((i & 3) == 0 && i != 0)
++			printf(":");
+ 		printf("%02x", sb->set_uuid[i]);
+ 	}
+ }
+@@ -834,9 +869,8 @@ static void export_detail_super1(struct supertype *st)
+ 	int i;
+ 	int len = 32;
+ 
+-	for (i=0; i<32; i++)
+-		if (sb->set_name[i] == '\n' ||
+-		    sb->set_name[i] == '\0') {
++	for (i = 0; i < 32; i++)
++		if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') {
+ 			len = i;
+ 			break;
+ 		}
+@@ -852,13 +886,12 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
+ 	__u64 *bbl, *bbp;
+ 	int i;
+ 
+-	if  (!sb->bblog_size || __le16_to_cpu(sb->bblog_size) > 100
+-	     || !sb->bblog_offset){
++	if  (!sb->bblog_size || __le16_to_cpu(sb->bblog_size) > 100 ||
++	     !sb->bblog_offset){
+ 		printf("No bad-blocks list configured on %s\n", devname);
+ 		return 0;
+ 	}
+-	if ((sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS))
+-	    == 0) {
++	if ((sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) == 0) {
+ 		printf("Bad-blocks list is empty in %s\n", devname);
+ 		return 0;
+ 	}
+@@ -905,8 +938,7 @@ static int match_home1(struct supertype *st, char *homehost)
+ 	struct mdp_superblock_1 *sb = st->sb;
+ 	int l = homehost ? strlen(homehost) : 0;
+ 
+-	return (l > 0 && l < 32 &&
+-		sb->set_name[l] == ':' &&
++	return (l > 0 && l < 32 && sb->set_name[l] == ':' &&
+ 		strncmp(sb->set_name, homehost, l) == 0);
+ }
+ 
+@@ -915,7 +947,7 @@ static void uuid_from_super1(struct supertype *st, int uuid[4])
+ 	struct mdp_superblock_1 *super = st->sb;
+ 	char *cuuid = (char*)uuid;
+ 	int i;
+-	for (i=0; i<16; i++)
++	for (i = 0; i < 16; i++)
+ 		cuuid[i] = super->set_uuid[i];
+ }
+ 
+@@ -923,7 +955,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ {
+ 	struct mdp_superblock_1 *sb = st->sb;
+ 	struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE);
+-	struct misc_dev_info *misc = (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE);
++	struct misc_dev_info *misc =
++		(void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE);
+ 	int working = 0;
+ 	unsigned int i;
+ 	unsigned int role;
+@@ -943,8 +976,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	info->array.utime = __le64_to_cpu(sb->utime);
+ 	info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512;
+ 	info->array.state =
+-		(__le64_to_cpu(sb->resync_offset) == MaxSector)
+-		? 1 : 0;
++		(__le64_to_cpu(sb->resync_offset) == MaxSector)	? 1 : 0;
+ 	if (__le32_to_cpu(bsb->nodes) > 1)
+ 		info->array.state |= (1 << MD_SB_CLUSTERED);
+ 
+@@ -985,7 +1017,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 		}
+ 
+ 		if (super_offset + info->bitmap_offset + info->ppl_offset < end)
+-			end = super_offset + info->bitmap_offset + info->ppl_offset;
++			end = super_offset + info->bitmap_offset +
++				info->ppl_offset;
+ 
+ 		if (info->data_offset + data_size < end)
+ 			info->space_after = end - data_size - info->data_offset;
+@@ -1002,8 +1035,9 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 			if (bmend > earliest)
+ 				earliest = bmend;
+ 		} else if (info->ppl_offset > 0) {
+-			unsigned long long pplend = info->ppl_offset +
+-						    info->ppl_size;
++			unsigned long long pplend;
++
++			pplend = info->ppl_offset + info->ppl_size;
+ 			if (pplend > earliest)
+ 				earliest = pplend;
+ 		}
+@@ -1018,7 +1052,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 			info->space_before = info->data_offset - earliest;
+ 		else
+ 			info->space_before = 0;
+-		info->space_after = misc->device_size - data_size - info->data_offset;
++		info->space_after = misc->device_size - data_size -
++			info->data_offset;
+ 	}
+ 	if (info->space_before == 0 && info->space_after == 0) {
+ 		/* It will look like we don't support data_offset changes,
+@@ -1032,7 +1067,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	info->disk.raid_disk = -1;
+ 	switch(role) {
+ 	case MD_DISK_ROLE_SPARE:
+-		info->disk.state = 0; /* spare: not active, not sync, not faulty */
++		/* spare: not active, not sync, not faulty */
++		info->disk.state = 0;
+ 		break;
+ 	case MD_DISK_ROLE_FAULTY:
+ 		info->disk.state = (1 << MD_DISK_FAULTY); /* faulty */
+@@ -1040,7 +1076,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	case MD_DISK_ROLE_JOURNAL:
+ 		info->disk.state = (1 << MD_DISK_JOURNAL);
+ 		info->disk.raid_disk = role;
+-		info->space_after = (misc->device_size - info->data_offset) % 8; /* journal uses all 4kB blocks*/
++		/* journal uses all 4kB blocks*/
++		info->space_after = (misc->device_size - info->data_offset) % 8;
+ 		break;
+ 	default:
+ 		info->disk.state = 6; /* active and in sync */
+@@ -1129,8 +1166,7 @@ static struct mdinfo *container_content1(struct supertype *st, char *subarray)
+ }
+ 
+ static int update_super1(struct supertype *st, struct mdinfo *info,
+-			 char *update,
+-			 char *devname, int verbose,
++			 char *update, char *devname, int verbose,
+ 			 int uuid_set, char *homehost)
+ {
+ 	/* NOTE: for 'assemble' and 'force' we need to return non-zero
+@@ -1145,7 +1181,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 	if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+ 		rv = cluster_get_dlmlock(&lockid);
+ 		if (rv) {
+-			pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
++			pr_err("Cannot get dlmlock in %s return %d\n",
++			       __func__, rv);
+ 			cluster_release_dlmlock(lockid);
+ 			return rv;
+ 		}
+@@ -1178,7 +1215,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		 * maybe need to mark it 'clean'.
+ 		 */
+ 		switch(__le32_to_cpu(sb->level)) {
+-		case 5: case 4: case 6:
++		case 4:
++		case 5:
++		case 6:
+ 			/* need to force clean */
+ 			if (sb->resync_offset != MaxSector)
+ 				rv = 1;
+@@ -1198,17 +1237,23 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			rv = 1;
+ 		}
+ 		if (info->reshape_active &&
+-		    sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) &&
++		    sb->feature_map &
++		    __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) &&
+ 		    info->delta_disks >= 0 &&
+-		    info->reshape_progress < __le64_to_cpu(sb->reshape_position)) {
+-			sb->reshape_position = __cpu_to_le64(info->reshape_progress);
++		    info->reshape_progress <
++		    __le64_to_cpu(sb->reshape_position)) {
++			sb->reshape_position =
++				__cpu_to_le64(info->reshape_progress);
+ 			rv = 1;
+ 		}
+ 		if (info->reshape_active &&
+-		    sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) &&
++		    sb->feature_map &
++		    __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) &&
+ 		    info->delta_disks < 0 &&
+-		    info->reshape_progress > __le64_to_cpu(sb->reshape_position)) {
+-			sb->reshape_position = __cpu_to_le64(info->reshape_progress);
++		    info->reshape_progress >
++		    __le64_to_cpu(sb->reshape_position)) {
++			sb->reshape_position =
++				__cpu_to_le64(info->reshape_progress);
+ 			rv = 1;
+ 		}
+ 	} else if (strcmp(update, "linear-grow-new") == 0) {
+@@ -1216,8 +1261,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		int fd;
+ 		unsigned int max = __le32_to_cpu(sb->max_dev);
+ 
+-		for (i=0 ; i < max ; i++)
+-			if (__le16_to_cpu(sb->dev_roles[i]) >= MD_DISK_ROLE_FAULTY)
++		for (i = 0; i < max; i++)
++			if (__le16_to_cpu(sb->dev_roles[i]) >=
++			    MD_DISK_ROLE_FAULTY)
+ 				break;
+ 		sb->dev_number = __cpu_to_le32(i);
+ 		info->disk.number = i;
+@@ -1226,8 +1272,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 
+ 		random_uuid(sb->device_uuid);
+ 
+-		sb->dev_roles[i] =
+-			__cpu_to_le16(info->disk.raid_disk);
++		sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk);
+ 
+ 		fd = open(devname, O_RDONLY);
+ 		if (fd >= 0) {
+@@ -1280,14 +1325,16 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		}
+ 
+ 		if (sb_offset < data_offset) {
+-			/* 1.1 or 1.2.  Put bbl after bitmap leaving at least 32K
++			/*
++			 * 1.1 or 1.2.  Put bbl after bitmap leaving
++			 * at least 32K
+ 			 */
+ 			long bb_offset;
+ 			bb_offset = sb_offset + 8;
+ 			if (bm_sectors && bitmap_offset > 0)
+ 				bb_offset = bitmap_offset + bm_sectors;
+-			while (bb_offset < (long)sb_offset + 8 + 32*2
+-			       && bb_offset + 8+8 <= (long)data_offset)
++			while (bb_offset < (long)sb_offset + 8 + 32*2 &&
++			       bb_offset + 8+8 <= (long)data_offset)
+ 				/* too close to bitmap, and room to grow */
+ 				bb_offset += 8;
+ 			if (bb_offset + 8 <= (long)data_offset) {
+@@ -1381,8 +1428,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		} else
+ 			strncpy(sb->set_name, info->name, sizeof(sb->set_name));
+ 	} else if (strcmp(update, "devicesize") == 0 &&
+-	    __le64_to_cpu(sb->super_offset) <
+-	    __le64_to_cpu(sb->data_offset)) {
++		   __le64_to_cpu(sb->super_offset) <
++		   __le64_to_cpu(sb->data_offset)) {
+ 		/* set data_size to device size less data_offset */
+ 		struct misc_dev_info *misc = (struct misc_dev_info*)
+ 			(st->sb + MAX_SB_SIZE + BM_SUPER_SIZE);
+@@ -1390,7 +1437,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			misc->device_size - __le64_to_cpu(sb->data_offset));
+ 	} else if (strncmp(update, "revert-reshape", 14) == 0) {
+ 		rv = -2;
+-		if (!(sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)))
++		if (!(sb->feature_map &
++		      __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)))
+ 			pr_err("No active reshape to revert on %s\n",
+ 			       devname);
+ 		else {
+@@ -1431,9 +1479,11 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			 */
+ 			if (__le32_to_cpu(sb->level) >= 4 &&
+ 			    __le32_to_cpu(sb->level) <= 6) {
+-				reshape_sectors = __le64_to_cpu(sb->reshape_position);
++				reshape_sectors =
++					__le64_to_cpu(sb->reshape_position);
+ 				reshape_chunk = __le32_to_cpu(sb->new_chunk);
+-				reshape_chunk *= __le32_to_cpu(sb->raid_disks) - __le32_to_cpu(sb->delta_disks) -
++				reshape_chunk *= __le32_to_cpu(sb->raid_disks) -
++					__le32_to_cpu(sb->delta_disks) -
+ 					(__le32_to_cpu(sb->level)==6 ? 2 : 1);
+ 				if (reshape_sectors % reshape_chunk) {
+ 					pr_err("Reshape position is not suitably aligned.\n");
+@@ -1441,8 +1491,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 					return -2;
+ 				}
+ 			}
+-			sb->raid_disks = __cpu_to_le32(__le32_to_cpu(sb->raid_disks) -
+-						       __le32_to_cpu(sb->delta_disks));
++			sb->raid_disks =
++				__cpu_to_le32(__le32_to_cpu(sb->raid_disks) -
++					      __le32_to_cpu(sb->delta_disks));
+ 			if (sb->delta_disks == 0)
+ 				sb->feature_map ^= __cpu_to_le32(MD_FEATURE_RESHAPE_BACKWARDS);
+ 			else
+@@ -1456,19 +1507,21 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			sb->new_chunk = sb->chunksize;
+ 			sb->chunksize = temp;
+ 
+-			if (sb->feature_map & __cpu_to_le32(MD_FEATURE_NEW_OFFSET)) {
+-				long offset_delta = (int32_t)__le32_to_cpu(sb->new_offset);
++			if (sb->feature_map &
++			    __cpu_to_le32(MD_FEATURE_NEW_OFFSET)) {
++				long offset_delta =
++					(int32_t)__le32_to_cpu(sb->new_offset);
+ 				sb->data_offset = __cpu_to_le64(__le64_to_cpu(sb->data_offset) + offset_delta);
+ 				sb->new_offset = __cpu_to_le32(-offset_delta);
+ 				sb->data_size = __cpu_to_le64(__le64_to_cpu(sb->data_size) - offset_delta);
+ 			}
+ 		done:;
+ 		}
+-	} else if (strcmp(update, "_reshape_progress")==0)
++	} else if (strcmp(update, "_reshape_progress") == 0)
+ 		sb->reshape_position = __cpu_to_le64(info->reshape_progress);
+-	else if (strcmp(update, "writemostly")==0)
++	else if (strcmp(update, "writemostly") == 0)
+ 		sb->devflags |= WriteMostly1;
+-	else if (strcmp(update, "readwrite")==0)
++	else if (strcmp(update, "readwrite") == 0)
+ 		sb->devflags &= ~WriteMostly1;
+ 	else if (strcmp(update, "failfast") == 0)
+ 		sb->devflags |= FailFast1;
+@@ -1553,11 +1606,14 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
+ 		sb->resync_offset = MaxSector;
+ 	else
+ 		sb->resync_offset = 0;
+-	sbsize = sizeof(struct mdp_superblock_1) + 2 * (info->raid_disks + spares);
++	sbsize = sizeof(struct mdp_superblock_1) +
++		2 * (info->raid_disks + spares);
+ 	sbsize = ROUND_UP(sbsize, 512);
+-	sb->max_dev = __cpu_to_le32((sbsize - sizeof(struct mdp_superblock_1)) / 2);
++	sb->max_dev =
++		__cpu_to_le32((sbsize - sizeof(struct mdp_superblock_1)) / 2);
+ 
+-	memset(sb->dev_roles, 0xff, MAX_SB_SIZE - sizeof(struct mdp_superblock_1));
++	memset(sb->dev_roles, 0xff,
++	       MAX_SB_SIZE - sizeof(struct mdp_superblock_1));
+ 
+ 	if (s->consistency_policy == CONSISTENCY_POLICY_PPL)
+ 		sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL);
+@@ -1587,7 +1643,8 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 	if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+ 		rv = cluster_get_dlmlock(&lockid);
+ 		if (rv) {
+-			pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
++			pr_err("Cannot get dlmlock in %s return %d\n",
++			       __func__, rv);
+ 			cluster_release_dlmlock(lockid);
+ 			return rv;
+ 		}
+@@ -1599,7 +1656,8 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 		*rp = __cpu_to_le16(dk->raid_disk);
+ 	else if (dk_state & (1<<MD_DISK_JOURNAL))
+                 *rp = MD_DISK_ROLE_JOURNAL;
+-	else if ((dk_state & ~(1<<MD_DISK_ACTIVE)) == 0) /* active or idle -> spare */
++	else if ((dk_state & ~(1<<MD_DISK_ACTIVE)) == 0)
++		/* active or idle -> spare */
+ 		*rp = MD_DISK_ROLE_SPARE;
+ 	else
+ 		*rp = MD_DISK_ROLE_FAULTY;
+@@ -1644,7 +1702,8 @@ static int store_super1(struct supertype *st, int fd)
+ 	if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+ 		rv = cluster_get_dlmlock(&lockid);
+ 		if (rv) {
+-			pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv);
++			pr_err("Cannot get dlmlock in %s return %d\n",
++			       __func__, rv);
+ 			cluster_release_dlmlock(lockid);
+ 			return rv;
+ 		}
+@@ -1911,7 +1970,8 @@ static int write_init_super1(struct supertype *st)
+ 			bm_space = calc_bitmap_size(bms, 4096) >> 9;
+ 			bm_offset = (long)__le32_to_cpu(sb->bitmap_offset);
+ 		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
+-			bm_space = choose_ppl_space(__le32_to_cpu(sb->chunksize));
++			bm_space =
++			  choose_ppl_space(__le32_to_cpu(sb->chunksize));
+ 			if (bm_space > UINT16_MAX)
+ 				bm_space = UINT16_MAX;
+ 			if (st->minor_version == 0) {
+@@ -1981,7 +2041,10 @@ static int write_init_super1(struct supertype *st)
+ 			rv = -EINVAL;
+ 			goto out;
+ 		}
+-		/* Disable badblock log on clusters, or when explicitly requested */
++		/*
++		 * Disable badblock log on clusters, or when
++		 * explicitly requested
++		 */
+ 		if (st->nodes > 0 || conf_get_create_info()->bblist == 0) {
+ 			sb->bblog_size = 0;
+ 			sb->bblog_offset = 0;
+@@ -1997,7 +2060,8 @@ static int write_init_super1(struct supertype *st)
+ 		}
+ 
+ 		if (rv == 0 &&
+-		    (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) {
++		    (__le32_to_cpu(sb->feature_map) &
++		     MD_FEATURE_BITMAP_OFFSET)) {
+ 			rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate);
+ 		} else if (rv == 0 &&
+ 			 (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) {
+@@ -2014,8 +2078,7 @@ static int write_init_super1(struct supertype *st)
+ 	}
+ error_out:
+ 	if (rv)
+-		pr_err("Failed to write metadata to %s\n",
+-		       di->devname);
++		pr_err("Failed to write metadata to %s\n", di->devname);
+ out:
+ 	return rv;
+ }
+@@ -2080,7 +2143,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
+ 		/* guess... choose latest ctime */
+ 		memset(&tst, 0, sizeof(tst));
+ 		tst.ss = &super1;
+-		for (tst.minor_version = 0; tst.minor_version <= 2 ; tst.minor_version++) {
++		for (tst.minor_version = 0; tst.minor_version <= 2;
++		     tst.minor_version++) {
+ 			switch(load_super1(&tst, fd, devname)) {
+ 			case 0: super = tst.sb;
+ 				if (bestvers == -1 ||
+@@ -2167,7 +2231,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
+ 	if (__le32_to_cpu(super->magic) != MD_SB_MAGIC) {
+ 		if (devname)
+ 			pr_err("No super block found on %s (Expected magic %08x, got %08x)\n",
+-				devname, MD_SB_MAGIC, __le32_to_cpu(super->magic));
++				devname, MD_SB_MAGIC,
++			       __le32_to_cpu(super->magic));
+ 		free(super);
+ 		return 2;
+ 	}
+@@ -2190,7 +2255,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
+ 
+ 	bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
+ 
+-	misc = (struct misc_dev_info*) (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE);
++	misc = (struct misc_dev_info*)
++	  (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE);
+ 	misc->device_size = dsize;
+ 	if (st->data_offset == INVALID_SECTORS)
+ 		st->data_offset = __le64_to_cpu(super->data_offset);
+@@ -2230,13 +2296,11 @@ static struct supertype *match_metadata_desc1(char *arg)
+ 	/* leading zeros can be safely ignored.  --detail generates them. */
+ 	while (*arg == '0')
+ 		arg++;
+-	if (strcmp(arg, "1.0") == 0 ||
+-	    strcmp(arg, "1.00") == 0) {
++	if (strcmp(arg, "1.0") == 0 || strcmp(arg, "1.00") == 0) {
+ 		st->minor_version = 0;
+ 		return st;
+ 	}
+-	if (strcmp(arg, "1.1") == 0 ||
+-	    strcmp(arg, "1.01") == 0
++	if (strcmp(arg, "1.1") == 0 || strcmp(arg, "1.01") == 0
+ 		) {
+ 		st->minor_version = 1;
+ 		return st;
+@@ -2249,8 +2313,7 @@ static struct supertype *match_metadata_desc1(char *arg)
+ 		st->minor_version = 2;
+ 		return st;
+ 	}
+-	if (strcmp(arg, "1") == 0 ||
+-	    strcmp(arg, "default") == 0) {
++	if (strcmp(arg, "1") == 0 || strcmp(arg, "default") == 0) {
+ 		st->minor_version = -1;
+ 		return st;
+ 	}
+@@ -2348,20 +2411,26 @@ add_internal_bitmap1(struct supertype *st,
+ 	int uuid[4];
+ 
+ 	if (__le64_to_cpu(sb->data_size) == 0)
+-		/* Must be creating the array, else data_size would be non-zero */
++		/*
++		 * Must be creating the array, else data_size
++		 * would be non-zero
++		 */
+ 		creating = 1;
+ 	switch(st->minor_version) {
+ 	case 0:
+-		/* either 3K after the superblock (when hot-add),
++		/*
++		 * either 3K after the superblock (when hot-add),
+ 		 * or some amount of space before.
+ 		 */
+ 		if (creating) {
+-			/* We are creating array, so we *know* how much room has
++			/*
++			 * We are creating array, so we *know* how much room has
+ 			 * been left.
+ 			 */
+ 			offset = 0;
+ 			bbl_size = 8;
+-			room = choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size;
++			room =
++			  choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size;
+ 		} else {
+ 			room = __le64_to_cpu(sb->super_offset)
+ 				- __le64_to_cpu(sb->data_offset)
+@@ -2373,8 +2442,8 @@ add_internal_bitmap1(struct supertype *st,
+ 			if (bbl_size < -bbl_offset)
+ 				bbl_size = -bbl_offset;
+ 
+-			if (!may_change || (room < 3*2 &&
+-					    __le32_to_cpu(sb->max_dev) <= 384)) {
++			if (!may_change ||
++			    (room < 3*2 && __le32_to_cpu(sb->max_dev) <= 384)) {
+ 				room = 3*2;
+ 				offset = 1*2;
+ 				bbl_size = 0;
+@@ -2388,13 +2457,15 @@ add_internal_bitmap1(struct supertype *st,
+ 		if (creating) {
+ 			offset = 4*2;
+ 			bbl_size = 8;
+-			room = choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size;
++			room =
++			  choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size;
+ 		} else {
+ 			room = __le64_to_cpu(sb->data_offset)
+ 				- __le64_to_cpu(sb->super_offset);
+ 			bbl_size = __le16_to_cpu(sb->bblog_size);
+ 			if (bbl_size)
+-				room = __le32_to_cpu(sb->bblog_offset) + bbl_size;
++				room =
++				  __le32_to_cpu(sb->bblog_offset) + bbl_size;
+ 			else
+ 				bbl_size = 8;
+ 
+@@ -2453,8 +2524,8 @@ add_internal_bitmap1(struct supertype *st,
+ 
+ 	sb->bitmap_offset = (int32_t)__cpu_to_le32(offset);
+ 
+-	sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map)
+-					| MD_FEATURE_BITMAP_OFFSET);
++	sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) |
++					MD_FEATURE_BITMAP_OFFSET);
+ 	memset(bms, 0, sizeof(*bms));
+ 	bms->magic = __cpu_to_le32(BITMAP_MAGIC);
+ 	bms->version = __cpu_to_le32(major);
+@@ -2466,8 +2537,8 @@ add_internal_bitmap1(struct supertype *st,
+ 	bms->write_behind = __cpu_to_le32(write_behind);
+ 	bms->nodes = __cpu_to_le32(st->nodes);
+ 	if (st->nodes)
+-		sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map)
+-						| MD_FEATURE_BITMAP_VERSIONED);
++		sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) |
++						MD_FEATURE_BITMAP_VERSIONED);
+ 	if (st->cluster_name) {
+ 		len = sizeof(bms->cluster_name);
+ 		strncpy((char *)bms->cluster_name, st->cluster_name, len);
+@@ -2528,31 +2599,43 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
+ 		break;
+ 	case NodeNumUpdate:
+ 		/* cluster md only supports superblock 1.2 now */
+-		if (st->minor_version != 2 && bms->version == BITMAP_MAJOR_CLUSTERED) {
++		if (st->minor_version != 2 &&
++		    bms->version == BITMAP_MAJOR_CLUSTERED) {
+ 			pr_err("Warning: cluster md only works with superblock 1.2\n");
+ 			return -EINVAL;
+ 		}
+ 
+ 		if (bms->version == BITMAP_MAJOR_CLUSTERED) {
+ 			if (__cpu_to_le32(st->nodes) < bms->nodes) {
+-				/* Since the nodes num is not increased, no need to check the space
+-				 * is enough or not, just update bms->nodes */
++				/*
++				 * Since the nodes num is not increased, no
++				 * need to check the space enough or not,
++				 * just update bms->nodes
++				 */
+ 				bms->nodes = __cpu_to_le32(st->nodes);
+ 				break;
+ 			}
+ 		} else {
+-			/* no need to change bms->nodes for other bitmap types */
++			/*
++			 * no need to change bms->nodes for other
++			 * bitmap types
++			 */
+ 			if (st->nodes)
+ 				pr_err("Warning: --nodes option is only suitable for clustered bitmap\n");
+ 			break;
+ 		}
+ 
+-		/* Each node has an independent bitmap, it is necessary to calculate the
+-		 * space is enough or not, first get how many bytes for the total bitmap */
++		/*
++		 * Each node has an independent bitmap, it is necessary to
++		 * calculate the space is enough or not, first get how many
++		 * bytes for the total bitmap
++		 */
+ 		bm_space_per_node = calc_bitmap_size(bms, 4096);
+ 
+-		total_bm_space = 512 * (__le64_to_cpu(sb->data_offset) - __le64_to_cpu(sb->super_offset));
+-		total_bm_space = total_bm_space - 4096; /* leave another 4k for superblock */
++		total_bm_space = 512 * (__le64_to_cpu(sb->data_offset) -
++					__le64_to_cpu(sb->super_offset));
++		/* leave another 4k for superblock */
++		total_bm_space = total_bm_space - 4096;
+ 
+ 		if (bm_space_per_node * st->nodes > total_bm_space) {
+ 			pr_err("Warning: The max num of nodes can't exceed %llu\n",
+-- 
+2.7.4
+
diff --git a/SOURCES/super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch b/SOURCES/super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch
new file mode 100644
index 0000000..0b38da0
--- /dev/null
+++ b/SOURCES/super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch
@@ -0,0 +1,56 @@
+From 68fee4af1703dc0bc0d1c9c99fd750e8dca3a131 Mon Sep 17 00:00:00 2001
+From: Lidong Zhong <lzhong@suse.com>
+Date: Thu, 25 May 2017 17:28:11 +0800
+Subject: [RHEL7.5 PATCH 148/169] super1: fix sb->max_dev when adding a new
+ disk in linear array
+
+The value of sb->max_dev will always be increased by 1 when adding
+a new disk in linear array. It causes an inconsistence between each
+disk in the array and the "Array State" value of "mdadm --examine DISK"
+is wrong. For example, when adding the first new disk into linear array
+it will be:
+
+Array State : RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+('A' == active, '.' == missing, 'R' == replacing)
+
+Adding the second disk into linear array it will be
+
+Array State : .AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+('A' == active, '.' == missing, 'R' == replacing)
+
+Signed-off-by: Lidong Zhong <lzhong@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/super1.c b/super1.c
+index 2fcb814..86ec850 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1267,8 +1267,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 				break;
+ 		sb->dev_number = __cpu_to_le32(i);
+ 		info->disk.number = i;
+-		if (max >= __le32_to_cpu(sb->max_dev))
++		if (i >= max) {
+ 			sb->max_dev = __cpu_to_le32(max+1);
++		}
+ 
+ 		random_uuid(sb->device_uuid);
+ 
+@@ -1293,7 +1294,11 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			}
+ 		}
+ 	} else if (strcmp(update, "linear-grow-update") == 0) {
++		int max = __le32_to_cpu(sb->max_dev);
+ 		sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
++		if (info->array.raid_disks > max) {
++			sb->max_dev = __cpu_to_le32(max+1);
++		}
+ 		sb->dev_roles[info->disk.number] =
+ 			__cpu_to_le16(info->disk.raid_disk);
+ 	} else if (strcmp(update, "resync") == 0) {
+-- 
+2.7.4
+
diff --git a/SOURCES/super1-ignore-failfast-flag-for-setting-device-role.patch b/SOURCES/super1-ignore-failfast-flag-for-setting-device-role.patch
new file mode 100644
index 0000000..f73b1b0
--- /dev/null
+++ b/SOURCES/super1-ignore-failfast-flag-for-setting-device-role.patch
@@ -0,0 +1,48 @@
+From e23c2663da73f905aa5fa9800feda3d08a8026ee Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@profitbricks.com>
+Date: Mon, 20 Mar 2017 10:51:56 +0100
+Subject: [RHEL7.5 PATCH 017/169] super1: ignore failfast flag for setting
+ device role
+
+There is corner case for setting device role,
+if new device has failfast flag.
+The failfast flag should be ignored.
+
+Signed-off-by: Gioh Kim <gi-oh.kim@profitbricks.com>
+Signed-off-by: Jack Wang <jinpu.wang@profitbricks.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ super1.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index 882cd61..f3520ac 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1491,6 +1491,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 	struct devinfo *di, **dip;
+ 	bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
+ 	int rv, lockid;
++	int dk_state;
+ 
+ 	if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) {
+ 		rv = cluster_get_dlmlock(&lockid);
+@@ -1501,11 +1502,12 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 		}
+ 	}
+ 
+-	if ((dk->state & 6) == 6) /* active, sync */
++	dk_state = dk->state & ~(1<<MD_DISK_FAILFAST);
++	if ((dk_state & 6) == 6) /* active, sync */
+ 		*rp = __cpu_to_le16(dk->raid_disk);
+-	else if (dk->state & (1<<MD_DISK_JOURNAL))
++	else if (dk_state & (1<<MD_DISK_JOURNAL))
+                 *rp = MD_DISK_ROLE_JOURNAL;
+-	else if ((dk->state & ~2) == 0) /* active or idle -> spare */
++	else if ((dk_state & ~2) == 0) /* active or idle -> spare */
+ 		*rp = MD_DISK_ROLE_SPARE;
+ 	else
+ 		*rp = MD_DISK_ROLE_FAULTY;
+-- 
+2.7.4
+
diff --git a/SOURCES/super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch b/SOURCES/super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch
new file mode 100644
index 0000000..59ccca1
--- /dev/null
+++ b/SOURCES/super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch
@@ -0,0 +1,43 @@
+From 6438c249c4fed92cf6e5fb492d19f4c4f516ff6f Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Fri, 4 Aug 2017 15:30:02 +1000
+Subject: [RHEL7.5 PATCH 166/169] super1: only set clustered flag when
+ bitmap is present
+
+If no bitmap is present, then the test
+
+	if (__le32_to_cpu(bsb->nodes) > 1)
+
+accesses uninitialised memory.  So move that test inside
+a test for a bitmap being present.
+
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index b15a1c7..f6a1045 100644
+--- a/super1.c
++++ b/super1.c
+@@ -977,14 +977,14 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512;
+ 	info->array.state =
+ 		(__le64_to_cpu(sb->resync_offset) == MaxSector)	? 1 : 0;
+-	if (__le32_to_cpu(bsb->nodes) > 1)
+-		info->array.state |= (1 << MD_SB_CLUSTERED);
+ 
+ 	super_offset = __le64_to_cpu(sb->super_offset);
+ 	info->data_offset = __le64_to_cpu(sb->data_offset);
+ 	info->component_size = __le64_to_cpu(sb->size);
+ 	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) {
+ 		info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset);
++		if (__le32_to_cpu(bsb->nodes) > 1)
++			info->array.state |= (1 << MD_SB_CLUSTERED);
+ 	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
+ 		info->ppl_offset = __le16_to_cpu(sb->ppl.offset);
+ 		info->ppl_size = __le16_to_cpu(sb->ppl.size);
+-- 
+2.7.4
+
diff --git a/SOURCES/super1-ppl-support.patch b/SOURCES/super1-ppl-support.patch
deleted file mode 100644
index 665387d..0000000
--- a/SOURCES/super1-ppl-support.patch
+++ /dev/null
@@ -1,430 +0,0 @@
-commit e97a7cd011345e5dead736de51b33968da49d876
-Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
-Date:   Wed Mar 29 11:54:18 2017 +0200
-
-    super1: PPL support
-    
-    Enable creating and assembling raid5 arrays with PPL for 1.x metadata.
-    
-    When creating, reserve enough space for PPL and store its size and
-    location in the superblock and set MD_FEATURE_PPL bit. Write an initial
-    empty header in the PPL area on each device. PPL is stored in the
-    metadata region reserved for internal write-intent bitmap, so don't
-    allow using bitmap and PPL together.
-    
-    While at it, fix two endianness issues in write_empty_r5l_meta_block()
-    and write_init_super1().
-    
-    Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
-    Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
-
-diff --git a/Assemble.c b/Assemble.c
-index 8e55b49..c098420 100644
---- a/Assemble.c
-+++ b/Assemble.c
-@@ -962,6 +962,9 @@ static int start_array(int mdfd,
- 		c->readonly = 1;
- 	}
- 
-+	if (content->consistency_policy == CONSISTENCY_POLICY_PPL)
-+		clean = 1;
-+
- 	rv = set_array_info(mdfd, st, content);
- 	if (rv && !err_ok) {
- 		pr_err("failed to set array info for %s: %s\n",
-diff --git a/Create.c b/Create.c
-index 4080bf6..10e7d10 100644
---- a/Create.c
-+++ b/Create.c
-@@ -524,6 +524,8 @@ int Create(struct supertype *st, char *mddev,
- 	if (!s->bitmap_file &&
- 	    s->level >= 1 &&
- 	    st->ss->add_internal_bitmap &&
-+	    (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
-+	     s->consistency_policy != CONSISTENCY_POLICY_PPL) &&
- 	    (s->write_behind || s->size > 100*1024*1024ULL)) {
- 		if (c->verbose > 0)
- 			pr_err("automatically enabling write-intent bitmap on large array\n");
-diff --git a/Grow.c b/Grow.c
-index e22661c..a849012 100755
---- a/Grow.c
-+++ b/Grow.c
-@@ -290,6 +290,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
- 	int major = BITMAP_MAJOR_HI;
- 	int vers = md_get_version(fd);
- 	unsigned long long bitmapsize, array_size;
-+	struct mdinfo *mdi;
- 
- 	if (vers < 9003) {
- 		major = BITMAP_MAJOR_HOSTENDIAN;
-@@ -389,12 +390,23 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
- 		free(st);
- 		return 1;
- 	}
-+
-+	mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY);
-+	if (mdi) {
-+		if (mdi->consistency_policy == CONSISTENCY_POLICY_PPL) {
-+			pr_err("Cannot add bitmap to array with PPL\n");
-+			free(mdi);
-+			free(st);
-+			return 1;
-+		}
-+		free(mdi);
-+	}
-+
- 	if (strcmp(s->bitmap_file, "internal") == 0 ||
- 	    strcmp(s->bitmap_file, "clustered") == 0) {
- 		int rv;
- 		int d;
- 		int offset_setable = 0;
--		struct mdinfo *mdi;
- 		if (st->ss->add_internal_bitmap == NULL) {
- 			pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name);
- 			return 1;
-@@ -446,6 +458,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
- 			sysfs_init(mdi, fd, NULL);
- 			rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
- 						  mdi->bitmap_offset);
-+			free(mdi);
- 		} else {
- 			if (strcmp(s->bitmap_file, "clustered") == 0)
- 				array.state |= (1 << MD_SB_CLUSTERED);
-diff --git a/Incremental.c b/Incremental.c
-index 0f507bb..81afc7e 100644
---- a/Incremental.c
-+++ b/Incremental.c
-@@ -528,6 +528,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
- 
- 	journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0);
- 
-+	if (info.consistency_policy == CONSISTENCY_POLICY_PPL)
-+		info.array.state |= 1;
-+
- 	if (enough(info.array.level, info.array.raid_disks,
- 		   info.array.layout, info.array.state & 1,
- 		   avail) == 0) {
-diff --git a/mdadm.h b/mdadm.h
-index d222cc3..2c7066d 100644
---- a/mdadm.h
-+++ b/mdadm.h
-@@ -302,6 +302,7 @@ struct mdinfo {
- 	long			bitmap_offset;	/* 0 == none, 1 == a file */
- 	unsigned int		ppl_size;
- 	unsigned long long	ppl_sector;
-+	int			ppl_offset;
- 	unsigned long		safe_mode_delay; /* ms delay to mark clean */
- 	int			new_level, delta_disks, new_layout, new_chunk;
- 	int			errors;
-diff --git a/super1.c b/super1.c
-index 8df17a1..409b6c3 100644
---- a/super1.c
-+++ b/super1.c
-@@ -48,10 +48,18 @@ struct mdp_superblock_1 {
- 
- 	__u32	chunksize;	/* in 512byte sectors */
- 	__u32	raid_disks;
--	__u32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
--				 * NOTE: signed, so bitmap can be before superblock
--				 * only meaningful of feature_map[0] is set.
--				 */
-+	union {
-+		__u32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
-+					 * NOTE: signed, so bitmap can be before superblock
-+					 * only meaningful of feature_map[0] is set.
-+					 */
-+
-+		/* only meaningful when feature_map[MD_FEATURE_PPL] is set */
-+		struct {
-+			__s16 offset; /* sectors from start of superblock that ppl starts */
-+			__u16 size; /* ppl size in sectors */
-+		} ppl;
-+	};
- 
- 	/* These are only valid with feature bit '4' */
- 	__u32	new_level;	/* new level we are reshaping to		*/
-@@ -131,6 +139,7 @@ struct misc_dev_info {
- #define	MD_FEATURE_NEW_OFFSET		64 /* new_offset must be honoured */
- #define	MD_FEATURE_BITMAP_VERSIONED	256 /* bitmap version number checked properly */
- #define	MD_FEATURE_JOURNAL		512 /* support write journal */
-+#define	MD_FEATURE_PPL			1024 /* support PPL */
- #define	MD_FEATURE_ALL			(MD_FEATURE_BITMAP_OFFSET	\
- 					|MD_FEATURE_RECOVERY_OFFSET	\
- 					|MD_FEATURE_RESHAPE_ACTIVE	\
-@@ -140,6 +149,7 @@ struct misc_dev_info {
- 					|MD_FEATURE_NEW_OFFSET		\
- 					|MD_FEATURE_BITMAP_VERSIONED	\
- 					|MD_FEATURE_JOURNAL		\
-+					|MD_FEATURE_PPL			\
- 					)
- 
- #ifndef MDASSEMBLE
-@@ -289,6 +299,11 @@ static int awrite(struct align_fd *afd, void *buf, int len)
- 	return len;
- }
- 
-+static inline unsigned int choose_ppl_space(int chunk)
-+{
-+	return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2);
-+}
-+
- #ifndef MDASSEMBLE
- static void examine_super1(struct supertype *st, char *homehost)
- {
-@@ -392,6 +407,10 @@ static void examine_super1(struct supertype *st, char *homehost)
- 	if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
- 		printf("Internal Bitmap : %ld sectors from superblock\n",
- 		       (long)(int32_t)__le32_to_cpu(sb->bitmap_offset));
-+	} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
-+		printf("            PPL : %u sectors at offset %d sectors from superblock\n",
-+		       __le16_to_cpu(sb->ppl.size),
-+		       __le16_to_cpu(sb->ppl.offset));
- 	}
- 	if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) {
- 		printf("  Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2,
-@@ -934,10 +953,16 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
- 	if (__le32_to_cpu(bsb->nodes) > 1)
- 		info->array.state |= (1 << MD_SB_CLUSTERED);
- 
-+	super_offset = __le64_to_cpu(sb->super_offset);
- 	info->data_offset = __le64_to_cpu(sb->data_offset);
- 	info->component_size = __le64_to_cpu(sb->size);
--	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET))
-+	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) {
- 		info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset);
-+	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
-+		info->ppl_offset = __le16_to_cpu(sb->ppl.offset);
-+		info->ppl_size = __le16_to_cpu(sb->ppl.size);
-+		info->ppl_sector = super_offset + info->ppl_offset;
-+	}
- 
- 	info->disk.major = 0;
- 	info->disk.minor = 0;
-@@ -948,7 +973,6 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
- 	else
- 		role = __le16_to_cpu(sb->dev_roles[__le32_to_cpu(sb->dev_number)]);
- 
--	super_offset = __le64_to_cpu(sb->super_offset);
- 	if (info->array.level <= 0)
- 		data_size = __le64_to_cpu(sb->data_size);
- 	else
-@@ -965,8 +989,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
- 				end = bboffset;
- 		}
- 
--		if (super_offset + info->bitmap_offset < end)
--			end = super_offset + info->bitmap_offset;
-+		if (super_offset + info->bitmap_offset + info->ppl_offset < end)
-+			end = super_offset + info->bitmap_offset + info->ppl_offset;
- 
- 		if (info->data_offset + data_size < end)
- 			info->space_after = end - data_size - info->data_offset;
-@@ -982,6 +1006,11 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
- 			bmend += size;
- 			if (bmend > earliest)
- 				earliest = bmend;
-+		} else if (info->ppl_offset > 0) {
-+			unsigned long long pplend = info->ppl_offset +
-+						    info->ppl_size;
-+			if (pplend > earliest)
-+				earliest = pplend;
- 		}
- 		if (sb->bblog_offset && sb->bblog_size) {
- 			unsigned long long bbend = super_offset;
-@@ -1075,8 +1104,20 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
- 	}
- 
- 	info->array.working_disks = working;
--	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL))
-+
-+	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) {
- 		info->journal_device_required = 1;
-+		info->consistency_policy = CONSISTENCY_POLICY_JOURNAL;
-+	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
-+		info->consistency_policy = CONSISTENCY_POLICY_PPL;
-+	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) {
-+		info->consistency_policy = CONSISTENCY_POLICY_BITMAP;
-+	} else if (info->array.level <= 0) {
-+		info->consistency_policy = CONSISTENCY_POLICY_NONE;
-+	} else {
-+		info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
-+	}
-+
- 	info->journal_clean = 0;
- }
- 
-@@ -1239,6 +1280,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
- 		if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
- 			bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
- 			bm_sectors = calc_bitmap_size(bms, 4096) >> 9;
-+		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
-+			bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset);
-+			bm_sectors = (long)__le16_to_cpu(sb->ppl.size);
- 		}
- #endif
- 		if (sb_offset < data_offset) {
-@@ -1472,6 +1516,9 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
- 
- 	memset(sb->dev_roles, 0xff, MAX_SB_SIZE - sizeof(struct mdp_superblock_1));
- 
-+	if (s->consistency_policy == CONSISTENCY_POLICY_PPL)
-+		sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL);
-+
- 	return 1;
- }
- 
-@@ -1645,10 +1692,49 @@ static unsigned long choose_bm_space(unsigned long devsize)
- 
- static void free_super1(struct supertype *st);
- 
--#define META_BLOCK_SIZE 4096
-+#ifndef MDASSEMBLE
-+
- __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len);
- 
--#ifndef MDASSEMBLE
-+static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
-+{
-+	struct mdp_superblock_1 *sb = st->sb;
-+	void *buf;
-+	struct ppl_header *ppl_hdr;
-+	int ret;
-+
-+	ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
-+	if (ret) {
-+		pr_err("Failed to allocate PPL header buffer\n");
-+		return ret;
-+	}
-+
-+	memset(buf, 0, PPL_HEADER_SIZE);
-+	ppl_hdr = buf;
-+	memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED);
-+	ppl_hdr->signature = __cpu_to_le32(~crc32c_le(~0, sb->set_uuid,
-+						      sizeof(sb->set_uuid)));
-+	ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE));
-+
-+	if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) {
-+		ret = errno;
-+		perror("Failed to seek to PPL header location");
-+	}
-+
-+	if (!ret && write(fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) {
-+		ret = errno;
-+		perror("Write PPL header failed");
-+	}
-+
-+	if (!ret)
-+		fsync(fd);
-+
-+	free(buf);
-+	return ret;
-+}
-+
-+#define META_BLOCK_SIZE 4096
-+
- static int write_empty_r5l_meta_block(struct supertype *st, int fd)
- {
- 	struct r5l_meta_block *mb;
-@@ -1675,7 +1761,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
- 	crc = crc32c_le(crc, (void *)mb, META_BLOCK_SIZE);
- 	mb->checksum = crc;
- 
--	if (lseek64(fd, (sb->data_offset) * 512, 0) < 0LL) {
-+	if (lseek64(fd, __le64_to_cpu(sb->data_offset) * 512, 0) < 0LL) {
- 		pr_err("cannot seek to offset of the meta block\n");
- 		goto fail_to_write;
- 	}
-@@ -1708,7 +1794,7 @@ static int write_init_super1(struct supertype *st)
- 
- 	for (di = st->info; di; di = di->next) {
- 		if (di->disk.state & (1 << MD_DISK_JOURNAL))
--			sb->feature_map |= MD_FEATURE_JOURNAL;
-+			sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
- 	}
- 
- 	for (di = st->info; di; di = di->next) {
-@@ -1783,6 +1869,21 @@ static int write_init_super1(struct supertype *st)
- 					(((char *)sb) + MAX_SB_SIZE);
- 			bm_space = calc_bitmap_size(bms, 4096) >> 9;
- 			bm_offset = (long)__le32_to_cpu(sb->bitmap_offset);
-+		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
-+			bm_space = choose_ppl_space(__le32_to_cpu(sb->chunksize));
-+			if (bm_space > UINT16_MAX)
-+				bm_space = UINT16_MAX;
-+			if (st->minor_version == 0) {
-+				bm_offset = -bm_space - 8;
-+				if (bm_offset < INT16_MIN) {
-+					bm_offset = INT16_MIN;
-+					bm_space = -bm_offset - 8;
-+				}
-+			} else {
-+				bm_offset = 8;
-+			}
-+			sb->ppl.offset = __cpu_to_le16(bm_offset);
-+			sb->ppl.size = __cpu_to_le16(bm_space);
- 		} else {
- 			bm_space = choose_bm_space(array_size);
- 			bm_offset = 8;
-@@ -1854,8 +1955,17 @@ static int write_init_super1(struct supertype *st)
- 				goto error_out;
- 		}
- 
--		if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
-+		if (rv == 0 &&
-+		    (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) {
- 			rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate);
-+		} else if (rv == 0 &&
-+			 (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) {
-+			struct mdinfo info;
-+
-+			st->ss->getinfo_super(st, &info, NULL);
-+			rv = st->ss->write_init_ppl(st, &info, di->fd);
-+		}
-+
- 		close(di->fd);
- 		di->fd = -1;
- 		if (rv)
-@@ -2123,11 +2233,13 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
- 		return 0;
- 
- #ifndef MDASSEMBLE
--	if (__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
-+	if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) {
- 		/* hot-add. allow for actual size of bitmap */
- 		struct bitmap_super_s *bsb;
- 		bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
- 		bmspace = calc_bitmap_size(bsb, 4096) >> 9;
-+	} else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) {
-+		bmspace = __le16_to_cpu(super->ppl.size);
- 	}
- #endif
- 	/* Allow space for bad block log */
-@@ -2530,8 +2642,9 @@ static int validate_geometry1(struct supertype *st, int level,
- 		return 0;
- 	}
- 
--	/* creating:  allow suitable space for bitmap */
--	bmspace = choose_bm_space(devsize);
-+	/* creating:  allow suitable space for bitmap or PPL */
-+	bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ?
-+		  choose_ppl_space((*chunk)*2) : choose_bm_space(devsize);
- 
- 	if (data_offset == INVALID_SECTORS)
- 		data_offset = st->data_offset;
-@@ -2566,7 +2679,7 @@ static int validate_geometry1(struct supertype *st, int level,
- 	switch(st->minor_version) {
- 	case 0: /* metadata at end.  Round down and subtract space to reserve */
- 		devsize = (devsize & ~(4ULL*2-1));
--		/* space for metadata, bblog, bitmap */
-+		/* space for metadata, bblog, bitmap/ppl */
- 		devsize -= 8*2 + 8 + bmspace;
- 		break;
- 	case 1:
-@@ -2642,6 +2755,7 @@ struct superswitch super1 = {
- 	.add_to_super = add_to_super1,
- 	.examine_badblocks = examine_badblocks_super1,
- 	.copy_metadata = copy_metadata1,
-+	.write_init_ppl = write_init_ppl1,
- #endif
- 	.match_home = match_home1,
- 	.uuid_from_super = uuid_from_super1,
diff --git a/SOURCES/super1-replace-hard-coded-values-with-bit-definition.patch b/SOURCES/super1-replace-hard-coded-values-with-bit-definition.patch
new file mode 100644
index 0000000..2816e3a
--- /dev/null
+++ b/SOURCES/super1-replace-hard-coded-values-with-bit-definition.patch
@@ -0,0 +1,46 @@
+From aa3131183661955de112fa7d9824207de63d9fa5 Mon Sep 17 00:00:00 2001
+From: Gioh Kim <gi-oh.kim@profitbricks.com>
+Date: Wed, 29 Mar 2017 11:40:33 +0200
+Subject: [RHEL7.5 PATCH 032/169] super1: replace hard-coded values with
+ bit definitions
+
+Some hard-coded values for disk status are replaced
+with bit definitions.
+
+Signed-off-by: Gioh Kim <gi-oh.kim@profitbricks.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ super1.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index e76f777..6f91611 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1040,7 +1040,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 		info->disk.state = 0; /* spare: not active, not sync, not faulty */
+ 		break;
+ 	case MD_DISK_ROLE_FAULTY:
+-		info->disk.state = 1; /* faulty */
++		info->disk.state = (1 << MD_DISK_FAULTY); /* faulty */
+ 		break;
+ 	case MD_DISK_ROLE_JOURNAL:
+ 		info->disk.state = (1 << MD_DISK_JOURNAL);
+@@ -1600,11 +1600,12 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
+ 	}
+ 
+ 	dk_state = dk->state & ~(1<<MD_DISK_FAILFAST);
+-	if ((dk_state & 6) == 6) /* active, sync */
++	if ((dk_state & (1<<MD_DISK_ACTIVE)) &&
++	    (dk_state & (1<<MD_DISK_SYNC)))/* active, sync */
+ 		*rp = __cpu_to_le16(dk->raid_disk);
+ 	else if (dk_state & (1<<MD_DISK_JOURNAL))
+                 *rp = MD_DISK_ROLE_JOURNAL;
+-	else if ((dk_state & ~2) == 0) /* active or idle -> spare */
++	else if ((dk_state & ~(1<<MD_DISK_ACTIVE)) == 0) /* active or idle -> spare */
+ 		*rp = MD_DISK_ROLE_SPARE;
+ 	else
+ 		*rp = MD_DISK_ROLE_FAULTY;
+-- 
+2.7.4
+
diff --git a/SOURCES/super1add-support-for-multiple-ppls.patch b/SOURCES/super1add-support-for-multiple-ppls.patch
new file mode 100644
index 0000000..ccf70e7
--- /dev/null
+++ b/SOURCES/super1add-support-for-multiple-ppls.patch
@@ -0,0 +1,194 @@
+From fa601c2e897adfb3d2316377354269ffdeb824c3 Mon Sep 17 00:00:00 2001
+From: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Date: Thu, 28 Sep 2017 14:41:08 +0200
+Subject: [PATCH 02/12] super1: Add support for multiple-ppls
+
+Add support for super1 with multiple ppls. Extend ppl area size to 1MB.
+Use 1MB as default during creation. Always start array as single ppl -
+if kernel is capable of multiple ppls and there is enough space reserved -
+it will switch the policy during first metadata update.
+
+Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
+Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ super1.c | 65 ++++++++++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 37 insertions(+), 28 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index 3cfbbc0..f80e38a 100644
+--- a/super1.c
++++ b/super1.c
+@@ -121,6 +121,9 @@ struct misc_dev_info {
+ 	__u64 device_size;
+ };
+ 
++#define MULTIPLE_PPL_AREA_SIZE_SUPER1 (1024 * 1024) /* Size of the whole
++						     * mutliple PPL area
++						     */
+ /* feature_map bits */
+ #define MD_FEATURE_BITMAP_OFFSET	1
+ #define	MD_FEATURE_RECOVERY_OFFSET	2 /* recovery_offset is present and
+@@ -140,6 +143,7 @@ struct misc_dev_info {
+ #define	MD_FEATURE_BITMAP_VERSIONED	256 /* bitmap version number checked properly */
+ #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_ALL			(MD_FEATURE_BITMAP_OFFSET	\
+ 					|MD_FEATURE_RECOVERY_OFFSET	\
+ 					|MD_FEATURE_RESHAPE_ACTIVE	\
+@@ -150,6 +154,7 @@ struct misc_dev_info {
+ 					|MD_FEATURE_BITMAP_VERSIONED	\
+ 					|MD_FEATURE_JOURNAL		\
+ 					|MD_FEATURE_PPL			\
++					|MD_FEATURE_MULTIPLE_PPLS	\
+ 					)
+ 
+ static int role_from_sb(struct mdp_superblock_1 *sb)
+@@ -298,6 +303,12 @@ static int awrite(struct align_fd *afd, void *buf, int len)
+ 	return len;
+ }
+ 
++static inline unsigned int md_feature_any_ppl_on(__u32 feature_map)
++{
++	return ((__cpu_to_le32(feature_map) &
++	    (MD_FEATURE_PPL | MD_FEATURE_MUTLIPLE_PPLS)));
++}
++
+ static inline unsigned int choose_ppl_space(int chunk)
+ {
+ 	return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2);
+@@ -409,7 +420,7 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ 		printf("Internal Bitmap : %ld sectors from superblock\n",
+ 		       (long)(int32_t)__le32_to_cpu(sb->bitmap_offset));
+-	} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
++	} else if (md_feature_any_ppl_on(sb->feature_map)) {
+ 		printf("            PPL : %u sectors at offset %d sectors from superblock\n",
+ 		       __le16_to_cpu(sb->ppl.size),
+ 		       __le16_to_cpu(sb->ppl.offset));
+@@ -985,7 +996,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 		info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset);
+ 		if (__le32_to_cpu(bsb->nodes) > 1)
+ 			info->array.state |= (1 << MD_SB_CLUSTERED);
+-	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
++	} else if (md_feature_any_ppl_on(sb->feature_map)) {
+ 		info->ppl_offset = __le16_to_cpu(sb->ppl.offset);
+ 		info->ppl_size = __le16_to_cpu(sb->ppl.size);
+ 		info->ppl_sector = super_offset + info->ppl_offset;
+@@ -1140,7 +1151,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) {
+ 		info->journal_device_required = 1;
+ 		info->consistency_policy = CONSISTENCY_POLICY_JOURNAL;
+-	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
++	} else if (md_feature_any_ppl_on(sb->feature_map)) {
+ 		info->consistency_policy = CONSISTENCY_POLICY_PPL;
+ 	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) {
+ 		info->consistency_policy = CONSISTENCY_POLICY_BITMAP;
+@@ -1324,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ 			bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
+ 			bm_sectors = calc_bitmap_size(bms, 4096) >> 9;
+-		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
++		} else if (md_feature_any_ppl_on(sb->feature_map)) {
+ 			bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset);
+ 			bm_sectors = (long)__le16_to_cpu(sb->ppl.size);
+ 		}
+@@ -1377,7 +1388,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		unsigned long long data_size = __le64_to_cpu(sb->data_size);
+ 		long bb_offset = __le32_to_cpu(sb->bblog_offset);
+ 		int space;
+-		int optimal_space;
+ 		int offset;
+ 
+ 		if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+@@ -1408,18 +1418,23 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 			return -2;
+ 		}
+ 
+-		optimal_space = choose_ppl_space(__le32_to_cpu(sb->chunksize));
+-
+-		if (space > optimal_space)
+-			space = optimal_space;
+-		if (space > UINT16_MAX)
+-			space = UINT16_MAX;
++		if (space >= (MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9)) {
++			space = (MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9);
++		} else {
++			int optimal_space = choose_ppl_space(
++						__le32_to_cpu(sb->chunksize));
++			if (space > optimal_space)
++				space = optimal_space;
++			if (space > UINT16_MAX)
++				space = UINT16_MAX;
++		}
+ 
+ 		sb->ppl.offset = __cpu_to_le16(offset);
+ 		sb->ppl.size = __cpu_to_le16(space);
+ 		sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL);
+ 	} else if (strcmp(update, "no-ppl") == 0) {
+-		sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_PPL);
++		sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL |
++						   MD_FEATURE_MUTLIPLE_PPLS);
+ 	} else if (strcmp(update, "name") == 0) {
+ 		if (info->name[0] == 0)
+ 			sprintf(info->name, "%d", info->array.md_minor);
+@@ -1974,20 +1989,12 @@ static int write_init_super1(struct supertype *st)
+ 					(((char *)sb) + MAX_SB_SIZE);
+ 			bm_space = calc_bitmap_size(bms, 4096) >> 9;
+ 			bm_offset = (long)__le32_to_cpu(sb->bitmap_offset);
+-		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
+-			bm_space =
+-			  choose_ppl_space(__le32_to_cpu(sb->chunksize));
+-			if (bm_space > UINT16_MAX)
+-				bm_space = UINT16_MAX;
+-			if (st->minor_version == 0) {
++		} else if (md_feature_any_ppl_on(sb->feature_map)) {
++			bm_space = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9;
++			if (st->minor_version == 0)
+ 				bm_offset = -bm_space - 8;
+-				if (bm_offset < INT16_MIN) {
+-					bm_offset = INT16_MIN;
+-					bm_space = -bm_offset - 8;
+-				}
+-			} else {
++			else
+ 				bm_offset = 8;
+-			}
+ 			sb->ppl.offset = __cpu_to_le16(bm_offset);
+ 			sb->ppl.size = __cpu_to_le16(bm_space);
+ 		} else {
+@@ -2069,7 +2076,7 @@ static int write_init_super1(struct supertype *st)
+ 		     MD_FEATURE_BITMAP_OFFSET)) {
+ 			rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate);
+ 		} else if (rv == 0 &&
+-			 (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) {
++		    md_feature_any_ppl_on(sb->feature_map)) {
+ 			struct mdinfo info;
+ 
+ 			st->ss->getinfo_super(st, &info, NULL);
+@@ -2345,7 +2352,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
+ 		struct bitmap_super_s *bsb;
+ 		bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
+ 		bmspace = calc_bitmap_size(bsb, 4096) >> 9;
+-	} else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) {
++	} else if (md_feature_any_ppl_on(super->feature_map)) {
+ 		bmspace = __le16_to_cpu(super->ppl.size);
+ 	}
+ 
+@@ -2769,8 +2776,10 @@ static int validate_geometry1(struct supertype *st, int level,
+ 	}
+ 
+ 	/* creating:  allow suitable space for bitmap or PPL */
+-	bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ?
+-		  choose_ppl_space((*chunk)*2) : choose_bm_space(devsize);
++	if (consistency_policy == CONSISTENCY_POLICY_PPL)
++		bmspace = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9;
++	else
++		bmspace = choose_bm_space(devsize);
+ 
+ 	if (data_offset == INVALID_SECTORS)
+ 		data_offset = st->data_offset;
+-- 
+2.7.4
+
diff --git a/SOURCES/super1ppl-support.patch b/SOURCES/super1ppl-support.patch
new file mode 100644
index 0000000..665387d
--- /dev/null
+++ b/SOURCES/super1ppl-support.patch
@@ -0,0 +1,430 @@
+commit e97a7cd011345e5dead736de51b33968da49d876
+Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date:   Wed Mar 29 11:54:18 2017 +0200
+
+    super1: PPL support
+    
+    Enable creating and assembling raid5 arrays with PPL for 1.x metadata.
+    
+    When creating, reserve enough space for PPL and store its size and
+    location in the superblock and set MD_FEATURE_PPL bit. Write an initial
+    empty header in the PPL area on each device. PPL is stored in the
+    metadata region reserved for internal write-intent bitmap, so don't
+    allow using bitmap and PPL together.
+    
+    While at it, fix two endianness issues in write_empty_r5l_meta_block()
+    and write_init_super1().
+    
+    Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+    Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+
+diff --git a/Assemble.c b/Assemble.c
+index 8e55b49..c098420 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -962,6 +962,9 @@ static int start_array(int mdfd,
+ 		c->readonly = 1;
+ 	}
+ 
++	if (content->consistency_policy == CONSISTENCY_POLICY_PPL)
++		clean = 1;
++
+ 	rv = set_array_info(mdfd, st, content);
+ 	if (rv && !err_ok) {
+ 		pr_err("failed to set array info for %s: %s\n",
+diff --git a/Create.c b/Create.c
+index 4080bf6..10e7d10 100644
+--- a/Create.c
++++ b/Create.c
+@@ -524,6 +524,8 @@ int Create(struct supertype *st, char *mddev,
+ 	if (!s->bitmap_file &&
+ 	    s->level >= 1 &&
+ 	    st->ss->add_internal_bitmap &&
++	    (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
++	     s->consistency_policy != CONSISTENCY_POLICY_PPL) &&
+ 	    (s->write_behind || s->size > 100*1024*1024ULL)) {
+ 		if (c->verbose > 0)
+ 			pr_err("automatically enabling write-intent bitmap on large array\n");
+diff --git a/Grow.c b/Grow.c
+index e22661c..a849012 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -290,6 +290,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 	int major = BITMAP_MAJOR_HI;
+ 	int vers = md_get_version(fd);
+ 	unsigned long long bitmapsize, array_size;
++	struct mdinfo *mdi;
+ 
+ 	if (vers < 9003) {
+ 		major = BITMAP_MAJOR_HOSTENDIAN;
+@@ -389,12 +390,23 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 		free(st);
+ 		return 1;
+ 	}
++
++	mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY);
++	if (mdi) {
++		if (mdi->consistency_policy == CONSISTENCY_POLICY_PPL) {
++			pr_err("Cannot add bitmap to array with PPL\n");
++			free(mdi);
++			free(st);
++			return 1;
++		}
++		free(mdi);
++	}
++
+ 	if (strcmp(s->bitmap_file, "internal") == 0 ||
+ 	    strcmp(s->bitmap_file, "clustered") == 0) {
+ 		int rv;
+ 		int d;
+ 		int offset_setable = 0;
+-		struct mdinfo *mdi;
+ 		if (st->ss->add_internal_bitmap == NULL) {
+ 			pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name);
+ 			return 1;
+@@ -446,6 +458,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 			sysfs_init(mdi, fd, NULL);
+ 			rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
+ 						  mdi->bitmap_offset);
++			free(mdi);
+ 		} else {
+ 			if (strcmp(s->bitmap_file, "clustered") == 0)
+ 				array.state |= (1 << MD_SB_CLUSTERED);
+diff --git a/Incremental.c b/Incremental.c
+index 0f507bb..81afc7e 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -528,6 +528,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 
+ 	journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0);
+ 
++	if (info.consistency_policy == CONSISTENCY_POLICY_PPL)
++		info.array.state |= 1;
++
+ 	if (enough(info.array.level, info.array.raid_disks,
+ 		   info.array.layout, info.array.state & 1,
+ 		   avail) == 0) {
+diff --git a/mdadm.h b/mdadm.h
+index d222cc3..2c7066d 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -302,6 +302,7 @@ struct mdinfo {
+ 	long			bitmap_offset;	/* 0 == none, 1 == a file */
+ 	unsigned int		ppl_size;
+ 	unsigned long long	ppl_sector;
++	int			ppl_offset;
+ 	unsigned long		safe_mode_delay; /* ms delay to mark clean */
+ 	int			new_level, delta_disks, new_layout, new_chunk;
+ 	int			errors;
+diff --git a/super1.c b/super1.c
+index 8df17a1..409b6c3 100644
+--- a/super1.c
++++ b/super1.c
+@@ -48,10 +48,18 @@ struct mdp_superblock_1 {
+ 
+ 	__u32	chunksize;	/* in 512byte sectors */
+ 	__u32	raid_disks;
+-	__u32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
+-				 * NOTE: signed, so bitmap can be before superblock
+-				 * only meaningful of feature_map[0] is set.
+-				 */
++	union {
++		__u32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
++					 * NOTE: signed, so bitmap can be before superblock
++					 * only meaningful of feature_map[0] is set.
++					 */
++
++		/* only meaningful when feature_map[MD_FEATURE_PPL] is set */
++		struct {
++			__s16 offset; /* sectors from start of superblock that ppl starts */
++			__u16 size; /* ppl size in sectors */
++		} ppl;
++	};
+ 
+ 	/* These are only valid with feature bit '4' */
+ 	__u32	new_level;	/* new level we are reshaping to		*/
+@@ -131,6 +139,7 @@ struct misc_dev_info {
+ #define	MD_FEATURE_NEW_OFFSET		64 /* new_offset must be honoured */
+ #define	MD_FEATURE_BITMAP_VERSIONED	256 /* bitmap version number checked properly */
+ #define	MD_FEATURE_JOURNAL		512 /* support write journal */
++#define	MD_FEATURE_PPL			1024 /* support PPL */
+ #define	MD_FEATURE_ALL			(MD_FEATURE_BITMAP_OFFSET	\
+ 					|MD_FEATURE_RECOVERY_OFFSET	\
+ 					|MD_FEATURE_RESHAPE_ACTIVE	\
+@@ -140,6 +149,7 @@ struct misc_dev_info {
+ 					|MD_FEATURE_NEW_OFFSET		\
+ 					|MD_FEATURE_BITMAP_VERSIONED	\
+ 					|MD_FEATURE_JOURNAL		\
++					|MD_FEATURE_PPL			\
+ 					)
+ 
+ #ifndef MDASSEMBLE
+@@ -289,6 +299,11 @@ static int awrite(struct align_fd *afd, void *buf, int len)
+ 	return len;
+ }
+ 
++static inline unsigned int choose_ppl_space(int chunk)
++{
++	return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2);
++}
++
+ #ifndef MDASSEMBLE
+ static void examine_super1(struct supertype *st, char *homehost)
+ {
+@@ -392,6 +407,10 @@ static void examine_super1(struct supertype *st, char *homehost)
+ 	if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ 		printf("Internal Bitmap : %ld sectors from superblock\n",
+ 		       (long)(int32_t)__le32_to_cpu(sb->bitmap_offset));
++	} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
++		printf("            PPL : %u sectors at offset %d sectors from superblock\n",
++		       __le16_to_cpu(sb->ppl.size),
++		       __le16_to_cpu(sb->ppl.offset));
+ 	}
+ 	if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) {
+ 		printf("  Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2,
+@@ -934,10 +953,16 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	if (__le32_to_cpu(bsb->nodes) > 1)
+ 		info->array.state |= (1 << MD_SB_CLUSTERED);
+ 
++	super_offset = __le64_to_cpu(sb->super_offset);
+ 	info->data_offset = __le64_to_cpu(sb->data_offset);
+ 	info->component_size = __le64_to_cpu(sb->size);
+-	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET))
++	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) {
+ 		info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset);
++	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
++		info->ppl_offset = __le16_to_cpu(sb->ppl.offset);
++		info->ppl_size = __le16_to_cpu(sb->ppl.size);
++		info->ppl_sector = super_offset + info->ppl_offset;
++	}
+ 
+ 	info->disk.major = 0;
+ 	info->disk.minor = 0;
+@@ -948,7 +973,6 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	else
+ 		role = __le16_to_cpu(sb->dev_roles[__le32_to_cpu(sb->dev_number)]);
+ 
+-	super_offset = __le64_to_cpu(sb->super_offset);
+ 	if (info->array.level <= 0)
+ 		data_size = __le64_to_cpu(sb->data_size);
+ 	else
+@@ -965,8 +989,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 				end = bboffset;
+ 		}
+ 
+-		if (super_offset + info->bitmap_offset < end)
+-			end = super_offset + info->bitmap_offset;
++		if (super_offset + info->bitmap_offset + info->ppl_offset < end)
++			end = super_offset + info->bitmap_offset + info->ppl_offset;
+ 
+ 		if (info->data_offset + data_size < end)
+ 			info->space_after = end - data_size - info->data_offset;
+@@ -982,6 +1006,11 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 			bmend += size;
+ 			if (bmend > earliest)
+ 				earliest = bmend;
++		} else if (info->ppl_offset > 0) {
++			unsigned long long pplend = info->ppl_offset +
++						    info->ppl_size;
++			if (pplend > earliest)
++				earliest = pplend;
+ 		}
+ 		if (sb->bblog_offset && sb->bblog_size) {
+ 			unsigned long long bbend = super_offset;
+@@ -1075,8 +1104,20 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
+ 	}
+ 
+ 	info->array.working_disks = working;
+-	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL))
++
++	if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) {
+ 		info->journal_device_required = 1;
++		info->consistency_policy = CONSISTENCY_POLICY_JOURNAL;
++	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) {
++		info->consistency_policy = CONSISTENCY_POLICY_PPL;
++	} else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) {
++		info->consistency_policy = CONSISTENCY_POLICY_BITMAP;
++	} else if (info->array.level <= 0) {
++		info->consistency_policy = CONSISTENCY_POLICY_NONE;
++	} else {
++		info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
++	}
++
+ 	info->journal_clean = 0;
+ }
+ 
+@@ -1239,6 +1280,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
+ 		if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
+ 			bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
+ 			bm_sectors = calc_bitmap_size(bms, 4096) >> 9;
++		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
++			bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset);
++			bm_sectors = (long)__le16_to_cpu(sb->ppl.size);
+ 		}
+ #endif
+ 		if (sb_offset < data_offset) {
+@@ -1472,6 +1516,9 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
+ 
+ 	memset(sb->dev_roles, 0xff, MAX_SB_SIZE - sizeof(struct mdp_superblock_1));
+ 
++	if (s->consistency_policy == CONSISTENCY_POLICY_PPL)
++		sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL);
++
+ 	return 1;
+ }
+ 
+@@ -1645,10 +1692,49 @@ static unsigned long choose_bm_space(unsigned long devsize)
+ 
+ static void free_super1(struct supertype *st);
+ 
+-#define META_BLOCK_SIZE 4096
++#ifndef MDASSEMBLE
++
+ __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len);
+ 
+-#ifndef MDASSEMBLE
++static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
++{
++	struct mdp_superblock_1 *sb = st->sb;
++	void *buf;
++	struct ppl_header *ppl_hdr;
++	int ret;
++
++	ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
++	if (ret) {
++		pr_err("Failed to allocate PPL header buffer\n");
++		return ret;
++	}
++
++	memset(buf, 0, PPL_HEADER_SIZE);
++	ppl_hdr = buf;
++	memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED);
++	ppl_hdr->signature = __cpu_to_le32(~crc32c_le(~0, sb->set_uuid,
++						      sizeof(sb->set_uuid)));
++	ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE));
++
++	if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) {
++		ret = errno;
++		perror("Failed to seek to PPL header location");
++	}
++
++	if (!ret && write(fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) {
++		ret = errno;
++		perror("Write PPL header failed");
++	}
++
++	if (!ret)
++		fsync(fd);
++
++	free(buf);
++	return ret;
++}
++
++#define META_BLOCK_SIZE 4096
++
+ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
+ {
+ 	struct r5l_meta_block *mb;
+@@ -1675,7 +1761,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
+ 	crc = crc32c_le(crc, (void *)mb, META_BLOCK_SIZE);
+ 	mb->checksum = crc;
+ 
+-	if (lseek64(fd, (sb->data_offset) * 512, 0) < 0LL) {
++	if (lseek64(fd, __le64_to_cpu(sb->data_offset) * 512, 0) < 0LL) {
+ 		pr_err("cannot seek to offset of the meta block\n");
+ 		goto fail_to_write;
+ 	}
+@@ -1708,7 +1794,7 @@ static int write_init_super1(struct supertype *st)
+ 
+ 	for (di = st->info; di; di = di->next) {
+ 		if (di->disk.state & (1 << MD_DISK_JOURNAL))
+-			sb->feature_map |= MD_FEATURE_JOURNAL;
++			sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
+ 	}
+ 
+ 	for (di = st->info; di; di = di->next) {
+@@ -1783,6 +1869,21 @@ static int write_init_super1(struct supertype *st)
+ 					(((char *)sb) + MAX_SB_SIZE);
+ 			bm_space = calc_bitmap_size(bms, 4096) >> 9;
+ 			bm_offset = (long)__le32_to_cpu(sb->bitmap_offset);
++		} else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) {
++			bm_space = choose_ppl_space(__le32_to_cpu(sb->chunksize));
++			if (bm_space > UINT16_MAX)
++				bm_space = UINT16_MAX;
++			if (st->minor_version == 0) {
++				bm_offset = -bm_space - 8;
++				if (bm_offset < INT16_MIN) {
++					bm_offset = INT16_MIN;
++					bm_space = -bm_offset - 8;
++				}
++			} else {
++				bm_offset = 8;
++			}
++			sb->ppl.offset = __cpu_to_le16(bm_offset);
++			sb->ppl.size = __cpu_to_le16(bm_space);
+ 		} else {
+ 			bm_space = choose_bm_space(array_size);
+ 			bm_offset = 8;
+@@ -1854,8 +1955,17 @@ static int write_init_super1(struct supertype *st)
+ 				goto error_out;
+ 		}
+ 
+-		if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
++		if (rv == 0 &&
++		    (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) {
+ 			rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate);
++		} else if (rv == 0 &&
++			 (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) {
++			struct mdinfo info;
++
++			st->ss->getinfo_super(st, &info, NULL);
++			rv = st->ss->write_init_ppl(st, &info, di->fd);
++		}
++
+ 		close(di->fd);
+ 		di->fd = -1;
+ 		if (rv)
+@@ -2123,11 +2233,13 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
+ 		return 0;
+ 
+ #ifndef MDASSEMBLE
+-	if (__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
++	if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) {
+ 		/* hot-add. allow for actual size of bitmap */
+ 		struct bitmap_super_s *bsb;
+ 		bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
+ 		bmspace = calc_bitmap_size(bsb, 4096) >> 9;
++	} else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) {
++		bmspace = __le16_to_cpu(super->ppl.size);
+ 	}
+ #endif
+ 	/* Allow space for bad block log */
+@@ -2530,8 +2642,9 @@ static int validate_geometry1(struct supertype *st, int level,
+ 		return 0;
+ 	}
+ 
+-	/* creating:  allow suitable space for bitmap */
+-	bmspace = choose_bm_space(devsize);
++	/* creating:  allow suitable space for bitmap or PPL */
++	bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ?
++		  choose_ppl_space((*chunk)*2) : choose_bm_space(devsize);
+ 
+ 	if (data_offset == INVALID_SECTORS)
+ 		data_offset = st->data_offset;
+@@ -2566,7 +2679,7 @@ static int validate_geometry1(struct supertype *st, int level,
+ 	switch(st->minor_version) {
+ 	case 0: /* metadata at end.  Round down and subtract space to reserve */
+ 		devsize = (devsize & ~(4ULL*2-1));
+-		/* space for metadata, bblog, bitmap */
++		/* space for metadata, bblog, bitmap/ppl */
+ 		devsize -= 8*2 + 8 + bmspace;
+ 		break;
+ 	case 1:
+@@ -2642,6 +2755,7 @@ struct superswitch super1 = {
+ 	.add_to_super = add_to_super1,
+ 	.examine_badblocks = examine_badblocks_super1,
+ 	.copy_metadata = copy_metadata1,
++	.write_init_ppl = write_init_ppl1,
+ #endif
+ 	.match_home = match_home1,
+ 	.uuid_from_super = uuid_from_super1,
diff --git a/SOURCES/support-consistency-policy-change.patch b/SOURCES/support-consistency-policy-change.patch
deleted file mode 100644
index 26861a7..0000000
--- a/SOURCES/support-consistency-policy-change.patch
+++ /dev/null
@@ -1,339 +0,0 @@
-commit 860f11ed4d6a7bac6f2d698a30a13371c0aa7924
-Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
-Date:   Wed Mar 29 11:54:20 2017 +0200
-
-    Grow: support consistency policy change
-    
-    Extend the --consistency-policy parameter to work also in Grow mode.
-    Using it changes the currently active consistency policy in the kernel
-    driver and updates the metadata to make this change permanent. Currently
-    this supports only changing between "ppl" and "resync" policies, that is
-    enabling or disabling PPL at runtime.
-    
-    Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
-    Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
-
-diff --git a/Grow.c b/Grow.c
-index a849012..b86b53e 100755
---- a/Grow.c
-+++ b/Grow.c
-@@ -528,6 +528,178 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
- 	return 0;
- }
- 
-+int Grow_consistency_policy(char *devname, int fd, struct context *c, struct shape *s)
-+{
-+	struct supertype *st;
-+	struct mdinfo *sra;
-+	struct mdinfo *sd;
-+	char *subarray = NULL;
-+	int ret = 0;
-+	char container_dev[PATH_MAX];
-+
-+	if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
-+	    s->consistency_policy != CONSISTENCY_POLICY_PPL) {
-+		pr_err("Operation not supported for consistency policy %s\n",
-+		       map_num(consistency_policies, s->consistency_policy));
-+		return 1;
-+	}
-+
-+	st = super_by_fd(fd, &subarray);
-+	if (!st)
-+		return 1;
-+
-+	sra = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY|GET_LEVEL|
-+				   GET_DEVS|GET_STATE);
-+	if (!sra) {
-+		ret = 1;
-+		goto free_st;
-+	}
-+
-+	if (s->consistency_policy == CONSISTENCY_POLICY_PPL &&
-+	    !st->ss->write_init_ppl) {
-+		pr_err("%s metadata does not support PPL\n", st->ss->name);
-+		ret = 1;
-+		goto free_info;
-+	}
-+
-+	if (sra->array.level != 5) {
-+		pr_err("Operation not supported for array level %d\n",
-+				sra->array.level);
-+		ret = 1;
-+		goto free_info;
-+	}
-+
-+	if (sra->consistency_policy == (unsigned)s->consistency_policy) {
-+		pr_err("Consistency policy is already %s\n",
-+		       map_num(consistency_policies, s->consistency_policy));
-+		ret = 1;
-+		goto free_info;
-+	} else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
-+		   sra->consistency_policy != CONSISTENCY_POLICY_PPL) {
-+		pr_err("Current consistency policy is %s, cannot change to %s\n",
-+		       map_num(consistency_policies, sra->consistency_policy),
-+		       map_num(consistency_policies, s->consistency_policy));
-+		ret = 1;
-+		goto free_info;
-+	}
-+
-+	if (subarray) {
-+		char *update;
-+
-+		if (s->consistency_policy == CONSISTENCY_POLICY_PPL)
-+			update = "ppl";
-+		else
-+			update = "no-ppl";
-+
-+		sprintf(container_dev, "/dev/%s", st->container_devnm);
-+
-+		ret = Update_subarray(container_dev, subarray, update, NULL,
-+				      c->verbose);
-+		if (ret)
-+			goto free_info;
-+	}
-+
-+	if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
-+		struct mdinfo info;
-+
-+		if (subarray) {
-+			struct mdinfo *mdi;
-+			int cfd;
-+
-+			cfd = open(container_dev, O_RDWR|O_EXCL);
-+			if (cfd < 0) {
-+				pr_err("Failed to open %s\n", container_dev);
-+				ret = 1;
-+				goto free_info;
-+			}
-+
-+			ret = st->ss->load_container(st, cfd, st->container_devnm);
-+			close(cfd);
-+
-+			if (ret) {
-+				pr_err("Cannot read superblock for %s\n",
-+				       container_dev);
-+				goto free_info;
-+			}
-+
-+			mdi = st->ss->container_content(st, subarray);
-+			info = *mdi;
-+			free(mdi);
-+		}
-+
-+		for (sd = sra->devs; sd; sd = sd->next) {
-+			int dfd;
-+			char *devpath;
-+
-+			if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0)
-+				continue;
-+
-+			devpath = map_dev(sd->disk.major, sd->disk.minor, 0);
-+			dfd = dev_open(devpath, O_RDWR);
-+			if (dfd < 0) {
-+				pr_err("Failed to open %s\n", devpath);
-+				ret = 1;
-+				goto free_info;
-+			}
-+
-+			if (!subarray) {
-+				ret = st->ss->load_super(st, dfd, NULL);
-+				if (ret) {
-+					pr_err("Failed to load super-block.\n");
-+					close(dfd);
-+					goto free_info;
-+				}
-+
-+				ret = st->ss->update_super(st, sra, "ppl", devname,
-+							   c->verbose, 0, NULL);
-+				if (ret) {
-+					close(dfd);
-+					st->ss->free_super(st);
-+					goto free_info;
-+				}
-+				st->ss->getinfo_super(st, &info, NULL);
-+			}
-+
-+			ret |= sysfs_set_num(sra, sd, "ppl_sector", info.ppl_sector);
-+			ret |= sysfs_set_num(sra, sd, "ppl_size", info.ppl_size);
-+
-+			if (ret) {
-+				pr_err("Failed to set PPL attributes for %s\n",
-+				       sd->sys_name);
-+				close(dfd);
-+				st->ss->free_super(st);
-+				goto free_info;
-+			}
-+
-+			ret = st->ss->write_init_ppl(st, &info, dfd);
-+			if (ret)
-+				pr_err("Failed to write PPL\n");
-+
-+			close(dfd);
-+
-+			if (!subarray)
-+				st->ss->free_super(st);
-+
-+			if (ret)
-+				goto free_info;
-+		}
-+	}
-+
-+	ret = sysfs_set_str(sra, NULL, "consistency_policy",
-+			    map_num(consistency_policies,
-+				    s->consistency_policy));
-+	if (ret)
-+		pr_err("Failed to change array consistency policy\n");
-+
-+free_info:
-+	sysfs_free(sra);
-+free_st:
-+	free(st);
-+	free(subarray);
-+
-+	return ret;
-+}
-+
- /*
-  * When reshaping an array we might need to backup some data.
-  * This is written to all spares with a 'super_block' describing it.
-diff --git a/ReadMe.c b/ReadMe.c
-index fc04c2c..eb8fb4b 100644
---- a/ReadMe.c
-+++ b/ReadMe.c
-@@ -559,28 +559,30 @@ char Help_grow[] =
- "reconfiguration.\n"
- "\n"
- "Options that are valid with the grow (-G --grow) mode are:\n"
--"  --level=       -l   : Tell mdadm what level to convert the array to.\n"
--"  --layout=      -p   : For a FAULTY array, set/change the error mode.\n"
--"                      : for other arrays, update the layout\n"
--"  --size=        -z   : Change the active size of devices in an array.\n"
--"                      : This is useful if all devices have been replaced\n"
--"                      : with larger devices.   Value is in Kilobytes, or\n"
--"                      : the special word 'max' meaning 'as large as possible'.\n"
--"  --assume-clean      : When increasing the --size, this flag will avoid\n"
--"                      : a resync of the new space\n"
--"  --chunk=       -c   : Change the chunksize of the array\n"
--"  --raid-devices= -n  : Change the number of active devices in an array.\n"
--"  --add=         -a   : Add listed devices as part of reshape.  This is\n"
--"                      : needed for resizing a RAID0 which cannot have\n"
--"                      : spares already present.\n"
--"  --bitmap=      -b   : Add or remove a write-intent bitmap.\n"
--"  --backup-file= file : A file on a different device to store data for a\n"
--"                      : short time while increasing raid-devices on a\n"
--"                      : RAID4/5/6 array. Also needed throughout a reshape\n"
--"                      : when changing parameters other than raid-devices\n"
--"  --array-size=  -Z   : Change visible size of array.  This does not change\n"
--"                      : any data on the device, and is not stable across restarts.\n"
--"  --data-offset=      : Location on device to move start of data to.\n"
-+"  --level=           -l : Tell mdadm what level to convert the array to.\n"
-+"  --layout=          -p : For a FAULTY array, set/change the error mode.\n"
-+"                        : for other arrays, update the layout\n"
-+"  --size=            -z : Change the active size of devices in an array.\n"
-+"                        : This is useful if all devices have been replaced\n"
-+"                        : with larger devices.   Value is in Kilobytes, or\n"
-+"                        : the special word 'max' meaning 'as large as possible'.\n"
-+"  --assume-clean        : When increasing the --size, this flag will avoid\n"
-+"                        : a resync of the new space\n"
-+"  --chunk=           -c : Change the chunksize of the array\n"
-+"  --raid-devices=    -n : Change the number of active devices in an array.\n"
-+"  --add=             -a : Add listed devices as part of reshape.  This is\n"
-+"                        : needed for resizing a RAID0 which cannot have\n"
-+"                        : spares already present.\n"
-+"  --bitmap=          -b : Add or remove a write-intent bitmap.\n"
-+"  --backup-file= file   : A file on a different device to store data for a\n"
-+"                        : short time while increasing raid-devices on a\n"
-+"                        : RAID4/5/6 array. Also needed throughout a reshape\n"
-+"                        : when changing parameters other than raid-devices\n"
-+"  --array-size=      -Z : Change visible size of array. This does not change any\n"
-+"                        : data on the device, and is not stable across restarts.\n"
-+"  --data-offset=        : Location on device to move start of data to.\n"
-+"  --consistency-policy= : Change the consistency policy of an active array.\n"
-+"                     -k : Currently works only for PPL with RAID5.\n"
- ;
- 
- char Help_incr[] =
-diff --git a/mdadm.8.in b/mdadm.8.in
-index 1178ed9..744c12b 100644
---- a/mdadm.8.in
-+++ b/mdadm.8.in
-@@ -126,7 +126,7 @@ of component devices and changing the number of active devices in
- Linear and RAID levels 0/1/4/5/6,
- changing the RAID level between 0, 1, 5, and 6, and between 0 and 10,
- changing the chunk size and layout for RAID 0,4,5,6,10 as well as adding or
--removing a write-intent bitmap.
-+removing a write-intent bitmap and changing the array's consistency policy.
- 
- .TP
- .B "Incremental Assembly"
-@@ -1050,6 +1050,10 @@ after unclean shutdown. Implicitly selected when using
- For RAID5 only, Partial Parity Log is used to close the write hole and
- eliminate resync. PPL is stored in the metadata region of RAID member drives,
- no additional journal drive is needed.
-+
-+.PP
-+Can be used with \-\-grow to change the consistency policy of an active array
-+in some cases. See CONSISTENCY POLICY CHANGES below.
- .RE
- 
- 
-@@ -2694,6 +2698,8 @@ RAID0, RAID4, and RAID5, and between RAID0 and RAID10 (in the near-2 mode).
- .IP \(bu 4
- add a write-intent bitmap to any array which supports these bitmaps, or
- remove a write-intent bitmap from such an array.
-+.IP \(bu 4
-+change the array's consistency policy.
- .PP
- 
- Using GROW on containers is currently supported only for Intel's IMSM
-@@ -2850,6 +2856,16 @@ can be added.  Note that if you add a bitmap stored in a file which is
- in a filesystem that is on the RAID array being affected, the system
- will deadlock.  The bitmap must be on a separate filesystem.
- 
-+.SS CONSISTENCY POLICY CHANGES
-+
-+The consistency policy of an active array can be changed by using the
-+.B \-\-consistency\-policy
-+option in Grow mode. Currently this works only for the
-+.B ppl
-+and
-+.B resync
-+policies and allows to enable or disable the RAID5 Partial Parity Log (PPL).
-+
- .SH INCREMENTAL MODE
- 
- .HP 12
-diff --git a/mdadm.c b/mdadm.c
-index 6edf3ab..5ebf117 100644
---- a/mdadm.c
-+++ b/mdadm.c
-@@ -1221,6 +1221,7 @@ int main(int argc, char *argv[])
- 			s.journaldisks = 1;
- 			continue;
- 		case O(CREATE, 'k'):
-+		case O(GROW, 'k'):
- 			s.consistency_policy = map_name(consistency_policies,
- 							optarg);
- 			if (s.consistency_policy == UnSet ||
-@@ -1679,6 +1680,8 @@ int main(int argc, char *argv[])
- 			rv = Grow_reshape(devlist->devname, mdfd,
- 					  devlist->next,
- 					  data_offset, &c, &s);
-+		} else if (s.consistency_policy != UnSet) {
-+			rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
- 		} else if (array_size == 0)
- 			pr_err("no changes to --grow\n");
- 		break;
-diff --git a/mdadm.h b/mdadm.h
-index 2c7066d..4891acf 100644
---- a/mdadm.h
-+++ b/mdadm.h
-@@ -1331,6 +1331,8 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info,
- extern int Grow_continue(int mdfd, struct supertype *st,
- 			 struct mdinfo *info, char *backup_file,
- 			 int forked, int freeze_reshape);
-+extern int Grow_consistency_policy(char *devname, int fd,
-+				   struct context *c, struct shape *s);
- 
- extern int restore_backup(struct supertype *st,
- 			  struct mdinfo *content,
diff --git a/SOURCES/support-consistency-policy1-change.patch b/SOURCES/support-consistency-policy1-change.patch
new file mode 100644
index 0000000..26861a7
--- /dev/null
+++ b/SOURCES/support-consistency-policy1-change.patch
@@ -0,0 +1,339 @@
+commit 860f11ed4d6a7bac6f2d698a30a13371c0aa7924
+Author: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+Date:   Wed Mar 29 11:54:20 2017 +0200
+
+    Grow: support consistency policy change
+    
+    Extend the --consistency-policy parameter to work also in Grow mode.
+    Using it changes the currently active consistency policy in the kernel
+    driver and updates the metadata to make this change permanent. Currently
+    this supports only changing between "ppl" and "resync" policies, that is
+    enabling or disabling PPL at runtime.
+    
+    Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
+    Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+
+diff --git a/Grow.c b/Grow.c
+index a849012..b86b53e 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -528,6 +528,178 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 	return 0;
+ }
+ 
++int Grow_consistency_policy(char *devname, int fd, struct context *c, struct shape *s)
++{
++	struct supertype *st;
++	struct mdinfo *sra;
++	struct mdinfo *sd;
++	char *subarray = NULL;
++	int ret = 0;
++	char container_dev[PATH_MAX];
++
++	if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
++	    s->consistency_policy != CONSISTENCY_POLICY_PPL) {
++		pr_err("Operation not supported for consistency policy %s\n",
++		       map_num(consistency_policies, s->consistency_policy));
++		return 1;
++	}
++
++	st = super_by_fd(fd, &subarray);
++	if (!st)
++		return 1;
++
++	sra = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY|GET_LEVEL|
++				   GET_DEVS|GET_STATE);
++	if (!sra) {
++		ret = 1;
++		goto free_st;
++	}
++
++	if (s->consistency_policy == CONSISTENCY_POLICY_PPL &&
++	    !st->ss->write_init_ppl) {
++		pr_err("%s metadata does not support PPL\n", st->ss->name);
++		ret = 1;
++		goto free_info;
++	}
++
++	if (sra->array.level != 5) {
++		pr_err("Operation not supported for array level %d\n",
++				sra->array.level);
++		ret = 1;
++		goto free_info;
++	}
++
++	if (sra->consistency_policy == (unsigned)s->consistency_policy) {
++		pr_err("Consistency policy is already %s\n",
++		       map_num(consistency_policies, s->consistency_policy));
++		ret = 1;
++		goto free_info;
++	} else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
++		   sra->consistency_policy != CONSISTENCY_POLICY_PPL) {
++		pr_err("Current consistency policy is %s, cannot change to %s\n",
++		       map_num(consistency_policies, sra->consistency_policy),
++		       map_num(consistency_policies, s->consistency_policy));
++		ret = 1;
++		goto free_info;
++	}
++
++	if (subarray) {
++		char *update;
++
++		if (s->consistency_policy == CONSISTENCY_POLICY_PPL)
++			update = "ppl";
++		else
++			update = "no-ppl";
++
++		sprintf(container_dev, "/dev/%s", st->container_devnm);
++
++		ret = Update_subarray(container_dev, subarray, update, NULL,
++				      c->verbose);
++		if (ret)
++			goto free_info;
++	}
++
++	if (s->consistency_policy == CONSISTENCY_POLICY_PPL) {
++		struct mdinfo info;
++
++		if (subarray) {
++			struct mdinfo *mdi;
++			int cfd;
++
++			cfd = open(container_dev, O_RDWR|O_EXCL);
++			if (cfd < 0) {
++				pr_err("Failed to open %s\n", container_dev);
++				ret = 1;
++				goto free_info;
++			}
++
++			ret = st->ss->load_container(st, cfd, st->container_devnm);
++			close(cfd);
++
++			if (ret) {
++				pr_err("Cannot read superblock for %s\n",
++				       container_dev);
++				goto free_info;
++			}
++
++			mdi = st->ss->container_content(st, subarray);
++			info = *mdi;
++			free(mdi);
++		}
++
++		for (sd = sra->devs; sd; sd = sd->next) {
++			int dfd;
++			char *devpath;
++
++			if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0)
++				continue;
++
++			devpath = map_dev(sd->disk.major, sd->disk.minor, 0);
++			dfd = dev_open(devpath, O_RDWR);
++			if (dfd < 0) {
++				pr_err("Failed to open %s\n", devpath);
++				ret = 1;
++				goto free_info;
++			}
++
++			if (!subarray) {
++				ret = st->ss->load_super(st, dfd, NULL);
++				if (ret) {
++					pr_err("Failed to load super-block.\n");
++					close(dfd);
++					goto free_info;
++				}
++
++				ret = st->ss->update_super(st, sra, "ppl", devname,
++							   c->verbose, 0, NULL);
++				if (ret) {
++					close(dfd);
++					st->ss->free_super(st);
++					goto free_info;
++				}
++				st->ss->getinfo_super(st, &info, NULL);
++			}
++
++			ret |= sysfs_set_num(sra, sd, "ppl_sector", info.ppl_sector);
++			ret |= sysfs_set_num(sra, sd, "ppl_size", info.ppl_size);
++
++			if (ret) {
++				pr_err("Failed to set PPL attributes for %s\n",
++				       sd->sys_name);
++				close(dfd);
++				st->ss->free_super(st);
++				goto free_info;
++			}
++
++			ret = st->ss->write_init_ppl(st, &info, dfd);
++			if (ret)
++				pr_err("Failed to write PPL\n");
++
++			close(dfd);
++
++			if (!subarray)
++				st->ss->free_super(st);
++
++			if (ret)
++				goto free_info;
++		}
++	}
++
++	ret = sysfs_set_str(sra, NULL, "consistency_policy",
++			    map_num(consistency_policies,
++				    s->consistency_policy));
++	if (ret)
++		pr_err("Failed to change array consistency policy\n");
++
++free_info:
++	sysfs_free(sra);
++free_st:
++	free(st);
++	free(subarray);
++
++	return ret;
++}
++
+ /*
+  * When reshaping an array we might need to backup some data.
+  * This is written to all spares with a 'super_block' describing it.
+diff --git a/ReadMe.c b/ReadMe.c
+index fc04c2c..eb8fb4b 100644
+--- a/ReadMe.c
++++ b/ReadMe.c
+@@ -559,28 +559,30 @@ char Help_grow[] =
+ "reconfiguration.\n"
+ "\n"
+ "Options that are valid with the grow (-G --grow) mode are:\n"
+-"  --level=       -l   : Tell mdadm what level to convert the array to.\n"
+-"  --layout=      -p   : For a FAULTY array, set/change the error mode.\n"
+-"                      : for other arrays, update the layout\n"
+-"  --size=        -z   : Change the active size of devices in an array.\n"
+-"                      : This is useful if all devices have been replaced\n"
+-"                      : with larger devices.   Value is in Kilobytes, or\n"
+-"                      : the special word 'max' meaning 'as large as possible'.\n"
+-"  --assume-clean      : When increasing the --size, this flag will avoid\n"
+-"                      : a resync of the new space\n"
+-"  --chunk=       -c   : Change the chunksize of the array\n"
+-"  --raid-devices= -n  : Change the number of active devices in an array.\n"
+-"  --add=         -a   : Add listed devices as part of reshape.  This is\n"
+-"                      : needed for resizing a RAID0 which cannot have\n"
+-"                      : spares already present.\n"
+-"  --bitmap=      -b   : Add or remove a write-intent bitmap.\n"
+-"  --backup-file= file : A file on a different device to store data for a\n"
+-"                      : short time while increasing raid-devices on a\n"
+-"                      : RAID4/5/6 array. Also needed throughout a reshape\n"
+-"                      : when changing parameters other than raid-devices\n"
+-"  --array-size=  -Z   : Change visible size of array.  This does not change\n"
+-"                      : any data on the device, and is not stable across restarts.\n"
+-"  --data-offset=      : Location on device to move start of data to.\n"
++"  --level=           -l : Tell mdadm what level to convert the array to.\n"
++"  --layout=          -p : For a FAULTY array, set/change the error mode.\n"
++"                        : for other arrays, update the layout\n"
++"  --size=            -z : Change the active size of devices in an array.\n"
++"                        : This is useful if all devices have been replaced\n"
++"                        : with larger devices.   Value is in Kilobytes, or\n"
++"                        : the special word 'max' meaning 'as large as possible'.\n"
++"  --assume-clean        : When increasing the --size, this flag will avoid\n"
++"                        : a resync of the new space\n"
++"  --chunk=           -c : Change the chunksize of the array\n"
++"  --raid-devices=    -n : Change the number of active devices in an array.\n"
++"  --add=             -a : Add listed devices as part of reshape.  This is\n"
++"                        : needed for resizing a RAID0 which cannot have\n"
++"                        : spares already present.\n"
++"  --bitmap=          -b : Add or remove a write-intent bitmap.\n"
++"  --backup-file= file   : A file on a different device to store data for a\n"
++"                        : short time while increasing raid-devices on a\n"
++"                        : RAID4/5/6 array. Also needed throughout a reshape\n"
++"                        : when changing parameters other than raid-devices\n"
++"  --array-size=      -Z : Change visible size of array. This does not change any\n"
++"                        : data on the device, and is not stable across restarts.\n"
++"  --data-offset=        : Location on device to move start of data to.\n"
++"  --consistency-policy= : Change the consistency policy of an active array.\n"
++"                     -k : Currently works only for PPL with RAID5.\n"
+ ;
+ 
+ char Help_incr[] =
+diff --git a/mdadm.8.in b/mdadm.8.in
+index 1178ed9..744c12b 100644
+--- a/mdadm.8.in
++++ b/mdadm.8.in
+@@ -126,7 +126,7 @@ of component devices and changing the number of active devices in
+ Linear and RAID levels 0/1/4/5/6,
+ changing the RAID level between 0, 1, 5, and 6, and between 0 and 10,
+ changing the chunk size and layout for RAID 0,4,5,6,10 as well as adding or
+-removing a write-intent bitmap.
++removing a write-intent bitmap and changing the array's consistency policy.
+ 
+ .TP
+ .B "Incremental Assembly"
+@@ -1050,6 +1050,10 @@ after unclean shutdown. Implicitly selected when using
+ For RAID5 only, Partial Parity Log is used to close the write hole and
+ eliminate resync. PPL is stored in the metadata region of RAID member drives,
+ no additional journal drive is needed.
++
++.PP
++Can be used with \-\-grow to change the consistency policy of an active array
++in some cases. See CONSISTENCY POLICY CHANGES below.
+ .RE
+ 
+ 
+@@ -2694,6 +2698,8 @@ RAID0, RAID4, and RAID5, and between RAID0 and RAID10 (in the near-2 mode).
+ .IP \(bu 4
+ add a write-intent bitmap to any array which supports these bitmaps, or
+ remove a write-intent bitmap from such an array.
++.IP \(bu 4
++change the array's consistency policy.
+ .PP
+ 
+ Using GROW on containers is currently supported only for Intel's IMSM
+@@ -2850,6 +2856,16 @@ can be added.  Note that if you add a bitmap stored in a file which is
+ in a filesystem that is on the RAID array being affected, the system
+ will deadlock.  The bitmap must be on a separate filesystem.
+ 
++.SS CONSISTENCY POLICY CHANGES
++
++The consistency policy of an active array can be changed by using the
++.B \-\-consistency\-policy
++option in Grow mode. Currently this works only for the
++.B ppl
++and
++.B resync
++policies and allows to enable or disable the RAID5 Partial Parity Log (PPL).
++
+ .SH INCREMENTAL MODE
+ 
+ .HP 12
+diff --git a/mdadm.c b/mdadm.c
+index 6edf3ab..5ebf117 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1221,6 +1221,7 @@ int main(int argc, char *argv[])
+ 			s.journaldisks = 1;
+ 			continue;
+ 		case O(CREATE, 'k'):
++		case O(GROW, 'k'):
+ 			s.consistency_policy = map_name(consistency_policies,
+ 							optarg);
+ 			if (s.consistency_policy == UnSet ||
+@@ -1679,6 +1680,8 @@ int main(int argc, char *argv[])
+ 			rv = Grow_reshape(devlist->devname, mdfd,
+ 					  devlist->next,
+ 					  data_offset, &c, &s);
++		} else if (s.consistency_policy != UnSet) {
++			rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
+ 		} else if (array_size == 0)
+ 			pr_err("no changes to --grow\n");
+ 		break;
+diff --git a/mdadm.h b/mdadm.h
+index 2c7066d..4891acf 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1331,6 +1331,8 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info,
+ extern int Grow_continue(int mdfd, struct supertype *st,
+ 			 struct mdinfo *info, char *backup_file,
+ 			 int forked, int freeze_reshape);
++extern int Grow_consistency_policy(char *devname, int fd,
++				   struct context *c, struct shape *s);
+ 
+ extern int restore_backup(struct supertype *st,
+ 			  struct mdinfo *content,
diff --git a/SOURCES/sysfs-Make-sysfs_init-return-an-error-code.patch b/SOURCES/sysfs-Make-sysfs_init-return-an-error-code.patch
new file mode 100644
index 0000000..f9c94fd
--- /dev/null
+++ b/SOURCES/sysfs-Make-sysfs_init-return-an-error-code.patch
@@ -0,0 +1,332 @@
+From dae131379f9fd82e2867aed25a3ff719f957e9a3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Thu, 30 Mar 2017 16:52:37 -0400
+Subject: [RHEL7.5 PATCH 048/169] sysfs: Make sysfs_init() return an error
+ code
+
+Rather than have the caller inspect the returned content, return an
+error code from sysfs_init(). In addition make all callers actually
+check it.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Assemble.c    | 12 ++++++++++--
+ Create.c      | 10 ++++++++--
+ Grow.c        | 39 +++++++++++++++++++++++++++++++++------
+ Incremental.c | 12 ++++++++++--
+ Manage.c      |  7 +++++--
+ Monitor.c     |  4 +++-
+ mdadm.c       | 11 ++++++++---
+ mdadm.h       |  2 +-
+ sysfs.c       | 16 ++++++++++------
+ 9 files changed, 88 insertions(+), 25 deletions(-)
+
+diff --git a/Assemble.c b/Assemble.c
+index 6a6a56b..672cd12 100644
+--- a/Assemble.c
++++ b/Assemble.c
+@@ -1670,7 +1670,12 @@ try_again:
+ 	}
+ 	st->ss->getinfo_super(st, content, NULL);
+ #ifndef MDASSEMBLE
+-	sysfs_init(content, mdfd, NULL);
++	if (sysfs_init(content, mdfd, NULL)) {
++		pr_err("Unable to initialize sysfs\n");
++		close(mdfd);
++		free(devices);
++		return 1;
++	}
+ #endif
+ 	/* after reload context, store journal_clean in context */
+ 	content->journal_clean = journal_clean;
+@@ -1885,7 +1890,10 @@ int assemble_container_content(struct supertype *st, int mdfd,
+ 	char *avail;
+ 	int err;
+ 
+-	sysfs_init(content, mdfd, NULL);
++	if (sysfs_init(content, mdfd, NULL)) {
++		pr_err("Unable to initialize sysfs\n");
++		return 1;
++	}
+ 
+ 	sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS);
+ 	if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) {
+diff --git a/Create.c b/Create.c
+index 0e0778f..32987af 100644
+--- a/Create.c
++++ b/Create.c
+@@ -737,7 +737,10 @@ int Create(struct supertype *st, char *mddev,
+ 
+ 	total_slots = info.array.nr_disks;
+ 	st->ss->getinfo_super(st, &info, NULL);
+-	sysfs_init(&info, mdfd, NULL);
++	if (sysfs_init(&info, mdfd, NULL)) {
++		pr_err("unable to initialize sysfs\n");
++		goto abort_locked;
++	}
+ 
+ 	if (did_default && c->verbose >= 0) {
+ 		if (is_subarray(info.text_version)) {
+@@ -794,7 +797,10 @@ int Create(struct supertype *st, char *mddev,
+ 		s->bitmap_file = NULL;
+ 	}
+ 
+-	sysfs_init(&info, mdfd, NULL);
++	if (sysfs_init(&info, mdfd, NULL)) {
++		pr_err("unable to initialize sysfs\n");
++		goto abort_locked;
++	}
+ 
+ 	if (st->ss->external && st->container_devnm[0]) {
+ 		/* member */
+diff --git a/Grow.c b/Grow.c
+index 0c16d5b..78a3474 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -455,7 +455,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 		}
+ 		if (offset_setable) {
+ 			st->ss->getinfo_super(st, mdi, NULL);
+-			sysfs_init(mdi, fd, NULL);
++			if (sysfs_init(mdi, fd, NULL)) {
++				pr_err("failed to intialize sysfs.\n");
++				free(mdi);
++			}
+ 			rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
+ 						  mdi->bitmap_offset);
+ 			free(mdi);
+@@ -2149,7 +2152,11 @@ size_change_error:
+ 
+ 	memset(&info, 0, sizeof(info));
+ 	info.array = array;
+-	sysfs_init(&info, fd, NULL);
++	if (sysfs_init(&info, fd, NULL)) {
++		pr_err("failed to intialize sysfs.\n");
++		rv = 1;
++		goto release;
++	}
+ 	strcpy(info.text_version, sra->text_version);
+ 	info.component_size = s->size*2;
+ 	info.new_level = s->level;
+@@ -2870,7 +2877,11 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 	char *c;
+ 	struct mdu_array_info_s array;
+ 	struct mdinfo info;
+-	sysfs_init(&info, fd, NULL);
++
++	if (sysfs_init(&info, fd, NULL)) {
++		pr_err("failed to intialize sysfs.\n");
++		return  1;
++	}
+ 
+ 	md_get_array_info(fd, &array);
+ 	if (level == 0 &&
+@@ -3178,7 +3189,12 @@ static int reshape_array(char *container, int fd, char *devname,
+ 		struct mdinfo *d;
+ 
+ 		if (info2) {
+-			sysfs_init(info2, fd, st->devnm);
++			if (sysfs_init(info2, fd, st->devnm)) {
++				pr_err("unable to initialize sysfs for %s",
++				       st->devnm);
++				free(info2);
++				goto release;
++			}
+ 			/* When increasing number of devices, we need to set
+ 			 * new raid_disks before adding these, or they might
+ 			 * be rejected.
+@@ -3777,7 +3793,12 @@ int reshape_container(char *container, char *devname,
+ 		}
+ 		strcpy(last_devnm, mdstat->devnm);
+ 
+-		sysfs_init(content, fd, mdstat->devnm);
++		if (sysfs_init(content, fd, mdstat->devnm)) {
++			pr_err("Unable to initialize sysfs for %s\n",
++			       mdstat->devnm);
++			rv = 1;
++			break;
++		}
+ 
+ 		if (mdmon_running(container))
+ 			flush_mdmon(container);
+@@ -5110,7 +5131,13 @@ int Grow_continue_command(char *devname, int fd,
+ 			goto Grow_continue_command_exit;
+ 		}
+ 
+-		sysfs_init(content, fd2, mdstat->devnm);
++		if (sysfs_init(content, fd2, mdstat->devnm)) {
++			pr_err("Unable to initialize sysfs for %s, Grow cannot continue",
++			       mdstat->devnm);
++			ret_val = 1;
++			close(fd2);
++			goto Grow_continue_command_exit;
++		}
+ 
+ 		close(fd2);
+ 
+diff --git a/Incremental.c b/Incremental.c
+index 802e525..28f1f77 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -326,7 +326,12 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		if (mdfd < 0)
+ 			goto out_unlock;
+ 
+-		sysfs_init(&info, mdfd, NULL);
++		if (sysfs_init(&info, mdfd, NULL)) {
++			pr_err("unable to initialize sysfs for %s\n",
++			       chosen_name);
++			rv = 2;
++			goto out_unlock;
++		}
+ 
+ 		if (set_array_info(mdfd, st, &info) != 0) {
+ 			pr_err("failed to set array info for %s: %s\n",
+@@ -1734,7 +1739,10 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
+ 			pr_err("%s does not appear to be a component of any array\n", devname);
+ 		return 1;
+ 	}
+-	sysfs_init(&mdi, -1, ent->devnm);
++	if (sysfs_init(&mdi, -1, ent->devnm)) {
++		pr_err("unable to initialize sysfs for: %s\n", devname);
++		return 1;
++	}
+ 	mdfd = open_dev_excl(ent->devnm);
+ 	if (mdfd > 0) {
+ 		close(mdfd);
+diff --git a/Manage.c b/Manage.c
+index 0ffb6c6..618c98b 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -1382,12 +1382,15 @@ int Manage_subdevs(char *devname, int fd,
+ 	int busy = 0;
+ 	int raid_slot = -1;
+ 
++	if (sysfs_init(&info, fd, NULL)) {
++		pr_err("sysfs not availabile for %s\n", devname);
++		goto abort;
++	}
++
+ 	if (md_get_array_info(fd, &array)) {
+ 		pr_err("Cannot get array info for %s\n", devname);
+ 		goto abort;
+ 	}
+-	sysfs_init(&info, fd, NULL);
+-
+ 	/* array.size is only 32 bits and may be truncated.
+ 	 * So read from sysfs if possible, and record number of sectors
+ 	 */
+diff --git a/Monitor.c b/Monitor.c
+index 2c0f717..036a561 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -1026,7 +1026,9 @@ int Wait(char *dev)
+ 			 */
+ 			struct mdinfo mdi;
+ 			char buf[21];
+-			sysfs_init(&mdi, -1, devnm);
++
++			if (sysfs_init(&mdi, -1, devnm))
++				return 2;
+ 			if (sysfs_get_str(&mdi, NULL, "sync_action",
+ 					  buf, 20) > 0 &&
+ 			    strcmp(buf,"idle\n") != 0) {
+diff --git a/mdadm.c b/mdadm.c
+index d6b5437..3fe17fc 100644
+--- a/mdadm.c
++++ b/mdadm.c
+@@ -1631,7 +1631,10 @@ int main(int argc, char *argv[])
+ 				rv = 1;
+ 				break;
+ 			}
+-			sysfs_init(&sra, mdfd, NULL);
++			if (sysfs_init(&sra, mdfd, NULL)) {
++				rv = 1;
++				break;
++			}
+ 			if (array_size == MAX_SIZE)
+ 				err = sysfs_set_str(&sra, NULL, "array_size", "default");
+ 			else
+@@ -1998,13 +2001,15 @@ int SetAction(char *dev, char *action)
+ {
+ 	int fd = open(dev, O_RDONLY);
+ 	struct mdinfo mdi;
++	int retval;
++
+ 	if (fd < 0) {
+ 		pr_err("Couldn't open %s: %s\n", dev, strerror(errno));
+ 		return 1;
+ 	}
+-	sysfs_init(&mdi, fd, NULL);
++	retval = sysfs_init(&mdi, fd, NULL);
+ 	close(fd);
+-	if (!mdi.sys_name[0]) {
++	if (retval) {
+ 		pr_err("%s is no an md array\n", dev);
+ 		return 1;
+ 	}
+diff --git a/mdadm.h b/mdadm.h
+index 084bc97..612bd86 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -639,7 +639,7 @@ enum sysfs_read_flags {
+  * else use devnm.
+  */
+ extern int sysfs_open(char *devnm, char *devname, char *attr);
+-extern void sysfs_init(struct mdinfo *mdi, int fd, char *devnm);
++extern int sysfs_init(struct mdinfo *mdi, int fd, char *devnm);
+ extern void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid);
+ extern void sysfs_free(struct mdinfo *sra);
+ extern struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options);
+diff --git a/sysfs.c b/sysfs.c
+index 93ec3de..51deb23 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -84,25 +84,30 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid)
+ 		 sizeof(mdi->sys_name), "dev-%s", devid2kname(devid));
+ }
+ 
+-void sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
++int sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
+ {
+ 	struct stat stb;
+ 	char fname[MAX_SYSFS_PATH_LEN];
++	int retval = -ENODEV;
+ 
+ 	mdi->sys_name[0] = 0;
+ 	if (fd >= 0)
+ 		devnm = fd2devnm(fd);
+ 
+ 	if (devnm == NULL)
+-		return;
++		goto out;
+ 
+ 	snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm);
+ 
+ 	if (stat(fname, &stb))
+-		return;
++		goto out;
+ 	if (!S_ISDIR(stb.st_mode))
+-		return;
++		goto out;
+ 	strcpy(mdi->sys_name, devnm);
++
++	retval = 0;
++out:
++	return retval;
+ }
+ 
+ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+@@ -117,8 +122,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 	struct dirent *de;
+ 
+ 	sra = xcalloc(1, sizeof(*sra));
+-	sysfs_init(sra, fd, devnm);
+-	if (sra->sys_name[0] == 0) {
++	if (sysfs_init(sra, fd, devnm)) {
+ 		free(sra);
+ 		return NULL;
+ 	}
+-- 
+2.7.4
+
diff --git a/SOURCES/sysfs-Parse-array_state-in-sysfs_read.patch b/SOURCES/sysfs-Parse-array_state-in-sysfs_read.patch
new file mode 100644
index 0000000..212b6d1
--- /dev/null
+++ b/SOURCES/sysfs-Parse-array_state-in-sysfs_read.patch
@@ -0,0 +1,116 @@
+From 5e4ca8bb82e98400c9258cb3d7e4d030576f21df Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 19 Apr 2017 23:27:58 -0400
+Subject: [RHEL7.5 PATCH 081/169] sysfs: Parse array_state in sysfs_read()
+
+Rather than copying in the array_state string, parse it and use an
+enum to indicate the state.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Manage.c |  2 +-
+ maps.c   | 17 +++++++++++++++++
+ mdadm.h  | 17 ++++++++++++++---
+ sysfs.c  |  9 +++++----
+ 4 files changed, 37 insertions(+), 8 deletions(-)
+
+diff --git a/Manage.c b/Manage.c
+index bb84d28..8966e33 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -929,7 +929,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 			return -1;
+ 		}
+ 
+-		if (strncmp(mdp->sysfs_array_state, "readonly", 8) != 0) {
++		if (mdp->array_state != ARRAY_READONLY) {
+ 			sysfs_free(mdp);
+ 			pr_err("%s is not readonly, cannot add journal.\n", devname);
+ 			return -1;
+diff --git a/maps.c b/maps.c
+index d9ee7de..a8a4639 100644
+--- a/maps.c
++++ b/maps.c
+@@ -139,6 +139,23 @@ mapping_t consistency_policies[] = {
+ 	{ NULL, 0}
+ };
+ 
++mapping_t sysfs_array_states[] = {
++	/*
++	 * Beware map_name() uses strcmp() so active-idle must come before
++	 * active, to be detected correctly.
++	 */
++	{ "active-idle", ARRAY_ACTIVE_IDLE },
++	{ "active", ARRAY_ACTIVE },
++	{ "clear", ARRAY_CLEAR },
++	{ "inactive", ARRAY_INACTIVE },
++	{ "suspended", ARRAY_SUSPENDED },
++	{ "readonly", ARRAY_READONLY },
++	{ "read-auto", ARRAY_READ_AUTO },
++	{ "clean", ARRAY_CLEAN },
++	{ "write-pending", ARRAY_WRITE_PENDING },
++	{ NULL, 0 }
++};
++
+ char *map_num(mapping_t *map, int num)
+ {
+ 	while (map->name) {
+diff --git a/mdadm.h b/mdadm.h
+index f1f643c..a379973 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -335,8 +335,18 @@ struct mdinfo {
+ 	int prev_state, curr_state, next_state;
+ 
+ 	/* info read from sysfs */
+-	char		sysfs_array_state[20];
+-
++	enum {
++		ARRAY_CLEAR,
++		ARRAY_INACTIVE,
++		ARRAY_SUSPENDED,
++		ARRAY_READONLY,
++		ARRAY_READ_AUTO,
++		ARRAY_CLEAN,
++		ARRAY_ACTIVE,
++		ARRAY_WRITE_PENDING,
++		ARRAY_ACTIVE_IDLE,
++		ARRAY_UNKNOWN_STATE,
++	} array_state;
+ 	struct md_bb bb;
+ };
+ 
+@@ -716,7 +726,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[], consistency_policies[];
++extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
++extern mapping_t consistency_policies[], sysfs_array_states[];
+ 
+ extern char *map_dev_preferred(int major, int minor, int create,
+ 			       char *prefer);
+diff --git a/sysfs.c b/sysfs.c
+index 51deb23..c6df9b0 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -247,11 +247,12 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 
+ 	if (options & GET_ARRAY_STATE) {
+ 		strcpy(base, "array_state");
+-		if (load_sys(fname, sra->sysfs_array_state,
+-			     sizeof(sra->sysfs_array_state)))
++		if (load_sys(fname, buf, sizeof(buf)))
+ 			goto abort;
+-	} else
+-		sra->sysfs_array_state[0] = 0;
++		sra->array_state = map_name(sysfs_array_states, buf);
++		if (sra->array_state == UnSet)
++			sra->array_state = ARRAY_UNKNOWN_STATE;
++	}
+ 
+ 	if (options & GET_CONSISTENCY_POLICY) {
+ 		strcpy(base, "consistency_policy");
+-- 
+2.7.4
+
diff --git a/SOURCES/sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch b/SOURCES/sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch
new file mode 100644
index 0000000..a8c172b
--- /dev/null
+++ b/SOURCES/sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch
@@ -0,0 +1,51 @@
+From 67a02d520085b01a1b9e6ea59fb30e79c5649c9c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Thu, 30 Mar 2017 16:02:36 -0400
+Subject: [RHEL7.5 PATCH 047/169] sysfs: Use the presence of
+ /sys/block/<dev>/md as indicator of valid device
+
+Rather than calling ioctl(RAID_VERSION), use the presence of
+/sys/block/<dev>/md as indicator of the device being valid and sysfs
+being active for it. The ioctl could return valid data, but sysfs
+not mounted, which renders sysfs_init() useless anyway.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ sysfs.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/sysfs.c b/sysfs.c
+index 2a91ba0..93ec3de 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -86,15 +86,22 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid)
+ 
+ void sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
+ {
++	struct stat stb;
++	char fname[MAX_SYSFS_PATH_LEN];
++
+ 	mdi->sys_name[0] = 0;
+-	if (fd >= 0) {
+-		mdu_version_t vers;
+-		if (ioctl(fd, RAID_VERSION, &vers) != 0)
+-			return;
++	if (fd >= 0)
+ 		devnm = fd2devnm(fd);
+-	}
++
+ 	if (devnm == NULL)
+ 		return;
++
++	snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm);
++
++	if (stat(fname, &stb))
++		return;
++	if (!S_ISDIR(stb.st_mode))
++		return;
+ 	strcpy(mdi->sys_name, devnm);
+ }
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch b/SOURCES/sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch
new file mode 100644
index 0000000..acc5a0a
--- /dev/null
+++ b/SOURCES/sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch
@@ -0,0 +1,47 @@
+From 64ec81da7a70adcdc0dbccaacc69aaf90edb4011 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 5 May 2017 11:51:43 -0400
+Subject: [RHEL7.5 PATCH 113/169] sysfs/sysfs_read: Count active_disks and
+ failed_disks
+
+Cound active_disks as drives mark 'in_sync' and failed_disks as
+disks marked 'faulty', in the same way ioctl(GET_ARRAY_INFO) does.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ sysfs.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/sysfs.c b/sysfs.c
+index aa30de5..f7967e8 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -270,6 +270,8 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 	if (!dir)
+ 		goto abort;
+ 	sra->array.spare_disks = 0;
++	sra->array.active_disks = 0;
++	sra->array.failed_disks = 0;
+ 
+ 	devp = &sra->devs;
+ 	sra->devs = NULL;
+@@ -356,10 +358,14 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 			strcpy(dbase, "state");
+ 			if (load_sys(fname, buf, sizeof(buf)))
+ 				goto abort;
+-			if (strstr(buf, "in_sync"))
++			if (strstr(buf, "in_sync")) {
+ 				dev->disk.state |= (1<<MD_DISK_SYNC);
+-			if (strstr(buf, "faulty"))
++				sra->array.active_disks++;
++			}
++			if (strstr(buf, "faulty")) {
+ 				dev->disk.state |= (1<<MD_DISK_FAULTY);
++				sra->array.failed_disks++;
++			}
+ 			if (dev->disk.state == 0)
+ 				sra->array.spare_disks++;
+ 		}
+-- 
+2.7.4
+
diff --git a/SOURCES/sysfs-sysfs_read-Count-workingdisks.patch b/SOURCES/sysfs-sysfs_read-Count-workingdisks.patch
new file mode 100644
index 0000000..2c75429
--- /dev/null
+++ b/SOURCES/sysfs-sysfs_read-Count-workingdisks.patch
@@ -0,0 +1,53 @@
+From 8b0ebd645202b627982eb3ed9fc72583c4f245d3 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Tue, 9 May 2017 17:09:40 -0400
+Subject: [RHEL7.5 PATCH 133/169] sysfs/sysfs_read: Count working_disks
+
+This counts working_disks the same way as get_array_info counts it in
+the kernel.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ sysfs.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/sysfs.c b/sysfs.c
+index f7967e8..e47f5e4 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -272,6 +272,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 	sra->array.spare_disks = 0;
+ 	sra->array.active_disks = 0;
+ 	sra->array.failed_disks = 0;
++	sra->array.working_disks = 0;
+ 
+ 	devp = &sra->devs;
+ 	sra->devs = NULL;
+@@ -358,16 +359,18 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
+ 			strcpy(dbase, "state");
+ 			if (load_sys(fname, buf, sizeof(buf)))
+ 				goto abort;
+-			if (strstr(buf, "in_sync")) {
+-				dev->disk.state |= (1<<MD_DISK_SYNC);
+-				sra->array.active_disks++;
+-			}
+ 			if (strstr(buf, "faulty")) {
+ 				dev->disk.state |= (1<<MD_DISK_FAULTY);
+ 				sra->array.failed_disks++;
++			} else {
++				sra->array.working_disks++;
++				if (strstr(buf, "in_sync")) {
++					dev->disk.state |= (1<<MD_DISK_SYNC);
++					sra->array.active_disks++;
++				}
++				if (dev->disk.state == 0)
++					sra->array.spare_disks++;
+ 			}
+-			if (dev->disk.state == 0)
+-				sra->array.spare_disks++;
+ 		}
+ 		if (options & GET_ERROR) {
+ 			strcpy(buf, "errors");
+-- 
+2.7.4
+
diff --git a/SOURCES/sysfs_init_dev-takea-dev_t-argument.patch b/SOURCES/sysfs_init_dev-takea-dev_t-argument.patch
new file mode 100644
index 0000000..bd0db97
--- /dev/null
+++ b/SOURCES/sysfs_init_dev-takea-dev_t-argument.patch
@@ -0,0 +1,42 @@
+From a37563c91386a0c53d2d46aad00fe89ee28bd0da Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 29 Sep 2017 18:04:06 -0400
+Subject: [RHEL7.5 PATCH 11/13] sysfs_init_dev - take a dev_t argument
+
+Be consistent and use the correct type.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.h | 2 +-
+ sysfs.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index db08188..3fc8a4f 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -654,7 +654,7 @@ enum sysfs_read_flags {
+  */
+ extern int sysfs_open(char *devnm, char *devname, char *attr);
+ extern int sysfs_init(struct mdinfo *mdi, int fd, char *devnm);
+-extern void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid);
++extern void sysfs_init_dev(struct mdinfo *mdi, dev_t devid);
+ extern void sysfs_free(struct mdinfo *sra);
+ extern struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options);
+ extern int sysfs_attr_match(const char *attr, const char *str);
+diff --git a/sysfs.c b/sysfs.c
+index 78d2b52..68ddd5f 100644
+--- a/sysfs.c
++++ b/sysfs.c
+@@ -78,7 +78,7 @@ int sysfs_open(char *devnm, char *devname, char *attr)
+ 	return fd;
+ }
+ 
+-void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid)
++void sysfs_init_dev(struct mdinfo *mdi, dev_t devid)
+ {
+ 	snprintf(mdi->sys_name,
+ 		 sizeof(mdi->sys_name), "dev-%s", devid2kname(devid));
+-- 
+2.7.4
+
diff --git a/SOURCES/systemd-mdadm-last-resort-use-ConditionPathExists-in.patch b/SOURCES/systemd-mdadm-last-resort-use-ConditionPathExists-in.patch
new file mode 100644
index 0000000..a61aea0
--- /dev/null
+++ b/SOURCES/systemd-mdadm-last-resort-use-ConditionPathExists-in.patch
@@ -0,0 +1,49 @@
+From 5c4b3b9aa9f576305b36d5ccbd4b929b51307ce9 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 20 Apr 2017 12:40:05 +1000
+Subject: [RHEL7.5 PATCH 088/169] systemd/mdadm-last-resort: use
+ ConditionPathExists instead of Conflicts
+
+Commit cec72c071bbe ("systemd/mdadm-last-resort: add Conflicts to .service file.")
+
+added a 'Conflicts' directive to the mdadm-last-resort@.service file in
+the hope that this would make sure the service didn't run after the device
+was active, even if the timer managed to get started, which is possible in
+race conditions.
+
+This seemed to work is testing, but it isn't clear why, and it is known
+to cause problems.
+If systemd happens to know that the mentioned device is a dependency of a
+mount point, the Conflicts can unmount that mountpoint, which is certainly
+not wanted.
+
+So remove the "Conflicts" and instead use
+ ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action
+
+The "sync_action" file exists for any array which requires last-resort
+handling, and only appears when the array is activated.  So it is safe
+to rely on it to determine if the last-resort is really needed.
+
+Fixes: cec72c071bbe ("systemd/mdadm-last-resort: add Conflicts to .service file.")
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ systemd/mdadm-last-resort@.service | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/systemd/mdadm-last-resort@.service b/systemd/mdadm-last-resort@.service
+index e93d72b..f9d4d12 100644
+--- a/systemd/mdadm-last-resort@.service
++++ b/systemd/mdadm-last-resort@.service
+@@ -1,7 +1,7 @@
+ [Unit]
+ Description=Activate md array even though degraded
+ DefaultDependencies=no
+-Conflicts=sys-devices-virtual-block-%i.device
++ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action
+ 
+ [Service]
+ Type=oneshot
+-- 
+2.7.4
+
diff --git a/SOURCES/udev-md-raid-assembly.rules-Skip-non-ready-devices.patch b/SOURCES/udev-md-raid-assembly.rules-Skip-non-ready-devices.patch
new file mode 100644
index 0000000..8931cd5
--- /dev/null
+++ b/SOURCES/udev-md-raid-assembly.rules-Skip-non-ready-devices.patch
@@ -0,0 +1,39 @@
+From 3a77acd7170199adc690332ded37c41f067c720e Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Mon, 27 Mar 2017 11:15:44 +1100
+Subject: [RHEL7.5 PATCH 019/169] udev-md-raid-assembly.rules: Skip
+ non-ready devices
+
+If a device isn't fully initialized (e.g if it should be
+handled by multipathing) it should not be considered for
+md/RAID auto-assembly.  Doing so can cause incorrect results
+such as causing multipath to fail during startup.
+
+There is a convention that the udev environment variable
+SYSTEMD_READY be set to zero for such devices.  So change
+the mdadm rules to ignore devices with SYSTEMD_READY==0.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ udev-md-raid-assembly.rules | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
+index d0d440a..8ca232a 100644
+--- a/udev-md-raid-assembly.rules
++++ b/udev-md-raid-assembly.rules
+@@ -7,6 +7,9 @@ ENV{ANACONDA}=="?*", GOTO="md_inc_end"
+ 
+ SUBSYSTEM!="block", GOTO="md_inc_end"
+ 
++# skip non-initialized devices
++ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end"
++
+ # handle potential components of arrays (the ones supported by md)
+ ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc"
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Code-is-80-characterswide.patch b/SOURCES/util-Code-is-80-characterswide.patch
new file mode 100644
index 0000000..5e49255
--- /dev/null
+++ b/SOURCES/util-Code-is-80-characterswide.patch
@@ -0,0 +1,101 @@
+From b7a462e56135e38dfd9e53aeed6f425c28b1bbc7 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Fri, 29 Sep 2017 18:15:23 -0400
+Subject: [RHEL7.5 PATCH 13/13] util: Code is 80 characters wide
+
+Lets not make things uglier than they need to be.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ util.c | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+diff --git a/util.c b/util.c
+index c1c8509..68af381 100644
+--- a/util.c
++++ b/util.c
+@@ -147,9 +147,9 @@ int cluster_get_dlmlock(int *lockid)
+ 	}
+ 
+ 	snprintf(str, 64, "bitmap%s", cluster_name);
+-	ret = dlm_hooks->ls_lock(dlm_lock_res->ls, LKM_PWMODE, &dlm_lock_res->lksb,
+-			  flags, str, strlen(str), 0, dlm_ast,
+-			  dlm_lock_res, NULL, NULL);
++	ret = dlm_hooks->ls_lock(dlm_lock_res->ls, LKM_PWMODE,
++				 &dlm_lock_res->lksb, flags, str, strlen(str),
++				 0, dlm_ast, dlm_lock_res, NULL, NULL);
+ 	if (ret) {
+ 		pr_err("error %d when get PW mode on lock %s\n", errno, str);
+ 		dlm_hooks->release_lockspace(cluster_name, dlm_lock_res->ls, 1);
+@@ -183,7 +183,8 @@ int cluster_release_dlmlock(int lockid)
+ 
+ 	errno =	dlm_lock_res->lksb.sb_status;
+ 	if (errno != EUNLOCK) {
+-		pr_err("error %d happened in ast when unlock lockspace\n", errno);
++		pr_err("error %d happened in ast when unlock lockspace\n",
++		       errno);
+ 		/* XXX make sure the lockspace is unlocked eventually */
+                 goto out;
+ 	}
+@@ -639,14 +640,16 @@ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep)
+ 
+ }
+ 
+-char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep)
++char *fname_from_uuid(struct supertype *st, struct mdinfo *info,
++		      char *buf, char sep)
+ {
+ 	// dirty hack to work around an issue with super1 superblocks...
+ 	// super1 superblocks need swapuuid set in order for assembly to
+ 	// 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
+-	return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : st->ss->swapuuid, buf, sep);
++	return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 :
++				 st->ss->swapuuid, buf, sep);
+ }
+ 
+ int check_ext2(int fd, char *name)
+@@ -1084,9 +1087,11 @@ int dev_open(char *dev, int flags)
+ 		}
+ 		if (fd < 0) {
+ 			/* Try /tmp as /dev appear to be read-only */
+-			snprintf(devname, sizeof(devname), "/tmp/.tmp.md.%d:%d:%d",
++			snprintf(devname, sizeof(devname),
++				 "/tmp/.tmp.md.%d:%d:%d",
+ 				 (int)getpid(), major, minor);
+-			if (mknod(devname, S_IFBLK|0600, makedev(major, minor)) == 0) {
++			if (mknod(devname, S_IFBLK|0600,
++				  makedev(major, minor)) == 0) {
+ 				fd = open(devname, flags);
+ 				unlink(devname);
+ 			}
+@@ -2261,8 +2266,10 @@ void set_cmap_hooks(void)
+ 	if (!cmap_hooks->cmap_handle)
+ 		return;
+ 
+-	cmap_hooks->initialize = dlsym(cmap_hooks->cmap_handle, "cmap_initialize");
+-	cmap_hooks->get_string = dlsym(cmap_hooks->cmap_handle, "cmap_get_string");
++	cmap_hooks->initialize =
++		dlsym(cmap_hooks->cmap_handle, "cmap_initialize");
++	cmap_hooks->get_string =
++		dlsym(cmap_hooks->cmap_handle, "cmap_get_string");
+ 	cmap_hooks->finalize = dlsym(cmap_hooks->cmap_handle, "cmap_finalize");
+ 
+ 	if (!cmap_hooks->initialize || !cmap_hooks->get_string ||
+@@ -2305,8 +2312,10 @@ void set_dlm_hooks(void)
+ 	if (!dlm_hooks->dlm_handle)
+ 		return;
+ 
+-	dlm_hooks->create_lockspace = dlsym(dlm_hooks->dlm_handle, "dlm_create_lockspace");
+-	dlm_hooks->release_lockspace = dlsym(dlm_hooks->dlm_handle, "dlm_release_lockspace");
++	dlm_hooks->create_lockspace =
++		dlsym(dlm_hooks->dlm_handle, "dlm_create_lockspace");
++	dlm_hooks->release_lockspace =
++		dlsym(dlm_hooks->dlm_handle, "dlm_release_lockspace");
+ 	dlm_hooks->ls_lock = dlsym(dlm_hooks->dlm_handle, "dlm_ls_lock");
+ 	dlm_hooks->ls_unlock = dlsym(dlm_hooks->dlm_handle, "dlm_ls_unlock");
+ 	dlm_hooks->ls_get_fd = dlsym(dlm_hooks->dlm_handle, "dlm_ls_get_fd");
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Cosmetic-changes.patch b/SOURCES/util-Cosmetic-changes.patch
new file mode 100644
index 0000000..6053689
--- /dev/null
+++ b/SOURCES/util-Cosmetic-changes.patch
@@ -0,0 +1,99 @@
+From efa295309fd2d85133aaf3c224cd5834b689234c Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 12:05:12 -0400
+Subject: [RHEL7.5 PATCH 035/169] util: Cosmetic changes
+
+Fixup a number of indentation and whitespace issues
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ util.c | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/util.c b/util.c
+index 683c869..374015e 100644
+--- a/util.c
++++ b/util.c
+@@ -828,14 +828,12 @@ char *human_size(long long bytes)
+ 		long cMiB = (bytes * 200LL / (1LL<<20) + 1) / 2;
+ 		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);
++			cMiB/100, cMiB % 100, cMB/100, cMB % 100);
+ 	} else {
+ 		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);
++			cGiB/100, cGiB % 100, cGB/100, cGB % 100);
+ 	}
+ 	return buf;
+ }
+@@ -862,22 +860,22 @@ char *human_size_brief(long long bytes, int prefix)
+ 		if (bytes < 2*1024LL*1024LL*1024LL) {
+ 			long cMiB = (bytes * 200LL / (1LL<<20) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldMiB",
+-				cMiB/100 , cMiB % 100);
++				 cMiB/100, cMiB % 100);
+ 		} else {
+ 			long cGiB = (bytes * 200LL / (1LL<<30) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldGiB",
+-					cGiB/100 , cGiB % 100);
++				 cGiB/100, cGiB % 100);
+ 		}
+ 	}
+ 	else if (prefix == JEDEC) {
+ 		if (bytes < 2*1024LL*1024LL*1024LL) {
+ 			long cMB  = (bytes / ( 1000000LL / 200LL ) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldMB",
+-					cMB/100, cMB % 100);
++				 cMB/100, cMB % 100);
+ 		} else {
+ 			long cGB  = (bytes / (1000000000LL/200LL ) +1) /2;
+ 			snprintf(buf, sizeof(buf), "%ld.%02ldGB",
+-					cGB/100 , cGB % 100);
++				 cGB/100, cGB % 100);
+ 		}
+ 	}
+ 	else
+@@ -1093,7 +1091,7 @@ int open_dev_excl(char *devnm)
+ 	long delay = 1000;
+ 
+ 	sprintf(buf, "%d:%d", major(devid), minor(devid));
+-	for (i = 0 ; i < 25 ; i++) {
++	for (i = 0; i < 25; i++) {
+ 		int fd = dev_open(buf, flags|O_EXCL);
+ 		if (fd >= 0)
+ 			return fd;
+@@ -1134,7 +1132,7 @@ void wait_for(char *dev, int fd)
+ 	    (stb_want.st_mode & S_IFMT) != S_IFBLK)
+ 		return;
+ 
+-	for (i = 0 ; i < 25 ; i++) {
++	for (i = 0; i < 25; i++) {
+ 		struct stat stb;
+ 		if (stat(dev, &stb) == 0 &&
+ 		    (stb.st_mode & S_IFMT) == S_IFBLK &&
+@@ -1205,7 +1203,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
+ 			verstr = "-no-metadata-";
+ 	}
+ 
+-	for (i = 0; st == NULL && superlist[i] ; i++)
++	for (i = 0; st == NULL && superlist[i]; i++)
+ 		st = superlist[i]->match_metadata_desc(verstr);
+ 
+ 	sysfs_free(sra);
+@@ -1270,7 +1268,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
+ 	st = xcalloc(1, sizeof(*st));
+ 	st->container_devnm[0] = 0;
+ 
+-	for (i = 0 ; superlist[i]; i++) {
++	for (i = 0; superlist[i]; i++) {
+ 		int rv;
+ 		ss = superlist[i];
+ 		if (guess_type == guess_array && ss->add_to_super == NULL)
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Finally-kill-off-md_get_version.patch b/SOURCES/util-Finally-kill-off-md_get_version.patch
new file mode 100644
index 0000000..321810b
--- /dev/null
+++ b/SOURCES/util-Finally-kill-off-md_get_version.patch
@@ -0,0 +1,66 @@
+From 303949f6f00b750a88bcdfc39ffdfe9f0463f6f2 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:49:18 -0400
+Subject: [RHEL7.5 PATCH 066/169] util: Finally kill off md_get_version()
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ mdadm.h |  1 -
+ util.c  | 29 -----------------------------
+ 2 files changed, 30 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index 612bd86..f1f643c 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1404,7 +1404,6 @@ extern int Dump_metadata(char *dev, char *dir, struct context *c,
+ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 			    struct supertype *st, int only);
+ 
+-extern int md_get_version(int fd);
+ int md_get_array_info(int fd, struct mdu_array_info_s *array);
+ int md_set_array_info(int fd, struct mdu_array_info_s *array);
+ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk);
+diff --git a/util.c b/util.c
+index afeb6a5..a536f81 100644
+--- a/util.c
++++ b/util.c
+@@ -273,35 +273,6 @@ int parse_uuid(char *str, int uuid[4])
+ 	return 0;
+ }
+ 
+-/*
+- * Get the md version number.
+- * We use the RAID_VERSION ioctl if it is supported
+- * If not, but we have a block device with major '9', we assume
+- * 0.36.0
+- *
+- * Return version number as 24 but number - assume version parts
+- * always < 255
+- */
+-
+-int md_get_version(int fd)
+-{
+-	struct stat stb;
+-	mdu_version_t vers;
+-
+-	if (fstat(fd, &stb)<0)
+-		return -1;
+-	if ((S_IFMT&stb.st_mode) != S_IFBLK)
+-		return -1;
+-
+-	if (ioctl(fd, RAID_VERSION, &vers) == 0)
+-		return  (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
+-	if (errno == EACCES)
+-		return -1;
+-	if (major(stb.st_rdev) == MD_MAJOR)
+-		return (3600);
+-	return -1;
+-}
+-
+ int get_linux_version()
+ {
+ 	struct utsname name;
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Get-rid-of-unused-enoughfd.patch b/SOURCES/util-Get-rid-of-unused-enoughfd.patch
new file mode 100644
index 0000000..035064e
--- /dev/null
+++ b/SOURCES/util-Get-rid-of-unused-enoughfd.patch
@@ -0,0 +1,70 @@
+From 44356754ec8d7c38720db6c9916fef8f24921831 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 20 Apr 2017 11:53:30 -0400
+Subject: [RHEL7.5 PATCH 085/169] util: Get rid of unused enough_fd()
+
+enough_fd() is no longer used, so lets get rid of it.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.h |  1 -
+ util.c  | 31 -------------------------------
+ 2 files changed, 32 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index f6e97fd..1bbacfe 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1485,7 +1485,6 @@ extern char *fname_from_uuid(struct supertype *st,
+ extern unsigned long calc_csum(void *super, int bytes);
+ extern int enough(int level, int raid_disks, int layout, int clean,
+ 		   char *avail);
+-extern int enough_fd(int fd);
+ extern int ask(char *mesg);
+ extern unsigned long long get_component_size(int fd);
+ extern void remove_partitions(int fd);
+diff --git a/util.c b/util.c
+index 3adc675..21a63c9 100644
+--- a/util.c
++++ b/util.c
+@@ -542,37 +542,6 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
+ 	}
+ }
+ 
+-int enough_fd(int fd)
+-{
+-	struct mdu_array_info_s array;
+-	struct mdu_disk_info_s disk;
+-	int i, rv;
+-	char *avail;
+-
+-	if (md_get_array_info(fd, &array) != 0 || array.raid_disks <= 0)
+-		return 0;
+-	avail = xcalloc(array.raid_disks, 1);
+-	for (i = 0; i < MAX_DISKS && array.nr_disks > 0; i++) {
+-		disk.number = i;
+-		if (md_get_disk_info(fd, &disk) != 0)
+-			continue;
+-		if (disk.major == 0 && disk.minor == 0)
+-			continue;
+-		array.nr_disks--;
+-
+-		if (! (disk.state & (1<<MD_DISK_SYNC)))
+-			continue;
+-		if (disk.raid_disk < 0 || disk.raid_disk >= array.raid_disks)
+-			continue;
+-		avail[disk.raid_disk] = 1;
+-	}
+-	/* This is used on an active array, so assume it is clean */
+-	rv = enough(array.level, array.raid_disks, array.layout,
+-		    1, avail);
+-	free(avail);
+-	return rv;
+-}
+-
+ const int uuid_zero[4] = { 0, 0, 0, 0 };
+ 
+ int same_uuid(int a[4], int b[4], int swapuuid)
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Introduce2-md_get_array_info.patch b/SOURCES/util-Introduce2-md_get_array_info.patch
new file mode 100644
index 0000000..eeeb6e8
--- /dev/null
+++ b/SOURCES/util-Introduce2-md_get_array_info.patch
@@ -0,0 +1,416 @@
+From 9cd39f015558dba82c293a4433b481b921ceec87 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 14:35:41 -0400
+Subject: [RHEL7.5 PATCH 037/169] util: Introduce md_get_array_info()
+
+Remove most direct ioctl calls for GET_ARRAY_INFO, except for one,
+which will be addressed in the next patch.
+
+This is the start of the effort to clean up the use of ioctl calls and
+introduce a more structured API, which will use sysfs and fall back to
+ioctl for backup.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Create.c      |  5 ++---
+ Detail.c      |  2 +-
+ Grow.c        | 31 ++++++++++++++++---------------
+ Incremental.c | 11 +++++------
+ Manage.c      | 13 ++++++-------
+ Monitor.c     |  7 ++++---
+ Query.c       |  7 ++++---
+ mdadm.h       |  1 +
+ mdassemble.c  |  2 +-
+ util.c        | 14 +++++++++++---
+ 10 files changed, 51 insertions(+), 42 deletions(-)
+
+diff --git a/Create.c b/Create.c
+index 10e7d10..0e0778f 100644
+--- a/Create.c
++++ b/Create.c
+@@ -156,8 +156,7 @@ int Create(struct supertype *st, char *mddev,
+ 		memset(&inf, 0, sizeof(inf));
+ 		fd = open(devlist->devname, O_RDONLY);
+ 		if (fd >= 0 &&
+-		    ioctl(fd, GET_ARRAY_INFO, &inf) == 0 &&
+-		    inf.raid_disks == 0) {
++		    md_get_array_info(fd, &inf) == 0 && inf.raid_disks == 0) {
+ 			/* yep, looks like a container */
+ 			if (st) {
+ 				rv = st->ss->load_container(st, fd,
+@@ -634,7 +633,7 @@ int Create(struct supertype *st, char *mddev,
+ 	} else {
+ 		mdu_array_info_t inf;
+ 		memset(&inf, 0, sizeof(inf));
+-		ioctl(mdfd, GET_ARRAY_INFO, &inf);
++		md_get_array_info(mdfd, &inf);
+ 		if (inf.working_disks != 0) {
+ 			pr_err("another array by this name is already running.\n");
+ 			goto abort_locked;
+diff --git a/Detail.c b/Detail.c
+index 136875b..d7e886a 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -107,7 +107,7 @@ int Detail(char *dev, struct context *c)
+ 	external = (sra != NULL && sra->array.major_version == -1
+ 		    && sra->array.minor_version == -2);
+ 	st = super_by_fd(fd, &subarray);
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) {
++	if (md_get_array_info(fd, &array) == 0) {
+ 		inactive = 0;
+ 	} else if (errno == ENODEV && sra) {
+ 		if (sra->array.major_version == -1 &&
+diff --git a/Grow.c b/Grow.c
+index 6405f0e..4eab5cc 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -115,7 +115,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 	struct supertype *st = NULL;
+ 	char *subarray = NULL;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
++	if (md_get_array_info(fd, &info.array) < 0) {
+ 		pr_err("cannot get array info for %s\n", devname);
+ 		return 1;
+ 	}
+@@ -221,7 +221,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 	 * Now go through and update all superblocks
+ 	 */
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
++	if (md_get_array_info(fd, &info.array) < 0) {
+ 		pr_err("cannot get array info for %s\n", devname);
+ 		return 1;
+ 	}
+@@ -328,7 +328,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 			devname, bmf.pathname);
+ 		return 1;
+ 	}
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
++	if (md_get_array_info(fd, &array) != 0) {
+ 		pr_err("cannot get array status for %s\n", devname);
+ 		return 1;
+ 	}
+@@ -1784,7 +1784,7 @@ int Grow_reshape(char *devname, int fd,
+ 	struct mdinfo info;
+ 	struct mdinfo *sra;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
++	if (md_get_array_info(fd, &array) < 0) {
+ 		pr_err("%s is not an active md array - aborting\n",
+ 			devname);
+ 		return 1;
+@@ -2030,7 +2030,7 @@ int Grow_reshape(char *devname, int fd,
+ 					/* get array parameters after takeover
+ 					 * to change one parameter at time only
+ 					 */
+-					rv = ioctl(fd, GET_ARRAY_INFO, &array);
++					rv = md_get_array_info(fd, &array);
+ 				}
+ 			}
+ 			/* make sure mdmon is
+@@ -2072,7 +2072,7 @@ int Grow_reshape(char *devname, int fd,
+ 			/* go back to raid0, drop parity disk
+ 			 */
+ 			sysfs_set_str(sra, NULL, "level", "raid0");
+-			ioctl(fd, GET_ARRAY_INFO, &array);
++			md_get_array_info(fd, &array);
+ 		}
+ 
+ size_change_error:
+@@ -2101,7 +2101,7 @@ size_change_error:
+ 			    sysfs_set_str(sra, NULL, "resync_start", "none") < 0)
+ 				pr_err("--assume-clean not supported with --grow on this kernel\n");
+ 		}
+-		ioctl(fd, GET_ARRAY_INFO, &array);
++		md_get_array_info(fd, &array);
+ 		s->size = get_component_size(fd)/2;
+ 		if (s->size == 0)
+ 			s->size = array.size;
+@@ -2267,7 +2267,7 @@ size_change_error:
+ 			rv =1 ;
+ 		}
+ 		if (s->layout_str) {
+-			if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
++			if (md_get_array_info(fd, &array) != 0) {
+ 				dprintf("Cannot get array information.\n");
+ 				goto release;
+ 			}
+@@ -2830,7 +2830,7 @@ static int impose_reshape(struct mdinfo *sra,
+ 						 * reshape->after.data_disks);
+ 	}
+ 
+-	ioctl(fd, GET_ARRAY_INFO, &array);
++	md_get_array_info(fd, &array);
+ 	if (info->array.chunk_size == info->new_chunk &&
+ 	    reshape->before.layout == reshape->after.layout &&
+ 	    st->ss->external == 0) {
+@@ -2885,7 +2885,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 	struct mdinfo info;
+ 	sysfs_init(&info, fd, NULL);
+ 
+-	ioctl(fd, GET_ARRAY_INFO, &array);
++	md_get_array_info(fd, &array);
+ 	if (level == 0 &&
+ 	    (array.level >= 4 && array.level <= 6)) {
+ 		/* To convert to RAID0 we need to fail and
+@@ -2921,7 +2921,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 			      makedev(disk.major, disk.minor));
+ 		}
+ 		/* Now fail anything left */
+-		ioctl(fd, GET_ARRAY_INFO, &array);
++		md_get_array_info(fd, &array);
+ 		for (d = 0, found = 0;
+ 		     d < MAX_DISKS && found < array.nr_disks;
+ 		     d++) {
+@@ -3042,7 +3042,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 	/* when reshaping a RAID0, the component_size might be zero.
+ 	 * So try to fix that up.
+ 	 */
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
++	if (md_get_array_info(fd, &array) != 0) {
+ 		dprintf("Cannot get array information.\n");
+ 		goto release;
+ 	}
+@@ -3230,7 +3230,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 		 * some more changes: layout, raid_disks, chunk_size
+ 		 */
+ 		/* read current array info */
+-		if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
++		if (md_get_array_info(fd, &array) != 0) {
+ 			dprintf("Cannot get array information.\n");
+ 			goto release;
+ 		}
+@@ -4994,8 +4994,9 @@ int Grow_continue_command(char *devname, int fd,
+ 		int d;
+ 		int cnt = 5;
+ 		dprintf_cont("native array (%s)\n", devname);
+-		if (ioctl(fd, GET_ARRAY_INFO, &array.array) < 0) {
+-			pr_err("%s is not an active md array - aborting\n", devname);
++		if (md_get_array_info(fd, &array.array) < 0) {
++			pr_err("%s is not an active md array - aborting\n",
++			       devname);
+ 			ret_val = 1;
+ 			goto Grow_continue_command_exit;
+ 		}
+diff --git a/Incremental.c b/Incremental.c
+index 81afc7e..1f12c77 100644
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -398,7 +398,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 		    && ! policy_action_allows(policy, st->ss->name,
+ 					      act_re_add)
+ 		    && c->runstop < 1) {
+-			if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
++			if (md_get_array_info(mdfd, &ainf) == 0) {
+ 				pr_err("not adding %s to active array (without --run) %s\n",
+ 				       devname, chosen_name);
+ 				rv = 2;
+@@ -549,7 +549,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
+ 	/*   + add any bitmap file  */
+ 	/*   + start the array (auto-readonly). */
+ 
+-	if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
++	if (md_get_array_info(mdfd, &ainf) == 0) {
+ 		if (c->export) {
+ 			printf("MD_STARTED=already\n");
+ 		} else if (c->verbose >= 0)
+@@ -664,7 +664,7 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
+ 	struct mdinfo *d;
+ 	mdu_array_info_t ra;
+ 
+-	if (ioctl(mdfd, GET_ARRAY_INFO, &ra) == 0)
++	if (md_get_array_info(mdfd, &ra) == 0)
+ 		return; /* not safe to remove from active arrays
+ 			 * without thinking more */
+ 
+@@ -837,7 +837,7 @@ static int container_members_max_degradation(struct map_ent *map, struct map_ent
+ 		if (afd < 0)
+ 			continue;
+ 		/* most accurate information regarding array degradation */
+-		if (ioctl(afd, GET_ARRAY_INFO, &array) >= 0) {
++		if (md_get_array_info(afd, &array) >= 0) {
+ 			int degraded = array.raid_disks - array.active_disks -
+ 				       array.spare_disks;
+ 			if (degraded > max_degraded)
+@@ -1390,8 +1390,7 @@ restart:
+ 				rv = 1;
+ 			continue;
+ 		}
+-		if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
+-		    errno != ENODEV) {
++		if (md_get_array_info(mdfd, &array) == 0 || errno != ENODEV) {
+ 			close(mdfd);
+ 			continue;
+ 		}
+diff --git a/Manage.c b/Manage.c
+index 55218d9..24ed370 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -95,7 +95,7 @@ int Manage_ro(char *devname, int fd, int readonly)
+ 		goto out;
+ 	}
+ #endif
+-	if (ioctl(fd, GET_ARRAY_INFO, &array)) {
++	if (md_get_array_info(fd, &array)) {
+ 		pr_err("%s does not appear to be active.\n",
+ 			devname);
+ 		rv = 1;
+@@ -539,7 +539,7 @@ static void add_faulty(struct mddev_dev *dv, int fd, char disp)
+ 	int remaining_disks;
+ 	int i;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0)
++	if (md_get_array_info(fd, &array) != 0)
+ 		return;
+ 
+ 	remaining_disks = array.nr_disks;
+@@ -565,7 +565,7 @@ static void add_detached(struct mddev_dev *dv, int fd, char disp)
+ 	int remaining_disks;
+ 	int i;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0)
++	if (md_get_array_info(fd, &array) != 0)
+ 		return;
+ 
+ 	remaining_disks = array.nr_disks;
+@@ -602,7 +602,7 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char)
+ 	int copies, set;
+ 	int i;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0)
++	if (md_get_array_info(fd, &array) != 0)
+ 		return;
+ 	if (array.level != 10)
+ 		return;
+@@ -1383,9 +1383,8 @@ int Manage_subdevs(char *devname, int fd,
+ 	int busy = 0;
+ 	int raid_slot = -1;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &array)) {
+-		pr_err("Cannot get array info for %s\n",
+-			devname);
++	if (md_get_array_info(fd, &array)) {
++		pr_err("Cannot get array info for %s\n", devname);
+ 		goto abort;
+ 	}
+ 	sysfs_init(&info, fd, NULL);
+diff --git a/Monitor.c b/Monitor.c
+index bdd3e63..0a0a1e2 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -497,7 +497,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 		return 0;
+ 	}
+ 	fcntl(fd, F_SETFD, FD_CLOEXEC);
+-	if (ioctl(fd, GET_ARRAY_INFO, &array)<0) {
++	if (md_get_array_info(fd, &array) < 0) {
+ 		if (!st->err)
+ 			alert("DeviceDisappeared", dev, NULL, ainfo);
+ 		st->err++;
+@@ -709,9 +709,10 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
+ 
+ 			st->devname = xstrdup(name);
+ 			if ((fd = open(st->devname, O_RDONLY)) < 0 ||
+-			    ioctl(fd, GET_ARRAY_INFO, &array)< 0) {
++			    md_get_array_info(fd, &array) < 0) {
+ 				/* no such array */
+-				if (fd >=0) close(fd);
++				if (fd >= 0)
++					close(fd);
+ 				put_md_name(st->devname);
+ 				free(st->devname);
+ 				if (st->metadata) {
+diff --git a/Query.c b/Query.c
+index fbc1d10..cae75d1 100644
+--- a/Query.c
++++ b/Query.c
+@@ -53,9 +53,10 @@ int Query(char *dev)
+ 	}
+ 
+ 	vers = md_get_version(fd);
+-	if (ioctl(fd, GET_ARRAY_INFO, &array)<0)
++	if (md_get_array_info(fd, &array) < 0)
+ 		ioctlerr = errno;
+-	else ioctlerr = 0;
++	else
++		ioctlerr = 0;
+ 
+ 	fstat(fd, &stb);
+ 
+@@ -100,7 +101,7 @@ int Query(char *dev)
+ 			activity = "undetected";
+ 			if (mddev && (fd = open(mddev, O_RDONLY))>=0) {
+ 				if (md_get_version(fd) >= 9000 &&
+-				    ioctl(fd, GET_ARRAY_INFO, &array)>= 0) {
++				    md_get_array_info(fd, &array) >= 0) {
+ 					if (ioctl(fd, GET_DISK_INFO, &disc) >= 0 &&
+ 					    makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev)
+ 						activity = "active";
+diff --git a/mdadm.h b/mdadm.h
+index dbf1f92..7770585 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1405,6 +1405,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 			    struct supertype *st, int only);
+ 
+ extern int md_get_version(int fd);
++int md_get_array_info(int fd, struct mdu_array_info_s *array);
+ extern int get_linux_version(void);
+ extern int mdadm_version(char *version);
+ extern unsigned long long parse_size(char *size);
+diff --git a/mdassemble.c b/mdassemble.c
+index 471ffeb..a24b324 100644
+--- a/mdassemble.c
++++ b/mdassemble.c
+@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
+ 			if (strcasecmp(array_list->devname, "<ignore>") == 0)
+ 				continue;
+ 			mdfd = open_mddev(array_list->devname, 0);
+-			if (mdfd >= 0 && ioctl(mdfd, GET_ARRAY_INFO, &array) == 0) {
++			if (mdfd >= 0 && md_get_array_info(mdfd, &array) == 0) {
+ 				rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */
+ 				continue;
+ 			}
+diff --git a/util.c b/util.c
+index 374015e..725877d 100644
+--- a/util.c
++++ b/util.c
+@@ -212,6 +212,15 @@ int cluster_release_dlmlock(int lockid)
+ #endif
+ 
+ /*
++ * Get array info from the kernel. Longer term we want to deprecate the
++ * ioctl and get it from sysfs.
++ */
++int md_get_array_info(int fd, struct mdu_array_info_s *array)
++{
++	return ioctl(fd, GET_ARRAY_INFO, array);
++}
++
++/*
+  * Parse a 128 bit uuid in 4 integers
+  * format is 32 hexx nibbles with options :.<space> separator
+  * If not exactly 32 hex digits are found, return 0
+@@ -539,8 +548,7 @@ int enough_fd(int fd)
+ 	int i, rv;
+ 	char *avail;
+ 
+-	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 ||
+-	    array.raid_disks <= 0)
++	if (md_get_array_info(fd, &array) != 0 || array.raid_disks <= 0)
+ 		return 0;
+ 	avail = xcalloc(array.raid_disks, 1);
+ 	for (i = 0; i < MAX_DISKS && array.nr_disks > 0; i++) {
+@@ -1175,7 +1183,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
+ 		minor = sra->array.minor_version;
+ 		verstr = sra->text_version;
+ 	} else {
+-		if (ioctl(fd, GET_ARRAY_INFO, &array))
++		if (md_get_array_info(fd, &array))
+ 			array.major_version = array.minor_version = 0;
+ 		vers = array.major_version;
+ 		minor = array.minor_version;
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Introduce3-md_get_disk_info.patch b/SOURCES/util-Introduce3-md_get_disk_info.patch
new file mode 100644
index 0000000..5d58b92
--- /dev/null
+++ b/SOURCES/util-Introduce3-md_get_disk_info.patch
@@ -0,0 +1,268 @@
+From d97572f5a59ca1ddde9971a79d47c9ea4db5891b Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 15:23:50 -0400
+Subject: [RHEL7.5 PATCH 039/169] util: Introduce md_get_disk_info()
+
+This removes all the inline ioctl calls for GET_DISK_INFO, allowing us
+to switch to sysfs in one place, and improves type checking.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Detail.c  |  8 +++-----
+ Grow.c    | 14 +++++++-------
+ Manage.c  | 19 +++++++++----------
+ Monitor.c |  2 +-
+ Query.c   |  2 +-
+ mdadm.h   |  1 +
+ util.c    | 10 +++++++++-
+ 7 files changed, 31 insertions(+), 25 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index d7e886a..fa6d4c7 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -51,10 +51,8 @@ static int add_device(const char *dev, char ***p_devices,
+ int Detail(char *dev, struct context *c)
+ {
+ 	/*
+-	 * Print out details for an md array by using
+-	 * GET_ARRAY_INFO and GET_DISK_INFO ioctl calls
++	 * Print out details for an md array
+ 	 */
+-
+ 	int fd = open(dev, O_RDONLY);
+ 	int vers;
+ 	mdu_array_info_t array;
+@@ -165,7 +163,7 @@ int Detail(char *dev, struct context *c)
+ 			disk = subdev->disk;
+ 		else {
+ 			disk.number = d;
+-			if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
++			if (md_get_disk_info(fd, &disk) < 0)
+ 				continue;
+ 			if (d >= array.raid_disks &&
+ 			    disk.major == 0 &&
+@@ -322,7 +320,7 @@ int Detail(char *dev, struct context *c)
+ 	} else for (d = 0; d < max_disks; d++) {
+ 		mdu_disk_info_t disk;
+ 		disk.number = d;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
++		if (md_get_disk_info(fd, &disk) < 0) {
+ 			if (d < array.raid_disks)
+ 				pr_err("cannot get device detail for device %d: %s\n",
+ 					d, strerror(errno));
+diff --git a/Grow.c b/Grow.c
+index 4eab5cc..1c90902 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -161,7 +161,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 		st->ss->free_super(st);
+ 
+ 		disk.number = d;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
++		if (md_get_disk_info(fd, &disk) < 0) {
+ 			pr_err("cannot get device detail for device %d\n",
+ 				d);
+ 			close(nfd);
+@@ -232,7 +232,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
+ 		char *dv;
+ 
+ 		disk.number = d;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
++		if (md_get_disk_info(fd, &disk) < 0) {
+ 			pr_err("cannot get device detail for device %d\n",
+ 				d);
+ 			return 1;
+@@ -422,7 +422,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 			int fd2;
+ 
+ 			disk.number = d;
+-			if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
++			if (md_get_disk_info(fd, &disk) < 0)
+ 				continue;
+ 			if (disk.major == 0 && disk.minor == 0)
+ 				continue;
+@@ -483,7 +483,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 			char *dv;
+ 			int fd2;
+ 			disk.number = d;
+-			if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
++			if (md_get_disk_info(fd, &disk) < 0)
+ 				continue;
+ 			if ((disk.major==0 && disk.minor == 0) ||
+ 			    (disk.state & (1 << MD_DISK_REMOVED)))
+@@ -2908,7 +2908,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 		     d++) {
+ 			mdu_disk_info_t disk;
+ 			disk.number = d;
+-			if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
++			if (md_get_disk_info(fd, &disk) < 0)
+ 				continue;
+ 			if (disk.major == 0 && disk.minor == 0)
+ 				continue;
+@@ -2927,7 +2927,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
+ 		     d++) {
+ 			mdu_disk_info_t disk;
+ 			disk.number = d;
+-			if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
++			if (md_get_disk_info(fd, &disk) < 0)
+ 				continue;
+ 			if (disk.major == 0 && disk.minor == 0)
+ 				continue;
+@@ -5011,7 +5011,7 @@ int Grow_continue_command(char *devname, int fd,
+ 				char *dv;
+ 				int err;
+ 				disk.number = d;
+-				if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
++				if (md_get_disk_info(fd, &disk) < 0)
+ 					continue;
+ 				if (disk.major == 0 && disk.minor == 0)
+ 					continue;
+diff --git a/Manage.c b/Manage.c
+index 24ed370..0ffb6c6 100644
+--- a/Manage.c
++++ b/Manage.c
+@@ -546,7 +546,7 @@ static void add_faulty(struct mddev_dev *dv, int fd, char disp)
+ 	for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
+ 		char buf[40];
+ 		disk.number = i;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
++		if (md_get_disk_info(fd, &disk) != 0)
+ 			continue;
+ 		if (disk.major == 0 && disk.minor == 0)
+ 			continue;
+@@ -573,7 +573,7 @@ static void add_detached(struct mddev_dev *dv, int fd, char disp)
+ 		char buf[40];
+ 		int sfd;
+ 		disk.number = i;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
++		if (md_get_disk_info(fd, &disk) != 0)
+ 			continue;
+ 		if (disk.major == 0 && disk.minor == 0)
+ 			continue;
+@@ -615,7 +615,7 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char)
+ 	for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
+ 		char buf[40];
+ 		disk.number = i;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
++		if (md_get_disk_info(fd, &disk) != 0)
+ 			continue;
+ 		if (disk.major == 0 && disk.minor == 0)
+ 			continue;
+@@ -661,9 +661,8 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
+ 		    get_linux_version() <= 2006018)
+ 			goto skip_re_add;
+ 		disc.number = mdi.disk.number;
+-		if (ioctl(fd, GET_DISK_INFO, &disc) != 0
+-		    || disc.major != 0 || disc.minor != 0
+-			)
++		if (md_get_disk_info(fd, &disc) != 0 ||
++		    disc.major != 0 || disc.minor != 0)
+ 			goto skip_re_add;
+ 		disc.major = major(rdev);
+ 		disc.minor = minor(rdev);
+@@ -805,7 +804,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 				char *dev;
+ 				int dfd;
+ 				disc.number = j;
+-				if (ioctl(fd, GET_DISK_INFO, &disc))
++				if (md_get_disk_info(fd, &disc))
+ 					continue;
+ 				if (disc.major==0 && disc.minor==0)
+ 					continue;
+@@ -888,7 +887,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 
+ 			for (d = 0; d < MAX_DISKS && found < array->nr_disks; d++) {
+ 				disc.number = d;
+-				if (ioctl(fd, GET_DISK_INFO, &disc))
++				if (md_get_disk_info(fd, &disc))
+ 					continue;
+ 				if (disc.major == 0 && disc.minor == 0)
+ 					continue;
+@@ -929,7 +928,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 	 */
+ 	for (j = array->raid_disks; j < tst->max_devs; j++) {
+ 		disc.number = j;
+-		if (ioctl(fd, GET_DISK_INFO, &disc))
++		if (md_get_disk_info(fd, &disc))
+ 			break;
+ 		if (disc.major==0 && disc.minor==0)
+ 			break;
+@@ -994,7 +993,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
+ 		for (j = 0; j < tst->max_devs; j++) {
+ 			mdu_disk_info_t disc2;
+ 			disc2.number = j;
+-			if (ioctl(fd, GET_DISK_INFO, &disc2))
++			if (md_get_disk_info(fd, &disc2))
+ 				continue;
+ 			if (disc2.major==0 && disc2.minor==0)
+ 				continue;
+diff --git a/Monitor.c b/Monitor.c
+index 0a0a1e2..2c0f717 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -608,7 +608,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
+ 	     i++) {
+ 		mdu_disk_info_t disc;
+ 		disc.number = i;
+-		if (ioctl(fd, GET_DISK_INFO, &disc) >= 0) {
++		if (md_get_disk_info(fd, &disc) >= 0) {
+ 			info[i].state = disc.state;
+ 			info[i].major = disc.major;
+ 			info[i].minor = disc.minor;
+diff --git a/Query.c b/Query.c
+index cae75d1..a2c839c 100644
+--- a/Query.c
++++ b/Query.c
+@@ -102,7 +102,7 @@ int Query(char *dev)
+ 			if (mddev && (fd = open(mddev, O_RDONLY))>=0) {
+ 				if (md_get_version(fd) >= 9000 &&
+ 				    md_get_array_info(fd, &array) >= 0) {
+-					if (ioctl(fd, GET_DISK_INFO, &disc) >= 0 &&
++					if (md_get_disk_info(fd, &disc) >= 0 &&
+ 					    makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev)
+ 						activity = "active";
+ 					else
+diff --git a/mdadm.h b/mdadm.h
+index 7770585..3ab548f 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1406,6 +1406,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 
+ extern int md_get_version(int fd);
+ int md_get_array_info(int fd, struct mdu_array_info_s *array);
++int md_get_disk_info(int fd, struct mdu_disk_info_s *disk);
+ extern int get_linux_version(void);
+ extern int mdadm_version(char *version);
+ extern unsigned long long parse_size(char *size);
+diff --git a/util.c b/util.c
+index 725877d..aa27e59 100644
+--- a/util.c
++++ b/util.c
+@@ -221,6 +221,14 @@ int md_get_array_info(int fd, struct mdu_array_info_s *array)
+ }
+ 
+ /*
++ * Get disk info from the kernel.
++ */
++int md_get_disk_info(int fd, struct mdu_disk_info_s *disk)
++{
++	return ioctl(fd, GET_DISK_INFO, disk);
++}
++
++/*
+  * Parse a 128 bit uuid in 4 integers
+  * format is 32 hexx nibbles with options :.<space> separator
+  * If not exactly 32 hex digits are found, return 0
+@@ -553,7 +561,7 @@ int enough_fd(int fd)
+ 	avail = xcalloc(array.raid_disks, 1);
+ 	for (i = 0; i < MAX_DISKS && array.nr_disks > 0; i++) {
+ 		disk.number = i;
+-		if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
++		if (md_get_disk_info(fd, &disk) != 0)
+ 			continue;
+ 		if (disk.major == 0 && disk.minor == 0)
+ 			continue;
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Introduce4-md_set_array_info.patch b/SOURCES/util-Introduce4-md_set_array_info.patch
new file mode 100644
index 0000000..fe57bae
--- /dev/null
+++ b/SOURCES/util-Introduce4-md_set_array_info.patch
@@ -0,0 +1,153 @@
+From 018a488238e2ff55d7c2fd29333c1f7305354318 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 29 Mar 2017 15:43:53 -0400
+Subject: [RHEL7.5 PATCH 040/169] util: Introduce md_set_array_info()
+
+Switch from using ioctl(SET_ARRAY_INFO) to using md_set_array_info()
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ Build.c |  4 ++--
+ Grow.c  | 17 ++++++++---------
+ mdadm.h |  1 +
+ util.c  | 12 ++++++++++--
+ 4 files changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/Build.c b/Build.c
+index a5fcc06..691dd6f 100644
+--- a/Build.c
++++ b/Build.c
+@@ -148,8 +148,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
+ 			s->chunk = 64;
+ 		array.chunk_size = s->chunk*1024;
+ 		array.layout = s->layout;
+-		if (ioctl(mdfd, SET_ARRAY_INFO, &array)) {
+-			pr_err("SET_ARRAY_INFO failed for %s: %s\n",
++		if (md_set_array_info(mdfd, &array)) {
++			pr_err("md_set_array_info() failed for %s: %s\n",
+ 				mddev, strerror(errno));
+ 			goto abort;
+ 		}
+diff --git a/Grow.c b/Grow.c
+index 1c90902..af8d520 100755
+--- a/Grow.c
++++ b/Grow.c
+@@ -335,7 +335,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 	if (array.state & (1 << MD_SB_BITMAP_PRESENT)) {
+ 		if (strcmp(s->bitmap_file, "none")==0) {
+ 			array.state &= ~(1 << MD_SB_BITMAP_PRESENT);
+-			if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
++			if (md_set_array_info(fd, &array) != 0) {
+ 				if (array.state & (1 << MD_SB_CLUSTERED))
+ 					pr_err("failed to remove clustered bitmap.\n");
+ 				else
+@@ -463,7 +463,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
+ 			if (strcmp(s->bitmap_file, "clustered") == 0)
+ 				array.state |= (1 << MD_SB_CLUSTERED);
+ 			array.state |= (1 << MD_SB_BITMAP_PRESENT);
+-			rv = ioctl(fd, SET_ARRAY_INFO, &array);
++			rv = md_set_array_info(fd, &array);
+ 		}
+ 		if (rv < 0) {
+ 			if (errno == EBUSY)
+@@ -1823,7 +1823,7 @@ int Grow_reshape(char *devname, int fd,
+ 	    (array.state & (1<<MD_SB_BITMAP_PRESENT)) &&
+ 	    !(array.state & (1<<MD_SB_CLUSTERED))) {
+                 array.state &= ~(1<<MD_SB_BITMAP_PRESENT);
+-                if (ioctl(fd, SET_ARRAY_INFO, &array)!= 0) {
++                if (md_set_array_info(fd, &array)!= 0) {
+                         pr_err("failed to remove internal bitmap.\n");
+                         return 1;
+                 }
+@@ -2056,7 +2056,7 @@ int Grow_reshape(char *devname, int fd,
+ 			else
+ 				rv = -1;
+ 		} else {
+-			rv = ioctl(fd, SET_ARRAY_INFO, &array);
++			rv = md_set_array_info(fd, &array);
+ 
+ 			/* manage array size when it is managed externally
+ 			 */
+@@ -2272,7 +2272,7 @@ size_change_error:
+ 				goto release;
+ 			}
+ 			array.layout = info.new_layout;
+-			if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
++			if (md_set_array_info(fd, &array) != 0) {
+ 				pr_err("failed to set new layout\n");
+ 				rv = 1;
+ 			} else if (c->verbose >= 0)
+@@ -2836,8 +2836,7 @@ static int impose_reshape(struct mdinfo *sra,
+ 	    st->ss->external == 0) {
+ 		/* use SET_ARRAY_INFO but only if reshape hasn't started */
+ 		array.raid_disks = reshape->after.data_disks + reshape->parity;
+-		if (!restart &&
+-		    ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
++		if (!restart && md_set_array_info(fd, &array) != 0) {
+ 			int err = errno;
+ 
+ 			pr_err("Cannot set device shape for %s: %s\n",
+@@ -3239,7 +3238,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 		if (info->new_layout != UnSet &&
+ 		    info->new_layout != array.layout) {
+ 			array.layout = info->new_layout;
+-			if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
++			if (md_set_array_info(fd, &array) != 0) {
+ 				pr_err("failed to set new layout\n");
+ 				goto release;
+ 			} else if (verbose >= 0)
+@@ -3250,7 +3249,7 @@ static int reshape_array(char *container, int fd, char *devname,
+ 		    info->delta_disks != 0 &&
+ 		    array.raid_disks != (info->array.raid_disks + info->delta_disks)) {
+ 			array.raid_disks += info->delta_disks;
+-			if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
++			if (md_set_array_info(fd, &array) != 0) {
+ 				pr_err("failed to set raid disks\n");
+ 				goto release;
+ 			} else if (verbose >= 0) {
+diff --git a/mdadm.h b/mdadm.h
+index 3ab548f..084bc97 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1406,6 +1406,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 
+ extern int md_get_version(int fd);
+ int md_get_array_info(int fd, struct mdu_array_info_s *array);
++int md_set_array_info(int fd, struct mdu_array_info_s *array);
+ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk);
+ extern int get_linux_version(void);
+ extern int mdadm_version(char *version);
+diff --git a/util.c b/util.c
+index aa27e59..9fc7ba0 100644
+--- a/util.c
++++ b/util.c
+@@ -221,6 +221,14 @@ int md_get_array_info(int fd, struct mdu_array_info_s *array)
+ }
+ 
+ /*
++ * Set array info
++ */
++int md_set_array_info(int fd, struct mdu_array_info_s *array)
++{
++	return ioctl(fd, SET_ARRAY_INFO, array);
++}
++
++/*
+  * Get disk info from the kernel.
+  */
+ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk)
+@@ -1858,9 +1866,9 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
+ 		memset(&inf, 0, sizeof(inf));
+ 		inf.major_version = info->array.major_version;
+ 		inf.minor_version = info->array.minor_version;
+-		rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
++		rv = md_set_array_info(mdfd, &inf);
+ 	} else
+-		rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
++		rv = md_set_array_info(mdfd, NULL);
+ 	return rv;
+ }
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/util-Introduce6-md_array_active-helper.patch b/SOURCES/util-Introduce6-md_array_active-helper.patch
new file mode 100644
index 0000000..1837755
--- /dev/null
+++ b/SOURCES/util-Introduce6-md_array_active-helper.patch
@@ -0,0 +1,99 @@
+From 3ab8f4bf33d906cb1084f7b4036556bfb4bb73ec Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Thu, 13 Apr 2017 13:30:17 -0400
+Subject: [RHEL7.5 PATCH 082/169] util: Introduce md_array_active() helper
+
+Rather than querying md_get_array_info() to determine whether an array
+is valid, do the work in md_array_active() using sysfs, and fall back
+on md_get_array_info() if sysfs fails.
+
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ Query.c |  5 +++--
+ mdadm.h |  1 +
+ util.c  | 27 +++++++++++++++++++++++++++
+ 3 files changed, 31 insertions(+), 2 deletions(-)
+
+diff --git a/Query.c b/Query.c
+index b761c47..4dec9f5 100644
+--- a/Query.c
++++ b/Query.c
+@@ -38,7 +38,6 @@ int Query(char *dev)
+ 	int level, raid_disks, spare_disks;
+ 	struct mdinfo info;
+ 	struct mdinfo *sra;
+-	mdu_array_info_t array;
+ 	struct supertype *st = NULL;
+ 	unsigned long long larray_size;
+ 	struct stat stb;
+@@ -65,6 +64,8 @@ int Query(char *dev)
+ 		raid_disks = sra->array.raid_disks;
+ 		spare_disks = sra->array.spare_disks;
+ 	} else {
++		mdu_array_info_t array;
++
+ 		if (md_get_array_info(fd, &array) < 0) {
+ 			ioctlerr = errno;
+ 		} else {
+@@ -111,7 +112,7 @@ int Query(char *dev)
+ 			disc.number = info.disk.number;
+ 			activity = "undetected";
+ 			if (mddev && (fd = open(mddev, O_RDONLY))>=0) {
+-				if (md_get_array_info(fd, &array) >= 0) {
++				if (md_array_active(fd)) {
+ 					if (md_get_disk_info(fd, &disc) >= 0 &&
+ 					    makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev)
+ 						activity = "active";
+diff --git a/mdadm.h b/mdadm.h
+index a379973..f6e97fd 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1415,6 +1415,7 @@ extern int Dump_metadata(char *dev, char *dir, struct context *c,
+ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 			    struct supertype *st, int only);
+ 
++int md_array_active(int fd);
+ int md_get_array_info(int fd, struct mdu_array_info_s *array);
+ int md_set_array_info(int fd, struct mdu_array_info_s *array);
+ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk);
+diff --git a/util.c b/util.c
+index a695c45..3adc675 100644
+--- a/util.c
++++ b/util.c
+@@ -200,6 +200,33 @@ out:
+ 	return ret;
+ }
+ 
++int md_array_active(int fd)
++{
++	struct mdinfo *sra;
++	struct mdu_array_info_s array;
++	int ret;
++
++	sra = sysfs_read(fd, NULL, GET_ARRAY_STATE);
++	if (sra) {
++		if (sra->array_state != ARRAY_CLEAR &&
++		    sra->array_state != ARRAY_INACTIVE &&
++		    sra->array_state != ARRAY_UNKNOWN_STATE)
++			ret = 0;
++		else
++			ret = -ENODEV;
++
++		free(sra);
++	} else {
++		/*
++		 * GET_ARRAY_INFO doesn't provide access to the proper state
++		 * information, so fallback to a basic check for raid_disks != 0
++		 */
++		ret = ioctl(fd, GET_ARRAY_INFO, &array);
++	}
++
++	return !ret;
++}
++
+ /*
+  * Get array info from the kernel. Longer term we want to deprecate the
+  * ioctl and get it from sysfs.
+-- 
+2.7.4
+
diff --git a/SOURCES/util-md_array_valid-Introduce5-md_array_valid-helper.patch b/SOURCES/util-md_array_valid-Introduce5-md_array_valid-helper.patch
new file mode 100644
index 0000000..f8cf036
--- /dev/null
+++ b/SOURCES/util-md_array_valid-Introduce5-md_array_valid-helper.patch
@@ -0,0 +1,91 @@
+From 9db2ab4e9b1ad79b9364b6e03bdd675716a688a5 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <jsorensen@fb.com>
+Date: Wed, 3 May 2017 14:25:57 -0400
+Subject: [RHEL7.5 PATCH 106/169] util: md_array_valid(): Introduce
+ md_array_valid() helper
+
+Using md_get_array_info() to determine if an array is valid is broken
+during creation, since the ioctl() returns -ENODEV if the device is
+valid but not active.
+
+Where did I leave my stash of brown paper bags?
+
+Fixes: ("40b054e mdopen/open_mddev: Use md_get_array_info() to determine valid array")
+Signed-off-by: Jes Sorensen <jsorensen@fb.com>
+---
+ mdadm.h  |  1 +
+ mdopen.c |  3 +--
+ util.c   | 24 ++++++++++++++++++++++++
+ 3 files changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/mdadm.h b/mdadm.h
+index 6a382a7..07ee963 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -1415,6 +1415,7 @@ extern int Dump_metadata(char *dev, char *dir, struct context *c,
+ extern int Restore_metadata(char *dev, char *dir, struct context *c,
+ 			    struct supertype *st, int only);
+ 
++int md_array_valid(int fd);
+ int md_array_active(int fd);
+ int md_get_array_info(int fd, struct mdu_array_info_s *array);
+ int md_set_array_info(int fd, struct mdu_array_info_s *array);
+diff --git a/mdopen.c b/mdopen.c
+index 099efa0..c4f1c12 100644
+--- a/mdopen.c
++++ b/mdopen.c
+@@ -442,7 +442,6 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
+  */
+ int open_mddev(char *dev, int report_errors)
+ {
+-	struct mdu_array_info_s array;
+ 	int mdfd = open(dev, O_RDONLY);
+ 
+ 	if (mdfd < 0) {
+@@ -452,7 +451,7 @@ int open_mddev(char *dev, int report_errors)
+ 		return -1;
+ 	}
+ 
+-	if (md_get_array_info(mdfd, &array) != 0) {
++	if (md_array_valid(mdfd) == 0) {
+ 		close(mdfd);
+ 		if (report_errors)
+ 			pr_err("%s does not appear to be an md device\n", dev);
+diff --git a/util.c b/util.c
+index 21a63c9..c7585ac 100644
+--- a/util.c
++++ b/util.c
+@@ -200,6 +200,30 @@ out:
+ 	return ret;
+ }
+ 
++int md_array_valid(int fd)
++{
++	struct mdinfo *sra;
++	int ret;
++
++	sra = sysfs_read(fd, NULL, GET_ARRAY_STATE);
++	if (sra) {
++		if (sra->array_state != ARRAY_UNKNOWN_STATE)
++			ret = 0;
++		else
++			ret = -ENODEV;
++
++		free(sra);
++	} else {
++		/*
++		 * GET_ARRAY_INFO doesn't provide access to the proper state
++		 * information, so fallback to a basic check for raid_disks != 0
++		 */
++		ret = ioctl(fd, RAID_VERSION);
++	}
++
++	return !ret;
++}
++
+ int md_array_active(int fd)
+ {
+ 	struct mdinfo *sra;
+-- 
+2.7.4
+
diff --git a/SOURCES/util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch b/SOURCES/util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch
new file mode 100644
index 0000000..5031a88
--- /dev/null
+++ b/SOURCES/util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch
@@ -0,0 +1,37 @@
+From f5c924f441cedce2a13c48b12be35250560ee575 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 14:01:30 -0400
+Subject: [RHEL7.5 PATCH 052/169] util/must_be_container: Use
+ sysfs_read(GET_VERSION) to determine valid array
+
+Use sysfs_read() instead of ioctl(RAID_VERSION) to determine this is
+in fact a valid raid array fd.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ util.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/util.c b/util.c
+index 9fc7ba0..56daee3 100644
+--- a/util.c
++++ b/util.c
+@@ -1376,9 +1376,14 @@ int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep)
+  */
+ int must_be_container(int fd)
+ {
++	struct mdinfo *mdi;
+ 	unsigned long long size;
+-	if (md_get_version(fd) < 0)
++
++	mdi = sysfs_read(fd, NULL, GET_VERSION);
++	if (!mdi)
+ 		return 0;
++	sysfs_free(mdi);
++
+ 	if (get_dev_size(fd, NULL, &size) == 0)
+ 		return 1;
+ 	if (size == 0)
+-- 
+2.7.4
+
diff --git a/SOURCES/util-set_array_info-Simplify-code-since-md_get-versi.patch b/SOURCES/util-set_array_info-Simplify-code-since-md_get-versi.patch
new file mode 100644
index 0000000..d290939
--- /dev/null
+++ b/SOURCES/util-set_array_info-Simplify-code-since-md_get-versi.patch
@@ -0,0 +1,52 @@
+From 700483a22340f2f25a761acd08e6db87e92d90e9 Mon Sep 17 00:00:00 2001
+From: Jes Sorensen <Jes.Sorensen@gmail.com>
+Date: Wed, 5 Apr 2017 15:06:24 -0400
+Subject: [RHEL7.5 PATCH 053/169] util/set_array_info: Simplify code since
+ md_get_version returns a constant
+
+md_get_version() always returns (0 * 1000) + (90 * 100) + 3, so no
+point in calling it.
+
+Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
+---
+ util.c | 19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+diff --git a/util.c b/util.c
+index 56daee3..afeb6a5 100644
+--- a/util.c
++++ b/util.c
+@@ -1858,22 +1858,19 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
+ 	 * This varies between externally managed arrays
+ 	 * and older kernels
+ 	 */
+-	int vers = md_get_version(mdfd);
++	mdu_array_info_t inf;
+ 	int rv;
+ 
+ #ifndef MDASSEMBLE
+ 	if (st->ss->external)
+-		rv = sysfs_set_array(info, vers);
+-	else
++		return sysfs_set_array(info, 9003);
+ #endif
+-		if ((vers % 100) >= 1) { /* can use different versions */
+-		mdu_array_info_t inf;
+-		memset(&inf, 0, sizeof(inf));
+-		inf.major_version = info->array.major_version;
+-		inf.minor_version = info->array.minor_version;
+-		rv = md_set_array_info(mdfd, &inf);
+-	} else
+-		rv = md_set_array_info(mdfd, NULL);
++		
++	memset(&inf, 0, sizeof(inf));
++	inf.major_version = info->array.major_version;
++	inf.minor_version = info->array.minor_version;
++	rv = md_set_array_info(mdfd, &inf);
++
+ 	return rv;
+ }
+ 
+-- 
+2.7.4
+
diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec
index a8f19b8..360a5c9 100644
--- a/SPECS/mdadm.spec
+++ b/SPECS/mdadm.spec
@@ -1,7 +1,7 @@
 Summary:     The mdadm program controls Linux md devices (software RAID arrays)
 Name:        mdadm
 Version:     4.0
-Release:     5%{?dist}
+Release:     13%{?dist}
 Source:      http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz
 Source1:     mdmonitor.init
 Source2:     raid-check
@@ -12,30 +12,208 @@ Source6:     mdmonitor.service
 Source7:     mdadm.conf
 Source8:     mdadm_event.conf
 
-Patch1:      add-man-page-for-symlinks.patch
-Patch2:      specify-enough-length-when-write-to-buffer.patch
-Patch3:      generic-support-for-consistency-policy-and-PPL.patch
-Patch4:      detail-show-consistency-policy.patch
-Patch5:      imsmppl-support.patch
-Patch6:      super1-ppl-support.patch
-Patch7:      add-ppl-and-no-ppl-options-for-update.patch
-Patch8:      support-consistency-policy-change.patch
-Patch9:      imsm-use-rounded-size-for-metadata-initialization.patch
-Patch10:     allow-drives-in-a-container-regardless-of-sector-size.patch
-Patch11:     allocate-buffer-to-support-maximum-sector-size.patch
-Patch12:     dont-allow-disks-with-different-sector-size-in-one.patch
-Patch13:     Allow-more-spare-selection-criteria.patch
-Patch14:     Add-sector-size-as-spare-selection-criterion.patch
-Patch15:     Correct-examine-output-for-4k-disks.patch
-Patch16:     dont-allow-array-geometry-change-with-ppl-enabled.patch
-Patch17:     dont-allow-to-enable-PPL-reshape-in-progress.patch
+Patch1:      Makefile-Fix-date-to-be-output-in-ISO-format.patch
+Patch2:      imsm-fix-missing-error-message-during-migration1.patch
+Patch3:      Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch
+Patch4:      mdadm-fix-typo1-in-comment.patch
+Patch5:      mdadm-check-the-nodes-when-operate-clustered1-array.patch
+Patch6:      examine-tidy-up-some-code.patch
+Patch7:      add-man-page-for-symlinks.patch
+Patch8:      mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch
+Patch9:      mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch
+Patch10:     specify-enough-length-when-write-to-buffer.patch
+Patch11:     mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch
+Patch12:     mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch
+Patch13:     mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch
+Patch14:     mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch
+Patch15:     Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch
+Patch16:     mdadm-Forced-type-conversion-to-avoid-truncation.patch
+Patch17:     super1-ignore-failfast-flag-for-setting-device-role.patch
+Patch18:     mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch
+Patch19:     udev-md-raid-assembly.rules-Skip-non-ready-devices.patch
+Patch20:     Retry-HOT_REMOVE_DISK-a-few-times.patch
+Patch21:     mdadm-Build1-check-the-level-parameter-when-build-new.patch
+Patch22:     Introduce1-sys_hot_remove_disk.patch
+Patch23:     Add-force-flag1-to-hot_remove_disk.patch
+Patch24:     Detail-handle-non-existent-arrays-better.patch
+Patch25:     generic-support-for-consistency-policy-and-PPL.patch
+Patch26:     detail-show-consistency-policy.patch
+Patch27:     imsmppl-support.patch
+Patch28:     super1ppl-support.patch
+Patch29:     add-ppl-and-no-ppl-options-for-update.patch
+Patch30:     support-consistency-policy1-change.patch
+Patch31:     mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch
+Patch32:     super1-replace-hard-coded-values-with-bit-definition.patch
+Patch33:     mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch
+Patch34:     mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch
+Patch35:     util-Cosmetic-changes.patch
+Patch36:     Grow-Fixup-a-pile-of-cosmetic-issues.patch
+Patch37:     util-Introduce2-md_get_array_info.patch
+Patch38:     Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch
+Patch39:     util-Introduce3-md_get_disk_info.patch
+Patch40:     util-Introduce4-md_set_array_info.patch
+Patch41:     md_u-Remove-some-unused-ioctl-declarations.patch
+Patch42:     Grow-Remove-unnecessary-optimization.patch
+Patch43:     Grow-Do-not-shadow-an-existing-variable.patch
+Patch44:     mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch
+Patch45:     imsm-use-rounded-size-for-metadata-initialization.patch
+Patch46:     mdadm.c-fix-compile-error-switch-condition-has-boole.patch
+Patch47:     sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch
+Patch48:     sysfs-Make-sysfs_init-return-an-error-code.patch
+Patch49:     mdadm-Create-declaring1-an-existing-struct-within-sam.patch
+Patch50:     Create-Fixup-bad-placement-of-logical-in-multi-line-.patch
+Patch51:     Create-Fixup-various-whitespace-issues1.patch
+Patch52:     util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch
+Patch53:     util-set_array_info-Simplify-code-since-md_get-versi.patch
+Patch54:     Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch
+Patch55:     Build2-Stop-bothering-about-supporting-md-driver-olde.patch
+Patch56:     Grow-Stop-bothering-about-md-driver-versions-older-t.patch
+Patch57:     Detail-Stop-bothering1-about-md-drivers-older-than-0..patch
+Patch58:     Create-Remove-all-attemps-to-handle-md-driver-older-.patch
+Patch59:     Manage-Remove-all-references1-to-md_get_version.patch
+Patch60:     Query-Remove-all-references-to-md_get_version.patch
+Patch61:     bitmap-Remove-use-of-md-get-version1.patch
+Patch62:     mdmon-Stop-bothering-about-md-get-version2.patch
+Patch63:     mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch
+Patch64:     mdassemble-Use-md_get_array_info-to-check-for-valid-.patch
+Patch65:     Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch
+Patch66:     util-Finally-kill-off-md_get_version.patch
+Patch67:     mdadm-Fail-for-kernels-older-than-2.6.15.patch
+Patch68:     mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch
+Patch69:     Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch
+Patch70:     Retire-mdassemble.patch
+Patch71:     super1-Clean-up-various-style-abuses.patch
+Patch72:     mdopen-use-parameters-new_array-to-create-arrays-whe.patch
+Patch73:     mdadm-manpage-update-manpage-for-readonly-parameter.patch
+Patch74:     mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch
+Patch75:     Assemble-Clean1-up-start_array.patch
+Patch76:     Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch
+Patch77:     Assemble-Remove-obsolete-test-for-kernels1-older-than.patch
+Patch78:     Detail-Fixup-ugly-if-foo-abuse.patch
+Patch79:     Query-Handle-error-returned-by-fstat.patch
+Patch80:     Query-Use-sysfs-to-obtain-data-if-possible.patch
+Patch81:     sysfs-Parse-array_state-in-sysfs_read.patch
+Patch82:     util-Introduce6-md_array_active-helper.patch
+Patch83:     maps-Terminate-modes-map-correctly.patch
+Patch84:     maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch
+Patch85:     util-Get-rid-of-unused-enoughfd.patch
+Patch86:     mdadm-retire-mdassemble-in-make-everything.patch
+Patch87:     Grow_continue_command-ensure-content-is-properly-ini.patch
+Patch88:     systemd-mdadm-last-resort-use-ConditionPathExists-in.patch
+Patch89:     Detail-ensure-export-names-are-acceptable-as-shell-v.patch
+Patch90:     Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch
+Patch91:     Makefile-Default-to-O2-optimization1.patch
+Patch92:     maps-Remove-incorrect-comment-about-strcmp.patch
+Patch93:     maps-Simplify-implementation-of-map_name.patch
+Patch94:     Don-t-use-UnSet-with-consistency_policy.patch
+Patch95:     Detail-determine2-array-state-from-sysfs.patch
+Patch96:     Detail-Respect-code-lines-are-80-character-wide.patch
+Patch97:     Detail-Reinstate-support-for-not-having-sysfs.patch
+Patch98:     Incremental-Use-md_array_active-where-applicable.patch
+Patch99:     Incremental-Cleanup-some-if-statement-spaghetti.patch
+Patch100:    Create-tell-udev-md-device-is-not-ready-when-first-c.patch
+Patch101:    Incremental-Use-md_array_active-to-determine3-state-o.patch
+Patch102:    Manage-Manage-ro-Use-md_array_active.patch
+Patch103:    IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch
+Patch104:    Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch
+Patch105:    change-back-0644-permission-for-Grow.c.patch
+Patch106:    util-md_array_valid-Introduce5-md_array_valid-helper.patch
+Patch107:    kernel-patch-Remove-obsolete-kernel-patches-against-.patch
+Patch108:    mdassemble-Kill-off-the-last-remains.patch
+Patch109:    mdadm-util-unify-fstat-checking-blkdev1-into-function.patch
+Patch110:    mdadm-util-unify-stat-checking-blkdev-into-function.patch
+Patch111:    Fix-typo2-in-new-udev-rule.patch
+Patch112:    Incremental-returnis-not-a-function.patch
+Patch113:    sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch
+Patch114:    container_members_max-degradation-Switch-to-using-sy.patch
+Patch115:    IncrementalScan-Use-md_array_active-instead-of-mdge.patch
+Patch116:    Mention-endian-in-documentation-for-update-byte-orde.patch
+Patch117:    Monitor-Use-md_array_active-instead-of-manually-fidd.patch
+Patch118:    Monitor-Code-is-80-characters-per-line.patch
+Patch119:    mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch
+Patch120:    allow-drives-in-a-container-regardless-of-sector-size.patch
+Patch121:    allocate-buffer-to-support-maximum-sector-size.patch
+Patch122:    dont-allow-disks-with-different-sector-sizein-one.patch
+Patch123:    Allow-more-spare-selection-criteria.patch
+Patch124:    Add-sector-size-as-spare-selection-criterion.patch
+Patch125:    Monitor-check_array-Centralize-exit-path.patch
+Patch126:    Monitor-check_array-reduce-duplicated-error-handling.patch
+Patch127:    Monitor-check_array-declate-mdinfo-instance-globally.patch
+Patch128:    Monitor-check_array-Read-sysfs-entry-earlier.patch
+Patch129:    Monitor-check_array-Obtain-RAID-level-fromsyfs.patch
+Patch130:    Monitor-check_array-Get-faileddisks-from-sysfs.patch
+Patch131:    Monitor-check_array-Get-arraydisks-from-sysfs.patch
+Patch132:    Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch
+Patch133:    sysfs-sysfs_read-Count-workingdisks.patch
+Patch134:    Monitor-checkarray-Use-working_disks-from-sysfs.patch
+Patch135:    Correct-examine-output-for-4kdisks.patch
+Patch136:    retire-the-APIs-that-driver-nolonger-supports.patch
+Patch137:    Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch
+Patch138:    Monitor-mailfrom-is-initialized-correctly.patch
+Patch139:    Monitor-Fixup-apile-of-whitespace-issues.patch
+Patch140:    mdadm-Uninitialized-variable-rdev.patch
+Patch141:    super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch
+Patch142:    mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch
+Patch143:    mdadm-Fixup-morebroken-logical-operator-formatting.patch
+Patch144:    mdadm-Fix-broken-formatting1.patch
+Patch145:    mdadm-Fixup-broken-formatting2.patch
+Patch146:    manpage-badblock-support-for-IMSM.patch
+Patch147:    Detail-don-t-exit-if-ioctl-has-been-successful.patch
+Patch148:    super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch
+Patch149:    md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch
+Patch150:    Grow-set-component-size-prior-to-array-size.patch
+Patch151:    Get-failed-disk-count-fromarray-state.patch
+Patch152:    dont-allow-array-geometry-change-with-ppl-enabled.patch
+Patch153:    dont-allow-to-enable-PPL-reshape-in-progress.patch
+Patch154:    mdadm-test-Convert-code-formatto-use-Tab.patch
+Patch155:    mdadm-test-Refactor-and-revamp-test-script.patch
+Patch156:    mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch
+Patch157:    mdadm-test-Add-disks-to-support-testing-phsical-devi.patch
+Patch158:    Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch
+Patch159:    super1-Always-round-data-offset-to-1M.patch
+Patch160:    mdadm-r5cache-allow-adding-journal-to-array-without-.patch
+Patch161:    Detail-correct-outputfor-active-arrays.patch
+Patch162:    imsm-rebuild-from-2-disk-RAID10.patch
+Patch163:    Error-messages-should-end-with-a-newline-character.patch
+Patch164:    Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch
+Patch165:    super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch
+Patch166:    Don-t-use-exit-ERANGE.patch
+Patch167:    Monitor-containers-don-t-have-the-same-sysfs-propert.patch
+Patch168:    Monitor-Include-containers-in-spare-migration2.patch
+Patch169:    Detail-differentiate-between-container-and-inactive-.patch
+Patch170:    mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch
+Patch171:    mdadm-install-twomore-udev-rules-in-mdadm.spec.patch
+Patch172:    mdadm-set-journal_clean-after-scanning-all-disks.patch
+Patch173:    lib-devid2kname-should-take-a-dev_t.patch
+Patch174:    sysfs_init_dev-takea-dev_t-argument.patch
+Patch175:    Manage-subdevs-Use-a-dev_t.patch
+Patch176:    util-Code-is-80-characterswide.patch
+#The above patches are backported from RHEL7.5 upstream rebase
+Patch177:    Don-t-abort-starting-the-array-if-kernel-does-not-su.patch
+Patch178:    super1add-support-for-multiple-ppls.patch
+Patch179:    imsmadd-support-for-multiple-ppls.patch
+Patch180:    imsm-validate-multiple-ppls-during-assemble.patch
+Patch181:    Zeroout-whole-ppl-space-during-creation-force-assemb.patch
+Patch182:    imsm-switch-to-multiple-ppls-automatically-during-as.patch
+Patch183:    Grow-fix-switching-on-PPL-during-recovery.patch
+Patch184:    imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch
+Patch185:    imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch
+Patch186:    imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch
+Patch187:    imsm-use-correct-map-when-validating-ppl.patch
+Patch188:    imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch
+Patch189:    mdmon-get-safe-mode-delay-file.patch
+Patch190:    imsm-continue-resync-on-3disk-RAID10.patch
+Patch191:    imsm-Set-disk-slot-number.patch
+Patch192:    managemon-Dont-add-disk-to-the-array-after-it.patch
+Patch193:    Avoid-to-take-spare-without-defined-domain-by-imsm.patch
+Patch194:    stop-previous-reshape-process-first.patch
 
 # RHEL customization patches
-Patch95:     mdadm-3.4-udev-race.patch
-Patch96:     mdadm-3.3.2-skip-rules.patch
-Patch97:     mdadm-3.3-udev.patch
-Patch98:     mdadm-2.5.2-static.patch
-Patch99:     disable-journal.patch
+Patch195:    mdadm-3.4-udev-race.patch
+Patch196:    mdadm-3.3.2-skip-rules.patch
+Patch197:    mdadm-3.3-udev.patch
+Patch198:    mdadm-2.5.2-static.patch
+Patch199:    disable-journal.patch
 URL:         http://www.kernel.org/pub/linux/utils/raid/mdadm/
 License:     GPLv2+
 Group:       System Environment/Base
@@ -51,7 +229,7 @@ Requires: libreport-filesystem
 
 %define _hardened_build 1
 
-%description 
+%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
@@ -61,30 +239,207 @@ file can be used to help with some common tasks.
 %prep
 %setup -q
 
-%patch1 -p1 -b .symlinks
-%patch2 -p1 -b .specify
-%patch3 -p1 -b .generic
-%patch4 -p1 -b .detail
-%patch5 -p1 -b .imsmppl
-%patch6 -p1 -b .super1
-%patch7 -p1 -b .options
-%patch8 -p1 -b .change
-%patch9 -p1 -b .rounded
-%patch10 -p1 -b .regardless
-%patch11 -p1 -b .maximum
-%patch12 -p1 -b .different
-%patch13 -p1 -b .criteria
-%patch14 -p1 -b .criterion
-%patch15 -p1 -b .output
-%patch16 -p1 -b .pplgeometry
-%patch17 -p1 -b .pplreshape
+%patch1  -p1 -b .ISO
+%patch2  -p1 -b .migration1
+%patch3  -p1 -b .oddity
+%patch4  -p1 -b .typo1
+%patch5  -p1 -b .clustered1
+%patch6  -p1 -b .tidy
+%patch7  -p1 -b .symlinks
+%patch8  -p1 -b .clustered2
+%patch9  -p1 -b .Wimplicit
+%patch10 -p1 -b .specify
+%patch11 -p1 -b .trivial
+%patch12 -p1 -b .twice
+%patch13 -p1 -b .invoked
+%patch14 -p1 -b .dereference
+%patch15 -p1 -b .Replace
+%patch16 -p1 -b .Forced
+%patch17 -p1 -b .ignore
+%patch18 -p1 -b .comments1
+%patch19 -p1 -b .assembly
+%patch20 -p1 -b .Retry
+%patch21 -p1 -b .Build1
+%patch22 -p1 -b .Introduce1
+%patch23 -p1 -b .force
+%patch24 -p1 -b .existent
+%patch25 -p1 -b .generic
+%patch26 -p1 -b .detail
+%patch27 -p1 -b .imsmppl
+%patch28 -p1 -b .super1ppl
+%patch29 -p1 -b .options
+%patch30 -p1 -b .policy1
+%patch31 -p1 -b .reorganize
+%patch32 -p1 -b .hard
+%patch33 -p1 -b .multiple
+%patch34 -p1 -b .inconsistency
+%patch35 -p1 -b .Cosmetic
+%patch36 -p1 -b .cosmetic
+%patch37 -p1 -b .Introduce2
+%patch38 -p1 -b .redundant
+%patch39 -p1 -b .Introduce3
+%patch40 -p1 -b .Introduce4
+%patch41 -p1 -b .declarations
+%patch42 -p1 -b .unnecessary
+%patch43 -p1 -b .shadow
+%patch44 -p1 -b .would1
+%patch45 -p1 -b .rounded
+%patch46 -p1 -b .switch
+%patch47 -p1 -b .presence
+%patch48 -p1 -b .Make
+%patch49 -p1 -b .declaring1
+%patch50 -p1 -b .multi
+%patch51 -p1 -b .issues1
+%patch52 -p1 -b .container1
+%patch53 -p1 -b .versi
+%patch54 -p1 -b .ver
+%patch55 -p1 -b .Build2
+%patch56 -p1 -b .versions
+%patch57 -p1 -b .bothering1
+%patch58 -p1 -b .attemps
+%patch59 -p1 -b .references1
+%patch60 -p1 -b .references
+%patch61 -p1 -b .version1
+%patch62 -p1 -b .version2
+%patch63 -p1 -b .determine1
+%patch64 -p1 -b .valid
+%patch65 -p1 -b .vers
+%patch66 -p1 -b .Finally
+%patch67 -p1 -b .kernels
+%patch68 -p1 -b .uninitialized
+%patch69 -p1 -b .Revert
+%patch70 -p1 -b .Retire
+%patch71 -p1 -b .abuses
+%patch72 -p1 -b .parameters
+%patch73 -p1 -b .readonly
+%patch74 -p1 -b .clustered3
+%patch75 -p1 -b .Clean1
+%patch76 -p1 -b .pre
+%patch77 -p1 -b .kernels1
+%patch78 -p1 -b .abuse
+%patch79 -p1 -b .Handle
+%patch80 -p1 -b .obtain
+%patch81 -p1 -b .Parse
+%patch82 -p1 -b .Introduce6
+%patch83 -p1 -b .Terminate
+%patch84 -p1 -b .keyvalue
+%patch85 -p1 -b .enoughfd
+%patch86 -p1 -b .everything
+%patch87 -p1 -b .ini
+%patch88 -p1 -b .ConditionPathExists
+%patch89 -p1 -b .export
+%patch90 -p1 -b .Quiet
+%patch91 -p1 -b .optimization1
+%patch92 -p1 -b .incorrect
+%patch93 -p1 -b .implementation
+%patch94 -p1 -b .UnSet
+%patch95 -p1 -b .determine2
+%patch96 -p1 -b .Respect
+%patch97 -p1 -b .Reinstate
+%patch98 -p1 -b .applicable
+%patch99 -p1 -b .Cleanup
+%patch100 -p1 -b .first
+%patch101 -p1 -b .determine3
+%patch102 -p1 -b .ro
+%patch103 -p1 -b .Initialize
+%patch104 -p1 -b .vari
+%patch105 -p1 -b .back
+%patch106 -p1 -b .Introduce5
+%patch107 -p1 -b .against
+%patch108 -p1 -b .remains
+%patch109 -p1 -b .blkdev1
+%patch110 -p1 -b .blkdev
+%patch111 -p1 -b .typo2
+%patch112 -p1 -b .returnis
+%patch113 -p1 -b .activedisks
+%patch114 -p1 -b .degradation
+%patch115 -p1 -b .mdge
+%patch116 -p1 -b .orde
+%patch117 -p1 -b .fidd
+%patch118 -p1 -b .characters
+%patch119 -p1 -b .warnings
+%patch120 -p1 -b .regardless
+%patch121 -p1 -b .allocate
+%patch122 -p1 -b .sizein
+%patch123 -p1 -b .criteria
+%patch124 -p1 -b .criterion
+%patch125 -p1 -b .Centralize
+%patch126 -p1 -b .reduce
+%patch127 -p1 -b .declate
+%patch128 -p1 -b .earlier
+%patch129 -p1 -b .fromsyfs
+%patch130 -p1 -b .faileddisks
+%patch131 -p1 -b .arraydisks
+%patch132 -p1 -b .nrdisks
+%patch133 -p1 -b .workingdisks
+%patch134 -p1 -b .checkarray
+%patch135 -p1 -b .4kdisks
+%patch136 -p1 -b .nolonger
+%patch137 -p1 -b .fork
+%patch138 -p1 -b .mailfrom
+%patch139 -p1 -b .apile
+%patch140 -p1 -b .rdev
+%patch141 -p1 -b .devicename
+%patch142 -p1 -b .logi
+%patch143 -p1 -b .morebroken
+%patch144 -p1 -b .formatting1
+%patch145 -p1 -b .formatting2
+%patch146 -p1 -b .badblock
+%patch147 -p1 -b .successful
+%patch148 -p1 -b .inline
+%patch149 -p1 -b .declaration
+%patch150 -p1 -b .prior
+%patch151 -p1 -b .fromarray
+%patch152 -p1 -b .pplgeometry
+%patch153 -p1 -b .pplreshape
+%patch154 -p1 -b .formatto
+%patch155 -p1 -b .revamp
+%patch156 -p1 -b .raidlevel
+%patch157 -p1 -b .phsical
+%patch158 -p1 -b .blockdevi
+%patch159 -p1 -b .offset
+%patch160 -p1 -b .without
+%patch161 -p1 -b .outputfor
+%patch162 -p1 -b .rebuild
+%patch163 -p1 -b .newline
+%patch164 -p1 -b .fro
+%patch165 -p1 -b .flag2
+%patch166 -p1 -b .ERANGE
+%patch167 -p1 -b .propert
+%patch168 -p1 -b .migration2
+%patch169 -p1 -b .differentiate
+%patch170 -p1 -b .failed1
+%patch171 -p1 -b .twomore
+%patch172 -p1 -b .scanning
+%patch173 -p1 -b .devid2kname
+%patch174 -p1 -b .takea
+%patch175 -p1 -b .subdevs
+%patch176 -p1 -b .characterswide
+%patch177 -p1 -b .abort
+%patch178 -p1 -b .super1add
+%patch179 -p1 -b .imsmadd
+%patch180 -p1 -b .validate
+%patch181 -p1 -b .Zeroout
+%patch182 -p1 -b .automatically
+%patch183 -p1 -b .switching
+%patch184 -p1 -b .invalid
+%patch185 -p1 -b .assembling
+%patch186 -p1 -b .rebuildi
+%patch187 -p1 -b .validating
+%patch188 -p1 -b .initial
+%patch189 -p1 -b .safe
+%patch190 -p1 -b .3disk
+%patch191 -p1 -b .slot
+%patch192 -p1 -b .Dont
+%patch193 -p1 -b .defined
+%patch194 -p1 -b .previous
 
 # RHEL customization patches
-%patch95 -p1 -b .race
-%patch96 -p1 -b .rules
-%patch97 -p1 -b .udev
-%patch98 -p1 -b .static
-%patch99 -p1 -b .journal
+%patch195 -p1 -b .race
+%patch196 -p1 -b .rules
+%patch197 -p1 -b .udev
+%patch198 -p1 -b .static
+%patch199 -p1 -b .disable
 
 %build
 make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon
@@ -146,13 +501,45 @@ rm -rf %{buildroot}
 /etc/libreport/events.d/*
 
 %changelog
+* Wed Feb 07 2018 Xiao Ni <xni@redhat.com> - 4.0-13
+- stop previous reshape process first 
+- Resolves rhbz#1507415
+
+* Wed Jan 31 2018 Xiao Ni <xni@redhat.com> - 4.0-12
+- Don't take spare without defined domain by imsm
+- Resolves rhbz#1535436
+
+* Fri Jan 12 2018 Xiao Ni <xni@redhat.com> - 4.0-11
+- Fix some IMSM bugs 
+- Resolves rhbz#1507439 rhbz#1516800 rhbz#1528267
+
+* Mon Dec 11 2017 Xiao Ni <xni@redhat.com> - 4.0-10
+- Disable raid5 journal function
+- Resolves rhbz#1518477
+
+* Fri Nov 03 2017 Xiao Ni <xni@redhat.com> - 4.0-9
+- Enable raid5 journal function
+- Resolves rhbz1505611
+
+* Fri Nov 03 2017 Xiao Ni <xni@redhat.com> - 4.0-8
+- Support for multiple-ppl in mdadm
+- Resolves rhbz#1500638
+
+* Fri Nov 03 2017 Xiao Ni <xni@redhat.com> - 4.0-7
+- Support adding flags for mdmonitor.service
+- Resolves rhbz#1320018
+
+* Mon Sep 18 2017 Xiao Ni <xni@redhat.com> - 4.0-6
+- Update to the latest upstream
+- Resolves rhbz#1455936
+
 * Mon Jun 12 2017 Nigel Croxon <ncroxon@redhat.com> - 4.0-5
 - RAID array grow not blocked when PPL is enabled
 - Resolves rhbz#1460141
 
 * Wed May 31 2017 Xiao Ni <xni@redhat.com> - 4.0-4
-- Imsm should not allow combing 512 and 4096 sector size disks in 
-  one volume and Wrong array size shown for array built on 4096 
+- Imsm should not allow combing 512 and 4096 sector size disks in
+  one volume and Wrong array size shown for array built on 4096
   sector size disks
 - Resolves rhbz#1454390 and rhbz#1454379
 
@@ -178,7 +565,7 @@ rm -rf %{buildroot}
   these can show up with a valid size of 0. Work around this to only
   exit for non container arrays.
 - Resolves rhbz#1379194
-  
+
 * Wed Sep 14 2016 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.4-13
 - Make udev-md-array-arrays.rules more resilient to races if arrays are
   assembled and stopped and reassembled quick after each other.
@@ -225,7 +612,7 @@ rm -rf %{buildroot}
 - Resolves rhbz#1324637
 
 * Thu Apr 28 2016 Xiao Ni <xni@redhat.com> - 3.4-3
-- Fix Degraded Raid1 array becomes inactive after rebooting 
+- Fix Degraded Raid1 array becomes inactive after rebooting
 - Resolves rhbz#1290494
 
 * Tue Mar 1 2016 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.4-2
@@ -312,7 +699,7 @@ rm -rf %{buildroot}
 
 * Thu Oct 10 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-22
 - Check for DM_UDEV_DISABLE_OTHER_RULES_FLAG instead of
-  DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules 
+  DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules
 - Resolves bz1015515
 
 * Thu Aug 29 2013 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.6-21
@@ -323,7 +710,7 @@ rm -rf %{buildroot}
 
 * 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 
+  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
@@ -436,7 +823,7 @@ rm -rf %{buildroot}
 
 * 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  
+  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
@@ -511,7 +898,7 @@ rm -rf %{buildroot}
 * 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 
+  O_DIRECT
 - Resolves: bz789898 (f16) bz791189 (f15)
 
 * Mon Jan 30 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-4
@@ -811,7 +1198,7 @@ rm -rf %{buildroot}
 - 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 
+- 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
 
@@ -866,7 +1253,7 @@ rm -rf %{buildroot}
 * 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)