lib/ftl: delay writing band's metadata
Wait until all user writes are completed before writing band's metadata. Otherwise in case of power loss, user data might not get written while the metadata does, which would result in data loss. Change-Id: I419862960c072e38265b91d0d0498ff0c6f9f29e Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/459615 Reviewed-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
4d7c81625c
commit
17da389ecc
@ -76,6 +76,9 @@ struct ftl_wptr {
|
||||
* The PPA is not assigned by wptr, and is instead taken directly from the request.
|
||||
*/
|
||||
bool direct_mode;
|
||||
|
||||
/* Number of outstanding write requests */
|
||||
uint32_t num_outstanding;
|
||||
};
|
||||
|
||||
struct ftl_flush {
|
||||
@ -140,7 +143,6 @@ ftl_io_cmpl_cb(void *arg, const struct spdk_nvme_cpl *status)
|
||||
ftl_trace_completion(io->dev, io, FTL_TRACE_COMPLETION_DISK);
|
||||
|
||||
ftl_io_dec_req(io);
|
||||
|
||||
if (ftl_io_done(io)) {
|
||||
ftl_io_complete(io);
|
||||
}
|
||||
@ -575,10 +577,13 @@ ftl_wptr_ready(struct ftl_wptr *wptr)
|
||||
}
|
||||
|
||||
if (band->state == FTL_BAND_STATE_FULL) {
|
||||
if (ftl_wptr_close_band(wptr)) {
|
||||
/* TODO: need recovery here */
|
||||
assert(false);
|
||||
if (wptr->num_outstanding == 0) {
|
||||
if (ftl_wptr_close_band(wptr)) {
|
||||
/* TODO: need recovery here */
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -587,6 +592,7 @@ ftl_wptr_ready(struct ftl_wptr *wptr)
|
||||
/* TODO: need recovery here */
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1363,10 +1369,14 @@ static void
|
||||
ftl_io_child_write_cb(struct ftl_io *io, void *ctx, int status)
|
||||
{
|
||||
struct ftl_chunk *chunk;
|
||||
struct ftl_wptr *wptr;
|
||||
|
||||
chunk = ftl_band_chunk_from_ppa(io->band, io->ppa);
|
||||
wptr = ftl_wptr_from_band(io->band);
|
||||
|
||||
chunk->busy = false;
|
||||
chunk->write_offset += io->lbk_cnt;
|
||||
wptr->num_outstanding--;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1392,16 +1402,17 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
wptr->num_outstanding++;
|
||||
rc = spdk_nvme_ns_cmd_write_with_md(dev->ns, ftl_get_write_qpair(dev),
|
||||
ftl_io_iovec_addr(child), child->md,
|
||||
ftl_ppa_addr_pack(dev, ppa),
|
||||
lbk_cnt, ftl_io_cmpl_cb, child, 0, 0, 0);
|
||||
if (rc) {
|
||||
wptr->num_outstanding--;
|
||||
ftl_io_fail(child, rc);
|
||||
ftl_io_complete(child);
|
||||
SPDK_ERRLOG("spdk_nvme_ns_cmd_write failed with status:%d, ppa:%lu\n",
|
||||
SPDK_ERRLOG("spdk_nvme_ns_cmd_write_with_md failed with status:%d, ppa:%lu\n",
|
||||
rc, ppa.ppa);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user