Stripe and bitmap alignment can leave small gaps between resource group spans, and between the superblock and the first resource group. Zero out those blocks so that we don't leave stale data in unused space.
Signed-off-by: Andrew Price <anpr...@redhat.com> --- gfs2/libgfs2/libgfs2.h | 1 + gfs2/libgfs2/rgrp.c | 5 +++++ gfs2/mkfs/main_mkfs.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h index 3a54195c..05e45121 100644 --- a/gfs2/libgfs2/libgfs2.h +++ b/gfs2/libgfs2/libgfs2.h @@ -211,6 +211,7 @@ extern const struct gfs2_rgrp *lgfs2_rgrp_rgrp(lgfs2_rgrp_t rg); extern lgfs2_rgrp_t lgfs2_rgrp_first(lgfs2_rgrps_t rgs); extern lgfs2_rgrp_t lgfs2_rgrp_last(lgfs2_rgrps_t rgs); extern lgfs2_rgrp_t lgfs2_rgrp_next(lgfs2_rgrp_t rg); +extern lgfs2_rgrp_t lgfs2_rgrp_prev(lgfs2_rgrp_t rg); // Temporary function to aid API migration extern struct osi_node *lgfs2_rgrps_root(lgfs2_rgrps_t rgs) __attribute__((deprecated)); diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c index b61c5931..190715e1 100644 --- a/gfs2/libgfs2/rgrp.c +++ b/gfs2/libgfs2/rgrp.c @@ -719,6 +719,11 @@ lgfs2_rgrp_t lgfs2_rgrp_next(lgfs2_rgrp_t rg) return (lgfs2_rgrp_t)osi_next(&rg->node); } +lgfs2_rgrp_t lgfs2_rgrp_prev(lgfs2_rgrp_t rg) +{ + return (lgfs2_rgrp_t)osi_prev(&rg->node); +} + lgfs2_rgrp_t lgfs2_rgrp_last(lgfs2_rgrps_t rgs) { return (lgfs2_rgrp_t)osi_last(&rgs->root); diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c index 297ff7a3..846b341f 100644 --- a/gfs2/mkfs/main_mkfs.c +++ b/gfs2/mkfs/main_mkfs.c @@ -613,6 +613,42 @@ static void warn_of_destruction(const char *path) free(abspath); } +static int zero_gap(struct gfs2_sbd *sdp, uint64_t addr, size_t blocks) +{ + struct iovec *iov; + char *zerobuf; + ssize_t wrote; + unsigned i; + + if (blocks == 0) + return 0; + iov = calloc(blocks, sizeof(*iov)); + if (iov == NULL) { + perror(_("Failed to zero blocks\n")); + return 1; + } + zerobuf = calloc(1, sdp->bsize); + if (zerobuf == NULL) { + perror(_("Failed to zero blocks\n")); + free(iov); + return 1; + } + for (i = 0; i < blocks; i++) { + iov[i].iov_base = zerobuf; + iov[i].iov_len = sdp->bsize; + } + wrote = pwritev(sdp->device_fd, iov, blocks, addr * sdp->bsize); + if (wrote != blocks * sdp->bsize) { + fprintf(stderr, _("Zeroing write failed at block %"PRIu64"\n"), addr); + free(zerobuf); + free(iov); + return 1; + } + free(zerobuf); + free(iov); + return 0; +} + static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp) { lgfs2_rgrps_t rgs; @@ -665,9 +701,18 @@ static lgfs2_rgrps_t rgs_init(struct mkfs_opts *opts, struct gfs2_sbd *sdp) static int place_rgrp(struct gfs2_sbd *sdp, lgfs2_rgrp_t rg, int debug) { - int err = 0; + uint64_t prev_end = (GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->bsize) + 1; const struct gfs2_rindex *ri = lgfs2_rgrp_index(rg); + lgfs2_rgrp_t prev = lgfs2_rgrp_prev(rg); + int err = 0; + if (prev != NULL) { + prev_end = lgfs2_rgrp_index(prev)->ri_data0 + + lgfs2_rgrp_index(prev)->ri_data; + } + err = zero_gap(sdp, prev_end, ri->ri_addr - prev_end); + if (err != 0) + return -1; err = lgfs2_rgrp_write(sdp->device_fd, rg); if (err != 0) { perror(_("Failed to write resource group")); -- 2.16.2