Commit 3a58b2fb authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

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


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarMateusz Kozlowski <mateusz.kozlowski@intel.com>
Tested-by: default avatarSPDK 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>
parent 1ad43831
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -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: