diff --git a/include/spdk/ftl.h b/include/spdk/ftl.h index 2638d1cec..341734b17 100644 --- a/include/spdk/ftl.h +++ b/include/spdk/ftl.h @@ -93,6 +93,9 @@ struct spdk_ftl_conf { /* Allow for partial recovery from open bands instead of returning error */ bool allow_open_bands; + /* Use append instead of write */ + bool use_append; + struct { /* Maximum number of concurrent requests */ size_t max_request_cnt; diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index 6df88499c..b061629f0 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -164,12 +164,18 @@ static void ftl_io_cmpl_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) { struct ftl_io *io = cb_arg; + struct spdk_ftl_dev *dev = io->dev; if (spdk_unlikely(!success)) { io->status = -EIO; } - ftl_trace_completion(io->dev, io, FTL_TRACE_COMPLETION_DISK); + ftl_trace_completion(dev, io, FTL_TRACE_COMPLETION_DISK); + + if (io->type == FTL_IO_WRITE && ftl_is_append_supported(dev)) { + assert(io->parent); + io->parent->addr.offset = spdk_bdev_io_get_append_location(bdev_io); + } ftl_io_dec_req(io); if (ftl_io_done(io)) { @@ -1486,7 +1492,7 @@ ftl_io_init_child_write(struct ftl_io *parent, struct ftl_addr addr, .band = parent->band, .size = sizeof(struct ftl_io), .flags = 0, - .type = FTL_IO_WRITE, + .type = parent->type, .lbk_cnt = dev->xfer_size, .cb_fn = cb, .data = data, @@ -1549,10 +1555,18 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt) wptr->num_outstanding++; - rc = spdk_bdev_write_blocks(dev->base_bdev_desc, ioch->base_ioch, - ftl_io_iovec_addr(child), - addr.offset, - lbk_cnt, ftl_io_cmpl_cb, child); + if (ftl_is_append_supported(dev)) { + rc = spdk_bdev_zone_append(dev->base_bdev_desc, ioch->base_ioch, + ftl_io_iovec_addr(child), + ftl_addr_get_zone_slba(dev, addr), + lbk_cnt, ftl_io_cmpl_cb, child); + } else { + rc = spdk_bdev_write_blocks(dev->base_bdev_desc, ioch->base_ioch, + ftl_io_iovec_addr(child), + addr.offset, + lbk_cnt, ftl_io_cmpl_cb, child); + } + if (rc) { wptr->num_outstanding--; ftl_io_fail(child, rc); @@ -1581,7 +1595,7 @@ ftl_submit_write(struct ftl_wptr *wptr, struct ftl_io *io) while (io->iov_pos < io->iov_cnt) { /* There are no guarantees of the order of completion of NVMe IO submission queue */ /* so wait until zone is not busy before submitting another write */ - if (wptr->zone->busy) { + if (!ftl_is_append_supported(dev) && wptr->zone->busy) { TAILQ_INSERT_TAIL(&wptr->pending_queue, io, retry_entry); rc = -EAGAIN; break; diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index bb6625ff4..ba836e88e 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -326,6 +326,12 @@ ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev) return ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev); } +static inline uint64_t +ftl_addr_get_zone_slba(const struct spdk_ftl_dev *dev, struct ftl_addr addr) +{ + return addr.offset -= (addr.offset % ftl_get_num_blocks_in_zone(dev)); +} + static inline uint64_t ftl_addr_get_band(const struct spdk_ftl_dev *dev, struct ftl_addr addr) { @@ -502,4 +508,10 @@ ftl_nv_cache_unpack_lba(uint64_t in_lba, uint64_t *out_lba, unsigned int *phase) } } +static inline bool +ftl_is_append_supported(const struct spdk_ftl_dev *dev) +{ + return dev->conf.use_append; +} + #endif /* FTL_CORE_H */ diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index 005f60a53..ae1801674 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -981,6 +981,13 @@ ftl_dev_init_base_bdev(struct spdk_ftl_dev *dev) return -1; } + if (ftl_is_append_supported(dev) && + !spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_ZONE_APPEND)) { + SPDK_ERRLOG("Bdev dosen't support append: %s\n", + spdk_bdev_get_name(bdev)); + return -1; + } + dev->num_bands = block_cnt / (ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev)); dev->addr_len = spdk_u64log2(block_cnt) + 1; diff --git a/test/unit/lib/ftl/ftl_io.c/ftl_io_ut.c b/test/unit/lib/ftl/ftl_io.c/ftl_io_ut.c index 14a136555..b82d4e2b8 100644 --- a/test/unit/lib/ftl/ftl_io.c/ftl_io_ut.c +++ b/test/unit/lib/ftl/ftl_io.c/ftl_io_ut.c @@ -39,6 +39,7 @@ #include "ftl/ftl_io.c" DEFINE_STUB(ftl_trace_alloc_id, uint64_t, (struct spdk_ftl_dev *dev), 0); +DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0); DEFINE_STUB_V(ftl_band_acquire_lba_map, (struct ftl_band *band)); DEFINE_STUB_V(ftl_band_release_lba_map, (struct ftl_band *band)); 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 ba7f97f4f..2c94139eb 100644 --- a/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c +++ b/test/unit/lib/ftl/ftl_wptr/ftl_wptr_ut.c @@ -71,6 +71,7 @@ DEFINE_STUB(spdk_bdev_zone_management, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, uint64_t zone_id, enum spdk_bdev_zone_action action, spdk_bdev_io_completion_cb cb, void *cb_arg), 0); +DEFINE_STUB(spdk_bdev_io_get_append_location, uint64_t, (struct spdk_bdev_io *bdev_io), 0); struct ftl_io * ftl_io_erase_init(struct ftl_band *band, size_t lbk_cnt, ftl_io_fn cb)