Commit 17da389e authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Ben Walker
Browse files

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: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/459615


Reviewed-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarMateusz Kozlowski <mateusz.kozlowski@intel.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 4d7c8162
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -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 (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;
	}