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: Wojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/481503
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
Wojciech Malikowski 2020-01-13 08:52:47 -05:00 committed by Jim Harris
parent 6ea187fcbb
commit 4d122a3559
4 changed files with 96 additions and 106 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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: