dcavalca / rpms / mdadm

Forked from rpms/mdadm 3 years ago
Clone

Blame SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch

2c1b57
From b251424242b46d62f666829c0e7a7550768fc8de Mon Sep 17 00:00:00 2001
2c1b57
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
2c1b57
Date: Thu, 28 Sep 2017 14:41:11 +0200
2c1b57
Subject: [PATCH 05/12] Zeroout whole ppl space during creation/force
2c1b57
 assemble
2c1b57
2c1b57
PPL area should be cleared before creation/force assemble.
2c1b57
If the drive was used in other RAID array, it might contains PPL from it.
2c1b57
There is a risk that mdadm recognizes those PPLs and
2c1b57
refuses to assemble the RAID due to PPL conflict with created
2c1b57
array.
2c1b57
2c1b57
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
2c1b57
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
2c1b57
---
2c1b57
 mdadm.h       |  1 +
2c1b57
 super-intel.c |  7 ++++++-
2c1b57
 super1.c      |  5 +++++
2c1b57
 util.c        | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
2c1b57
 4 files changed, 61 insertions(+), 1 deletion(-)
2c1b57
2c1b57
diff --git a/mdadm.h b/mdadm.h
2c1b57
index 3fc8a4f..85947bf 100644
2c1b57
--- a/mdadm.h
2c1b57
+++ b/mdadm.h
2c1b57
@@ -687,6 +687,7 @@ extern int sysfs_unique_holder(char *devnm, long rdev);
2c1b57
 extern int sysfs_freeze_array(struct mdinfo *sra);
2c1b57
 extern int sysfs_wait(int fd, int *msec);
2c1b57
 extern int load_sys(char *path, char *buf, int len);
2c1b57
+extern int zero_disk_range(int fd, unsigned long long sector, size_t count);
2c1b57
 extern int reshape_prepare_fdlist(char *devname,
2c1b57
 				  struct mdinfo *sra,
2c1b57
 				  int raid_disks,
2c1b57
diff --git a/super-intel.c b/super-intel.c
2c1b57
index 56dec36..65cdc92 100644
2c1b57
--- a/super-intel.c
2c1b57
+++ b/super-intel.c
2c1b57
@@ -6065,7 +6065,12 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd
2c1b57
 	struct ppl_header *ppl_hdr;
2c1b57
 	int ret;
2c1b57
 
2c1b57
-	ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
2c1b57
+	/* first clear entire ppl space */
2c1b57
+	ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size);
2c1b57
+	if (ret)
2c1b57
+		return ret;
2c1b57
+
2c1b57
+	ret = posix_memalign(&buf, MAX_SECTOR_SIZE, PPL_HEADER_SIZE);
2c1b57
 	if (ret) {
2c1b57
 		pr_err("Failed to allocate PPL header buffer\n");
2c1b57
 		return ret;
2c1b57
diff --git a/super1.c b/super1.c
2c1b57
index f80e38a..7ae6dc3 100644
2c1b57
--- a/super1.c
2c1b57
+++ b/super1.c
2c1b57
@@ -1823,6 +1823,11 @@ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
2c1b57
 	struct ppl_header *ppl_hdr;
2c1b57
 	int ret;
2c1b57
 
2c1b57
+	/* first clear entire ppl space */
2c1b57
+	ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size);
2c1b57
+	if (ret)
2c1b57
+		return ret;
2c1b57
+
2c1b57
 	ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE);
2c1b57
 	if (ret) {
2c1b57
 		pr_err("Failed to allocate PPL header buffer\n");
2c1b57
diff --git a/util.c b/util.c
2c1b57
index 68af381..c11729e 100644
2c1b57
--- a/util.c
2c1b57
+++ b/util.c
2c1b57
@@ -30,6 +30,7 @@
2c1b57
 #include	<sys/un.h>
2c1b57
 #include	<sys/resource.h>
2c1b57
 #include	<sys/vfs.h>
2c1b57
+#include	<sys/mman.h>
2c1b57
 #include	<linux/magic.h>
2c1b57
 #include	<poll.h>
2c1b57
 #include	<ctype.h>
2c1b57
@@ -2334,3 +2335,51 @@ void set_hooks(void)
2c1b57
 	set_dlm_hooks();
2c1b57
 	set_cmap_hooks();
2c1b57
 }
2c1b57
+
2c1b57
+int zero_disk_range(int fd, unsigned long long sector, size_t count)
2c1b57
+{
2c1b57
+	int ret = 0;
2c1b57
+	int fd_zero;
2c1b57
+	void *addr = NULL;
2c1b57
+	size_t written = 0;
2c1b57
+	size_t len = count * 512;
2c1b57
+	ssize_t n;
2c1b57
+
2c1b57
+	fd_zero = open("/dev/zero", O_RDONLY);
2c1b57
+	if (fd_zero < 0) {
2c1b57
+		pr_err("Cannot open /dev/zero\n");
2c1b57
+		return -1;
2c1b57
+	}
2c1b57
+
2c1b57
+	if (lseek64(fd, sector * 512, SEEK_SET) < 0) {
2c1b57
+		ret = -errno;
2c1b57
+		pr_err("Failed to seek offset for zeroing\n");
2c1b57
+		goto out;
2c1b57
+	}
2c1b57
+
2c1b57
+	addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd_zero, 0);
2c1b57
+
2c1b57
+	if (addr == MAP_FAILED) {
2c1b57
+		ret = -errno;
2c1b57
+		pr_err("Mapping /dev/zero failed\n");
2c1b57
+		goto out;
2c1b57
+	}
2c1b57
+
2c1b57
+	do {
2c1b57
+		n = write(fd, addr + written, len - written);
2c1b57
+		if (n < 0) {
2c1b57
+			if (errno == EINTR)
2c1b57
+				continue;
2c1b57
+			ret = -errno;
2c1b57
+			pr_err("Zeroing disk range failed\n");
2c1b57
+			break;
2c1b57
+		}
2c1b57
+		written += n;
2c1b57
+	} while (written != len);
2c1b57
+
2c1b57
+	munmap(addr, len);
2c1b57
+
2c1b57
+out:
2c1b57
+	close(fd_zero);
2c1b57
+	return ret;
2c1b57
+}
2c1b57
-- 
2c1b57
2.7.4
2c1b57