summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorPawel Baldysiak <pawel.baldysiak@intel.com>2017-09-28 14:41:11 +0200
committerJes Sorensen <jsorensen@fb.com>2017-10-02 22:11:42 +0200
commitb251424242b46d62f666829c0e7a7550768fc8de (patch)
treeab6fbd34813d5f301685787eaf8912024f034ec9 /util.c
parentimsm: validate multiple ppls during assemble (diff)
downloadmdadm-b251424242b46d62f666829c0e7a7550768fc8de.tar.xz
mdadm-b251424242b46d62f666829c0e7a7550768fc8de.zip
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>
Diffstat (limited to 'util.c')
-rw-r--r--util.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/util.c b/util.c
index 68af3819..c11729e3 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;
+}