diff --git a/include/spdk/ftl.h b/include/spdk/ftl.h index 1fa549368c..33ba2abece 100644 --- a/include/spdk/ftl.h +++ b/include/spdk/ftl.h @@ -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 */ diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index fe9926f049..21b94a82f0 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -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 diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index 9ebd8c0b78..75870c0094 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -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; } diff --git a/module/bdev/ftl/bdev_ftl.c b/module/bdev/ftl/bdev_ftl.c index ba918e41c9..c6f430e8a3 100644 --- a/module/bdev/ftl/bdev_ftl.c +++ b/module/bdev/ftl/bdev_ftl.c @@ -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: