diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index c830605cf..b3017947f 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -290,16 +290,17 @@ ftl_submit_erase(struct ftl_io *io) assert(ppa.lbk == 0); ppa_packed = ftl_ppa_addr_pack(dev, ppa); - ftl_io_inc_req(io); - ftl_trace_submission(dev, io, ppa, 1); rc = spdk_nvme_ocssd_ns_cmd_vector_reset(dev->ns, ftl_get_write_qpair(dev), &ppa_packed, 1, NULL, ftl_io_cmpl_cb, io); if (rc) { + ftl_io_fail(io, rc); SPDK_ERRLOG("Vector reset failed with status: %d\n", rc); - ftl_io_dec_req(io); break; } + + ftl_io_inc_req(io); + ftl_io_advance(io, 1); } if (ftl_io_done(io)) { @@ -720,7 +721,7 @@ ftl_submit_read(struct ftl_io *io, ftl_next_ppa_fn next_ppa, /* We don't have to schedule the read, as it was read from cache */ if (ftl_read_canceled(rc)) { - ftl_io_update_iovec(io, 1); + ftl_io_advance(io, 1); continue; } @@ -735,11 +736,11 @@ ftl_submit_read(struct ftl_io *io, ftl_next_ppa_fn next_ppa, ftl_add_to_retry_queue(io); break; } else if (rc) { - io->status = rc; + ftl_io_fail(io, rc); break; } - ftl_io_update_iovec(io, lbk_cnt); + ftl_io_advance(io, lbk_cnt); ftl_io_inc_req(io); } @@ -996,14 +997,14 @@ ftl_submit_write(struct ftl_wptr *wptr, struct ftl_io *io) ftl_ppa_addr_pack(dev, wptr->ppa), lbk_cnt, ftl_io_cmpl_cb, io, 0, 0, 0); if (rc) { + ftl_io_fail(io, rc); SPDK_ERRLOG("spdk_nvme_ns_cmd_write failed with status:%d, ppa:%lu\n", rc, wptr->ppa.ppa); - io->status = -EIO; break; } - ftl_io_update_iovec(io, lbk_cnt); ftl_io_inc_req(io); + ftl_io_advance(io, lbk_cnt); ftl_wptr_advance(wptr, lbk_cnt); } @@ -1167,7 +1168,7 @@ ftl_rwb_fill(struct ftl_io *io) while (io->pos < io->lbk_cnt) { lba = ftl_io_current_lba(io); if (lba == FTL_LBA_INVALID) { - ftl_io_update_iovec(io, 1); + ftl_io_advance(io, 1); continue; } @@ -1181,7 +1182,7 @@ ftl_rwb_fill(struct ftl_io *io) ppa.offset = entry->pos; - ftl_io_update_iovec(io, 1); + ftl_io_advance(io, 1); ftl_update_l2p(dev, entry, ppa); /* Needs to be done after L2P is updated to avoid race with */ diff --git a/lib/ftl/ftl_io.c b/lib/ftl/ftl_io.c index f4979efb6..276fcb4ef 100644 --- a/lib/ftl/ftl_io.c +++ b/lib/ftl/ftl_io.c @@ -93,13 +93,17 @@ ftl_io_current_lba(struct ftl_io *io) } void -ftl_io_update_iovec(struct ftl_io *io, size_t lbk_cnt) +ftl_io_advance(struct ftl_io *io, size_t lbk_cnt) { struct iovec *iov = ftl_io_iovec(io); size_t iov_lbks; io->pos += lbk_cnt; + if (io->iov_cnt == 0) { + return; + } + while (lbk_cnt > 0) { assert(io->iov_pos < io->iov_cnt); iov_lbks = iov[io->iov_pos].iov_len / PAGE_SIZE; @@ -388,6 +392,12 @@ ftl_io_process_error(struct ftl_io *io, const struct spdk_nvme_cpl *status) io->status = -EIO; } +void ftl_io_fail(struct ftl_io *io, int status) +{ + io->status = status; + ftl_io_advance(io, io->lbk_cnt - io->pos); +} + void * ftl_io_get_md(const struct ftl_io *io) { diff --git a/lib/ftl/ftl_io.h b/lib/ftl/ftl_io.h index 3a61003fd..71267b646 100644 --- a/lib/ftl/ftl_io.h +++ b/lib/ftl/ftl_io.h @@ -251,11 +251,14 @@ ftl_io_mode_lba(const struct ftl_io *io) static inline bool ftl_io_done(const struct ftl_io *io) { - return io->req_cnt == 0 && !(io->flags & FTL_IO_RETRY); + return io->req_cnt == 0 && + io->pos == io->lbk_cnt && + !(io->flags & FTL_IO_RETRY); } struct ftl_io *ftl_io_alloc(struct spdk_io_channel *ch); struct ftl_io *ftl_io_alloc_child(struct ftl_io *parent); +void ftl_io_fail(struct ftl_io *io, int status); void ftl_io_free(struct ftl_io *io); struct ftl_io *ftl_io_init_internal(const struct ftl_io_init_opts *opts); void ftl_io_reinit(struct ftl_io *io, spdk_ftl_fn cb, @@ -265,7 +268,7 @@ void ftl_io_inc_req(struct ftl_io *io); void ftl_io_dec_req(struct ftl_io *io); struct iovec *ftl_io_iovec(struct ftl_io *io); uint64_t ftl_io_current_lba(struct ftl_io *io); -void ftl_io_update_iovec(struct ftl_io *io, size_t lbk_cnt); +void ftl_io_advance(struct ftl_io *io, size_t lbk_cnt); size_t ftl_iovec_num_lbks(struct iovec *iov, size_t iov_cnt); void *ftl_io_iovec_addr(struct ftl_io *io); size_t ftl_io_iovec_len_left(struct ftl_io *io); diff --git a/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c b/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c index b6cda88e2..c19bd0577 100644 --- a/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c +++ b/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c @@ -59,6 +59,7 @@ DEFINE_STUB(ftl_band_validate_md, bool, (struct ftl_band *band, const uint64_t * #endif DEFINE_STUB_V(ftl_io_dec_req, (struct ftl_io *io)); DEFINE_STUB_V(ftl_io_inc_req, (struct ftl_io *io)); +DEFINE_STUB_V(ftl_io_fail, (struct ftl_io *io, int status)); DEFINE_STUB_V(ftl_trace_completion, (struct spdk_ftl_dev *dev, const struct ftl_io *io, enum ftl_trace_completion completion)); DEFINE_STUB_V(ftl_reloc_add, (struct ftl_reloc *reloc, struct ftl_band *band, size_t offset, @@ -92,6 +93,12 @@ ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, spdk_ftl_fn cb) return io; } +void +ftl_io_advance(struct ftl_io *io, size_t lbk_cnt) +{ + io->pos += lbk_cnt; +} + void ftl_io_complete(struct ftl_io *io) {