From: Pawel Baldysiak Date: Thu, 28 Sep 2017 12:41:11 +0000 (+0200) Subject: Zeroout whole ppl space during creation/force assemble X-Git-Tag: mdadm-4.1-rc1~71 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=b251424242b46d62f666829c0e7a7550768fc8de 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 Signed-off-by: Jes Sorensen --- diff --git a/mdadm.h b/mdadm.h index 3fc8a4fb..85947bf6 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 56dec365..65cdc925 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 f80e38af..7ae6dc32 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 68af3819..c11729e3 100644 --- a/util.c +++ b/util.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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; +}