Commit 2c7c8b6c authored by Kozlowski Mateusz's avatar Kozlowski Mateusz Committed by Jim Harris
Browse files

ftl: Add rpc functionality for unmap



Trim is now also available as a management operation via RPC.

Signed-off-by: default avatarKozlowski Mateusz <mateusz.kozlowski@intel.com>
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: I05b778a611e9809a14bfed50b01986bb4649a35c
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13379


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 66fe5f75
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -469,6 +469,7 @@ Example response:
    "bdev_ftl_unload",
    "bdev_ftl_create",
    "bdev_ftl_load",
    "bdev_ftl_unmap",
    "bdev_lvol_get_lvstores",
    "bdev_lvol_delete",
    "bdev_lvol_resize",
@@ -4912,6 +4913,46 @@ Example response:
}
~~~

### bdev_ftl_unmap {#rpc_bdev_ftl_unmap}

Unmap range of LBAs.

This RPC is subject to change.

#### Parameters

Name                    | Optional | Type        | Description
----------------------- | -------- | ----------- | -----------
name                    | Required | string      | Bdev name
lba                     | Required | number      | start lba, aligned to 1024
num_blocks              | Required | number      | number of blocks, aligned to 1024

#### Example

Example request:

~~~json
{
  "params": {
    "name": "ftl0"
    "lba": "0"
    "num_blocks": "1024"
  },
  "jsonrpc": "2.0",
  "method": "bdev_ftl_unmap",
  "id": 1
}
~~~

Example response:

~~~json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": true
}
~~~
### bdev_pmem_create_pool {#rpc_bdev_pmem_create_pool}

