Commit 4d122a35 authored by Wojciech Malikowski's avatar Wojciech Malikowski Committed by Jim Harris
Browse files

lib/ftl: Add support for spdk_bdev_open_ext()



In order to handle media management events spdk_bdev_open_ext()
should be used instead spdk_bdev_open(). Move this call to ftl lib
to keep media management events internal to the library.

Change-Id: If4c9382cc89fc537667923f00d3dae5df0ace248
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/481503


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 6ea187fc
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -111,9 +111,9 @@ enum spdk_ftl_mode {

struct spdk_ftl_dev_init_opts {
	/* Underlying device */
	struct spdk_bdev_desc			*base_bdev_desc;
	const char				*base_bdev;
	/* Write buffer cache */
	struct spdk_bdev_desc			*cache_bdev_desc;
	const char				*cache_bdev;

	/* Thread responsible for core tasks execution */
	struct spdk_thread			*core_thread;
@@ -137,8 +137,10 @@ struct spdk_ftl_attrs {
	uint64_t				num_blocks;
	/* Logical block size */
	size_t					block_size;
	/* Underlying device */
	const char				*base_bdev;
	/* Write buffer cache */
	struct spdk_bdev_desc			*cache_bdev_desc;
	const char				*cache_bdev;
	/* Number of zones per parallel unit in the underlying device (including any offline ones) */
	size_t					num_zones;
	/* Number of logical blocks per zone */
+7 −1
Original line number Diff line number Diff line
@@ -1914,10 +1914,16 @@ spdk_ftl_dev_get_attrs(const struct spdk_ftl_dev *dev, struct spdk_ftl_attrs *at
	attrs->uuid = dev->uuid;
	attrs->num_blocks = dev->num_lbas;
	attrs->block_size = FTL_BLOCK_SIZE;
	attrs->cache_bdev_desc = dev->nv_cache.bdev_desc;
	attrs->num_zones = ftl_get_num_zones(dev);
	attrs->zone_size = ftl_get_num_blocks_in_zone(dev);
	attrs->conf = dev->conf;
	attrs->base_bdev = spdk_bdev_get_name(spdk_bdev_desc_get_bdev(dev->base_bdev_desc));

	attrs->cache_bdev = NULL;
	if (dev->nv_cache.bdev_desc) {
		attrs->cache_bdev = spdk_bdev_get_name(
					    spdk_bdev_desc_get_bdev(dev->nv_cache.bdev_desc));
	}
}

static void
+77 −10
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include "spdk/likely.h"
#include "spdk/string.h"
#include "spdk/bdev_zone.h"
#include "spdk/bdev_module.h"

#include "ftl_core.h"
#include "ftl_io.h"
@@ -54,6 +55,11 @@
#define FTL_NSID		1
#define FTL_ZONE_INFO_COUNT	64

/* Dummy bdev module used to to claim bdevs. */
static struct spdk_bdev_module g_ftl_bdev_module = {
	.name	= "ftl_lib",
};

struct ftl_dev_init_ctx {
	struct spdk_ftl_dev		*dev;
	struct spdk_ftl_dev_init_opts	opts;
@@ -207,8 +213,20 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
	return rc;
}

static void
ftl_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx)
{
	switch (type) {
	case SPDK_BDEV_EVENT_REMOVE:
		assert(0);
		break;
	default:
		break;
	}
}

static int
ftl_dev_init_nv_cache(struct spdk_ftl_dev *dev, struct spdk_bdev_desc *bdev_desc)
ftl_dev_init_nv_cache(struct spdk_ftl_dev *dev, const char *bdev_name)
{
	struct spdk_bdev *bdev;
	struct spdk_ftl_conf *conf = &dev->conf;
@@ -216,11 +234,29 @@ ftl_dev_init_nv_cache(struct spdk_ftl_dev *dev, struct spdk_bdev_desc *bdev_desc
	char pool_name[128];
	int rc;

	if (!bdev_desc) {
	if (!bdev_name) {
		return 0;
	}

	bdev = spdk_bdev_desc_get_bdev(bdev_desc);
	bdev = spdk_bdev_get_by_name(bdev_name);
	if (!bdev) {
		SPDK_ERRLOG("Unable to find bdev: %s\n", bdev_name);
		return -1;
	}

	if (spdk_bdev_open_ext(bdev_name, true, ftl_bdev_event_cb,
			       dev, &nv_cache->bdev_desc)) {
		SPDK_ERRLOG("Unable to open bdev: %s\n", bdev_name);
		return -1;
	}

	if (spdk_bdev_module_claim_bdev(bdev, nv_cache->bdev_desc, &g_ftl_bdev_module)) {
		spdk_bdev_close(nv_cache->bdev_desc);
		nv_cache->bdev_desc = NULL;
		SPDK_ERRLOG("Unable to claim bdev %s\n", bdev_name);
		return -1;
	}

	SPDK_INFOLOG(SPDK_LOG_FTL_INIT, "Using %s as write buffer cache\n",
		     spdk_bdev_get_name(bdev));

@@ -285,7 +321,6 @@ ftl_dev_init_nv_cache(struct spdk_ftl_dev *dev, struct spdk_bdev_desc *bdev_desc
		return -1;
	}

	nv_cache->bdev_desc = bdev_desc;
	nv_cache->current_addr = FTL_NV_CACHE_DATA_OFFSET;
	nv_cache->num_data_blocks = spdk_bdev_get_num_blocks(bdev) - 1;
	nv_cache->num_available = nv_cache->num_data_blocks;
@@ -951,11 +986,17 @@ ftl_dev_init_io_channel(struct spdk_ftl_dev *dev)
}

static int
ftl_dev_init_base_bdev(struct spdk_ftl_dev *dev)
ftl_dev_init_base_bdev(struct spdk_ftl_dev *dev, const char *bdev_name)
{
	uint32_t block_size;
	uint64_t num_blocks;
	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(dev->base_bdev_desc);
	struct spdk_bdev *bdev;

	bdev = spdk_bdev_get_by_name(bdev_name);
	if (!bdev) {
		SPDK_ERRLOG("Unable to find bdev: %s\n", bdev_name);
		return -1;
	}

	if (!spdk_bdev_is_zoned(bdev)) {
		SPDK_ERRLOG("Bdev dosen't support zone capabilities: %s\n",
@@ -963,6 +1004,19 @@ ftl_dev_init_base_bdev(struct spdk_ftl_dev *dev)
		return -1;
	}

	if (spdk_bdev_open_ext(bdev_name, true, ftl_bdev_event_cb,
			       dev, &dev->base_bdev_desc)) {
		SPDK_ERRLOG("Unable to open bdev: %s\n", bdev_name);
		return -1;
	}

	if (spdk_bdev_module_claim_bdev(bdev, dev->base_bdev_desc, &g_ftl_bdev_module)) {
		spdk_bdev_close(dev->base_bdev_desc);
		dev->base_bdev_desc = NULL;
		SPDK_ERRLOG("Unable to claim bdev %s\n", bdev_name);
		return -1;
	}

	dev->xfer_size = spdk_bdev_get_write_unit_size(bdev);
	dev->md_size = spdk_bdev_get_md_size(bdev);

@@ -1000,6 +1054,17 @@ ftl_lba_map_request_dtor(struct spdk_mempool *mp, void *opaque, void *obj, unsig
	spdk_bit_array_free(&request->segments);
}

static void
ftl_release_bdev(struct spdk_bdev_desc *bdev_desc)
{
	if (!bdev_desc) {
		return;
	}

	spdk_bdev_module_release_bdev(spdk_bdev_desc_get_bdev(bdev_desc));
	spdk_bdev_close(bdev_desc);
}

static void
ftl_dev_free_sync(struct spdk_ftl_dev *dev)
{
@@ -1055,6 +1120,9 @@ ftl_dev_free_sync(struct spdk_ftl_dev *dev)
	ftl_rwb_free(dev->rwb);
	ftl_reloc_free(dev->reloc);

	ftl_release_bdev(dev->nv_cache.bdev_desc);
	ftl_release_bdev(dev->base_bdev_desc);

	free(dev->name);
	free(dev->bands);
	free(dev->l2p);
@@ -1086,7 +1154,7 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
		opts.conf = &g_default_conf;
	}

	if (!opts.base_bdev_desc) {
	if (!opts.base_bdev) {
		SPDK_ERRLOG("Lack of underlying device in configuration\n");
		rc = -EINVAL;
		goto fail_sync;
@@ -1097,7 +1165,6 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
	dev->init_ctx.cb_fn = cb_fn;
	dev->init_ctx.cb_arg = cb_arg;
	dev->init_ctx.thread = spdk_get_thread();
	dev->base_bdev_desc = opts.base_bdev_desc;
	dev->limit = SPDK_FTL_LIMIT_MAX;

	dev->name = strdup(opts.name);
@@ -1106,7 +1173,7 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
		goto fail_sync;
	}

	if (ftl_dev_init_base_bdev(dev)) {
	if (ftl_dev_init_base_bdev(dev, opts.base_bdev)) {
		SPDK_ERRLOG("Unsupported underlying device\n");
		goto fail_sync;
	}
@@ -1130,7 +1197,7 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
		goto fail_sync;
	}

	if (ftl_dev_init_nv_cache(dev, opts.cache_bdev_desc)) {
	if (ftl_dev_init_nv_cache(dev, opts.cache_bdev)) {
		SPDK_ERRLOG("Unable to initialize persistent cache\n");
		goto fail_sync;
	}
+7 −92
Original line number Diff line number Diff line
@@ -53,10 +53,6 @@ struct ftl_bdev {

	struct spdk_ftl_dev		*dev;

	struct spdk_bdev_desc		*base_bdev_desc;

	struct spdk_bdev_desc		*cache_bdev_desc;

	ftl_bdev_init_fn		init_cb;

	void				*init_arg;
@@ -112,24 +108,12 @@ static struct spdk_bdev_module g_ftl_if = {

SPDK_BDEV_MODULE_REGISTER(ftl, &g_ftl_if)

static void
bdev_ftl_close(struct spdk_bdev_desc *bdev_desc)
{
	spdk_bdev_module_release_bdev(spdk_bdev_desc_get_bdev(bdev_desc));
	spdk_bdev_close(bdev_desc);
}

static void
bdev_ftl_free_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
{
	struct ftl_bdev *ftl_bdev = ctx;

	spdk_io_device_unregister(ftl_bdev, NULL);
	bdev_ftl_close(ftl_bdev->base_bdev_desc);

	if (ftl_bdev->cache_bdev_desc) {
		bdev_ftl_close(ftl_bdev->cache_bdev_desc);
	}

	spdk_bdev_destruct_done(&ftl_bdev->bdev, status);
	free(ftl_bdev->bdev.name);
@@ -332,17 +316,14 @@ bdev_ftl_get_io_channel(void *ctx)
static void
_bdev_ftl_write_config_info(struct ftl_bdev *ftl_bdev, struct spdk_json_write_ctx *w)
{
	struct spdk_ftl_attrs attrs;
	const char *cache_bdev, *base_bdev;
	struct spdk_ftl_attrs attrs = {};

	spdk_ftl_dev_get_attrs(ftl_bdev->dev, &attrs);

	base_bdev = spdk_bdev_get_name(spdk_bdev_desc_get_bdev(ftl_bdev->base_bdev_desc));
	spdk_json_write_named_string(w, "base_bdev", base_bdev);
	spdk_json_write_named_string(w, "base_bdev", attrs.base_bdev);

	if (ftl_bdev->cache_bdev_desc) {
		cache_bdev = spdk_bdev_get_name(spdk_bdev_desc_get_bdev(ftl_bdev->cache_bdev_desc));
		spdk_json_write_named_string(w, "cache", cache_bdev);
	if (attrs.cache_bdev) {
		spdk_json_write_named_string(w, "cache", attrs.cache_bdev);
	}
}

@@ -462,12 +443,6 @@ bdev_ftl_io_channel_destroy_cb(void *io_device, void *ctx_buf)
	spdk_put_io_channel(ch->ioch);
}

static void
bdev_ftl_bdev_removed_cb(void *ctx)
{
	assert(0 && "Removed dependent bdev\n");
}

static void
bdev_ftl_create_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
{
@@ -519,12 +494,6 @@ bdev_ftl_create_cb(struct spdk_ftl_dev *dev, void *ctx, int status)
error_unregister:
	spdk_io_device_unregister(ftl_bdev, NULL);
error_dev:
	bdev_ftl_close(ftl_bdev->base_bdev_desc);

	if (ftl_bdev->cache_bdev_desc) {
		bdev_ftl_close(ftl_bdev->cache_bdev_desc);
	}

	free(ftl_bdev->bdev.name);
	free(ftl_bdev);

@@ -583,33 +552,6 @@ error:
	return -ENOMEM;
}

static int
bdev_ftl_init_dependent_bdev(struct ftl_bdev *ftl_bdev, const char *bdev_name,
			     struct spdk_bdev_desc **bdev_desc)
{
	struct spdk_bdev *bdev = NULL;

	bdev = spdk_bdev_get_by_name(bdev_name);
	if (!bdev) {
		SPDK_ERRLOG("Unable to find bdev: %s\n", bdev_name);
		return -ENODEV;
	}

	if (spdk_bdev_open(bdev, true, bdev_ftl_bdev_removed_cb,
			   ftl_bdev, bdev_desc)) {
		SPDK_ERRLOG("Unable to open bdev: %s\n", bdev_name);
		return -EPERM;
	}

	if (spdk_bdev_module_claim_bdev(bdev, *bdev_desc, &g_ftl_if)) {
		SPDK_ERRLOG("Unable to claim bdev %s\n", bdev_name);
		spdk_bdev_close(*bdev_desc);
		return -EPERM;
	}

	return 0;
}

int
bdev_ftl_create_bdev(const struct ftl_bdev_init_opts *bdev_opts,
		     ftl_bdev_init_fn cb, void *cb_arg)
@@ -639,34 +581,14 @@ bdev_ftl_create_bdev(const struct ftl_bdev_init_opts *bdev_opts,
		goto error_name;
	}

	rc = bdev_ftl_init_dependent_bdev(ftl_bdev, bdev_opts->base_bdev,
					  &ftl_bdev->base_bdev_desc);
	if (rc) {
		goto error_name;
	}

	if (!spdk_bdev_is_zoned(spdk_bdev_desc_get_bdev(ftl_bdev->base_bdev_desc))) {
		SPDK_ERRLOG("Bdev dosen't support zone capabilities: %s\n", bdev_opts->base_bdev);
		rc = -EINVAL;
		goto error_cache;
	}

	if (bdev_opts->cache_bdev) {
		rc = bdev_ftl_init_dependent_bdev(ftl_bdev, bdev_opts->cache_bdev,
						  &ftl_bdev->cache_bdev_desc);
		if (rc) {
			goto error_cache;
		}
	}

	ftl_bdev->init_cb = cb;
	ftl_bdev->init_arg = cb_arg;

	opts.mode = bdev_opts->mode;
	opts.uuid = bdev_opts->uuid;
	opts.name = ftl_bdev->bdev.name;
	opts.base_bdev_desc = ftl_bdev->base_bdev_desc;
	opts.cache_bdev_desc = ftl_bdev->cache_bdev_desc;
	opts.base_bdev = bdev_opts->base_bdev;
	opts.cache_bdev = bdev_opts->cache_bdev;
	opts.conf = &bdev_opts->ftl_conf;

	/* TODO: set threads based on config */
@@ -675,18 +597,11 @@ bdev_ftl_create_bdev(const struct ftl_bdev_init_opts *bdev_opts,
	rc = spdk_ftl_dev_init(&opts, bdev_ftl_create_cb, ftl_bdev);
	if (rc) {
		SPDK_ERRLOG("Could not create FTL device\n");
		goto error_cache;
		goto error_name;
	}

	return 0;

error_cache:
	if (ftl_bdev->cache_bdev_desc) {
		bdev_ftl_close(ftl_bdev->cache_bdev_desc);
	}
	if (ftl_bdev->base_bdev_desc) {
		bdev_ftl_close(ftl_bdev->base_bdev_desc);
	}
error_name:
	free(ftl_bdev->bdev.name);
error_bdev: