bdev/ocssd: append command

This patch adds support for the append operation.  The user doesn't need
to specify the exact location of where the data should be placed, but
only need to pass starting LBA of a zone to append to.  The user can
retrieve the address the data was written at during completion callback.

Change-Id: Ic03abcf2e7a953a7a229a6b6b6122fffa01cb714
Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/469120
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Mateusz Kozlowski <mateusz.kozlowski@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Konrad Sztyber 2019-09-23 11:32:49 +02:00 committed by Tomasz Zawadzki
parent 1ad438311e
commit 3a58b2fb2f

View File

@ -354,6 +354,10 @@ bdev_ocssd_write_cb(void *ctx, const struct spdk_nvme_cpl *cpl)
struct spdk_bdev_io *bdev_io = ctx;
struct bdev_ocssd_io *ocdev_io = (struct bdev_ocssd_io *)bdev_io->driver_ctx;
if (bdev_io->type == SPDK_BDEV_IO_TYPE_ZONE_APPEND) {
bdev_io->u.bdev.offset_blocks = ocdev_io->io.zone->write_pointer;
}
ocdev_io->io.zone->write_pointer = bdev_io->u.bdev.offset_blocks +
bdev_io->u.bdev.num_blocks;
assert(ocdev_io->io.zone->write_pointer <= ocdev_io->io.zone->slba +
@ -399,6 +403,50 @@ bdev_ocssd_write(struct spdk_io_channel *ioch, struct spdk_bdev_io *bdev_io)
return rc;
}
static int
bdev_ocssd_zone_append(struct spdk_io_channel *ioch, struct spdk_bdev_io *bdev_io)
{
struct ocssd_bdev *ocssd_bdev = bdev_io->bdev->ctxt;
struct nvme_bdev *nvme_bdev = &ocssd_bdev->nvme_bdev;
struct nvme_io_channel *nvme_ioch = spdk_io_channel_get_ctx(ioch);
struct bdev_ocssd_io *ocdev_io = (struct bdev_ocssd_io *)bdev_io->driver_ctx;
struct bdev_ocssd_zone *zone;
uint64_t lba;
int rc = 0;
zone = bdev_ocssd_get_zone_by_slba(ocssd_bdev, bdev_io->u.bdev.offset_blocks);
if (!zone) {
SPDK_ERRLOG("Invalid zone SLBA: %"PRIu64"\n", bdev_io->u.bdev.offset_blocks);
return -EINVAL;
}
if (__atomic_exchange_n(&zone->busy, true, __ATOMIC_SEQ_CST)) {
return -EAGAIN;
}
if (zone->slba + zone->capacity - zone->write_pointer < bdev_io->u.bdev.num_blocks) {
SPDK_ERRLOG("Insufficient number of blocks remaining\n");
rc = -ENOSPC;
goto out;
}
ocdev_io->io.zone = zone;
ocdev_io->io.iov_pos = 0;
ocdev_io->io.iov_off = 0;
lba = bdev_ocssd_to_disk_lba(ocssd_bdev, zone->write_pointer);
rc = spdk_nvme_ns_cmd_writev_with_md(nvme_bdev->nvme_ns->ns, nvme_ioch->qpair, lba,
bdev_io->u.bdev.num_blocks, bdev_ocssd_write_cb,
bdev_io, 0, bdev_ocssd_reset_sgl,
bdev_ocssd_next_sge, bdev_io->u.bdev.md_buf, 0, 0);
out:
if (spdk_unlikely(rc != 0)) {
__atomic_store_n(&zone->busy, false, __ATOMIC_SEQ_CST);
}
return rc;
}
static void
bdev_ocssd_io_get_buf_cb(struct spdk_io_channel *ioch, struct spdk_bdev_io *bdev_io, bool success)
{
@ -667,6 +715,10 @@ bdev_ocssd_submit_request(struct spdk_io_channel *ioch, struct spdk_bdev_io *bde
rc = bdev_ocssd_get_zone_info(ioch, bdev_io);
break;
case SPDK_BDEV_IO_TYPE_ZONE_APPEND:
rc = bdev_ocssd_zone_append(ioch, bdev_io);
break;
default:
rc = -EINVAL;
break;
@ -694,6 +746,7 @@ bdev_ocssd_io_type_supported(void *ctx, enum spdk_bdev_io_type type)
case SPDK_BDEV_IO_TYPE_READ:
case SPDK_BDEV_IO_TYPE_WRITE:
case SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT:
case SPDK_BDEV_IO_TYPE_ZONE_APPEND:
return true;
default: