From 38bb4bcdeea31ff4a2ffa34dd74f1ae80f40ebda Mon Sep 17 00:00:00 2001 From: Mateusz Kozlowski Date: Fri, 14 Jun 2019 16:24:42 +0200 Subject: [PATCH] lib/ftl: Fix I/O alignment in dirty shutdown restore Changed to use 4k alignment in dirty shutdown I/Os. Otherwise the scatter gather lists used in QEMU for underlying file/block device would use an extra entry (e.g. 17 for 16 sector writes), and eventually some I/Os would write to offset 0 in underlying file, corrupting head metadata. Signed-off-by: Mateusz Kozlowski Change-Id: If8c88ce708529b094a09c8ee952912cc22cd53b9 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458090 Reviewed-by: Konrad Sztyber Reviewed-by: Wojciech Malikowski Reviewed-by: Darek Stojaczyk Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- lib/ftl/ftl_restore.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/ftl/ftl_restore.c b/lib/ftl/ftl_restore.c index e269a0537..a5f241ebf 100644 --- a/lib/ftl/ftl_restore.c +++ b/lib/ftl/ftl_restore.c @@ -180,7 +180,6 @@ ftl_restore_check_seq(const struct ftl_restore *restore) for (i = 0; i < ftl_dev_num_bands(dev); ++i) { rband = &restore->bands[i]; - if (rband->md_status != FTL_MD_SUCCESS) { continue; } @@ -533,7 +532,14 @@ ftl_restore_pad_band(struct ftl_restore_band *rband) ppa = band->chunk_buf[i].start_ppa; ppa.lbk = info.wp; - buffer = spdk_dma_zmalloc(FTL_BLOCK_SIZE * dev->xfer_size, sizeof(uint32_t), NULL); + /* + * We need 4k alignment for lightnvm writes; otherwise, due to a bug in QEMU, + * scatter gather lists to underlying block device become broken as the number of + * incoming offsets (dev->xfer_size) would be smaller than the calculated size of + * sgl (dev->xfer_size+1), which eventually results in some part of the write + * hitting offset 0 of the drive, overwriting head_md of band 0. + */ + buffer = spdk_dma_zmalloc(FTL_BLOCK_SIZE * dev->xfer_size, FTL_BLOCK_SIZE, NULL); if (spdk_unlikely(!buffer)) { rc = -ENOMEM; goto error;