Create a @ref bdev_config_pmem blk pool file. It is equivalent of following `pmempool create` command:
+11 −1
Original line number Diff line number Diff line
@@ -474,6 +474,12 @@ spdk_ftl_unmap(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_chann
	}

	if (lba % aligment || lba_cnt % aligment) {
		if (!io) {
			/* This is management/RPC path, its parameters must be aligned to 1MiB. */
			return -EINVAL;
		}

		/* Otherwise unaligned IO requests are NOPs */
		rc = ftl_io_init(ch, io, lba, lba_cnt, NULL, 0, cb_fn, cb_arg, FTL_IO_UNMAP);
		if (rc) {
			return rc;
@@ -484,7 +490,11 @@ spdk_ftl_unmap(struct spdk_ftl_dev *dev, struct ftl_io *io, struct spdk_io_chann
		return 0;
	}

	if (io) {
		rc = ftl_unmap(dev, io, ch, lba, lba_cnt, cb_fn, cb_arg);
	} else {
		rc = ftl_mngt_unmap(dev, lba, lba_cnt, cb_fn, cb_arg);
	}

	return rc;
}
+17 −0
Original line number Diff line number Diff line
@@ -303,6 +303,23 @@ void ftl_mngt_call_process_rollback(struct ftl_mngt_process *mngt,
 */
int ftl_mngt_call_dev_startup(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void *cb_cntx);

/*
 * The specific management functions
 */
/**
 * @brief Issue unmap on FTL instance
 *
 * @param dev FTL device
 * @param cb Caller callback
 * @param cb_cntx Caller context
 *
 * @return Operation result
 * @retval 0 The operation successful has started
 * @retval Non-zero Startup failure
 */
int ftl_mngt_unmap(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t num_blocks, spdk_ftl_fn cb,
		   void *cb_cntx);

/**
 * @brief Shuts down a FTL instance
 *
+81 −0
Original line number Diff line number Diff line
@@ -278,6 +278,87 @@ ftl_mngt_call_dev_startup(struct spdk_ftl_dev *dev, ftl_mngt_completion cb, void
	return ftl_mngt_process_execute(dev, &desc_startup, cb, cb_cntx);
}

struct ftl_unmap_ctx {
	uint64_t lba;
	uint64_t num_blocks;
	spdk_ftl_fn cb_fn;
	void *cb_arg;
};

static void
ftl_mngt_process_unmap_cb(void *ctx, int status)
{
	struct ftl_mngt_process *mngt = ctx;

	if (status) {
		ftl_mngt_fail_step(ctx);
	} else {
		ftl_mngt_next_step(mngt);
	}
}

static void
ftl_mngt_process_unmap(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
	struct ftl_io *io = ftl_mngt_get_process_ctx(mngt);
	struct ftl_unmap_ctx *ctx = ftl_mngt_get_caller_ctx(mngt);
	int rc;

	if (!dev->ioch) {
		ftl_mngt_fail_step(mngt);
		return;
	}

	rc = spdk_ftl_unmap(dev, io, dev->ioch, ctx->lba, ctx->num_blocks, ftl_mngt_process_unmap_cb, mngt);
	if (rc == -EAGAIN) {
		ftl_mngt_continue_step(mngt);
	}
}

/*
 * RPC unmap path.
 */
static const struct ftl_mngt_process_desc g_desc_unmap = {
	.name = "FTL unmap",
	.ctx_size = sizeof(struct ftl_io),
	.steps = {
		{
			.name = "Process unmap",
			.action = ftl_mngt_process_unmap,
		},
		{}
	}
};

static void
ftl_mngt_unmap_cb(struct spdk_ftl_dev *dev, void *_ctx, int status)
{
	struct ftl_unmap_ctx *ctx = _ctx;

	ctx->cb_fn(ctx->cb_arg, status);

	free(ctx);
}

int
ftl_mngt_unmap(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t num_blocks, spdk_ftl_fn cb,
	       void *cb_cntx)
{
	struct ftl_unmap_ctx *ctx;

	ctx = calloc(1, sizeof(*ctx));
	if (ctx == NULL) {
		return -EAGAIN;
	}

	ctx->lba = lba;
	ctx->num_blocks = num_blocks;
	ctx->cb_fn = cb;
	ctx->cb_arg = cb_cntx;

	return ftl_mngt_process_execute(dev, &g_desc_unmap, ftl_mngt_unmap_cb, ctx);
}

void
ftl_mngt_rollback_device(struct spdk_ftl_dev *dev, struct ftl_mngt_process *mngt)
{
+66 −0
Original line number Diff line number Diff line
@@ -482,6 +482,72 @@ not_found:
	cb_fn(cb_arg, -ENODEV);
}

struct ftl_unmap_ctx {
	struct spdk_bdev_desc *bdev;
	spdk_ftl_fn cb_fn;
	void *cb_arg;
};

static void
bdev_ftl_unmap_cb(void *cb_arg, int status)
{
	struct ftl_unmap_ctx *ctx = cb_arg;

	spdk_bdev_close(ctx->bdev);
	ctx->cb_fn(ctx->cb_arg, status);
	free(ctx);
}

void
bdev_ftl_unmap(const char *name, uint64_t lba, uint64_t num_blocks, spdk_ftl_fn cb_fn, void *cb_arg)
{
	struct spdk_bdev_desc *ftl_bdev_desc;
	struct spdk_bdev *bdev;
	struct ftl_bdev *ftl;
	struct ftl_unmap_ctx *ctx;
	int rc;

	rc = spdk_bdev_open_ext(name, false, bdev_ftl_event_cb, NULL, &ftl_bdev_desc);

	if (rc) {
		goto not_found;
	}

	bdev = spdk_bdev_desc_get_bdev(ftl_bdev_desc);

	if (bdev->module != &g_ftl_if) {
		rc = -ENODEV;
		goto bdev_opened;
	}

	ctx = calloc(1, sizeof(struct ftl_unmap_ctx));
	if (!ctx) {
		rc = -ENOMEM;
		goto bdev_opened;
	}

	ctx->bdev = ftl_bdev_desc;
	ctx->cb_arg = cb_arg;
	ctx->cb_fn = cb_fn;

	ftl = bdev->ctxt;
	assert(ftl);
	/* It's ok to pass NULL as IO channel - FTL will detect this and use it's internal IO channel for management operations */
	rc = spdk_ftl_unmap(ftl->dev, NULL, NULL, lba, num_blocks, bdev_ftl_unmap_cb, ctx);

	if (rc) {
		goto ctx_allocated;
	}

	return;
ctx_allocated:
	free(ctx);
bdev_opened:
	spdk_bdev_close(ftl_bdev_desc);
not_found:
	cb_fn(cb_arg, rc);
}

static void
bdev_ftl_finish(void)
{
Loading