From 5029fe14b66f0e27ba8b429c7edabafe35bb102f Mon Sep 17 00:00:00 2001 From: Li Feng Date: Tue, 8 Sep 2020 23:32:48 +0800 Subject: [PATCH] scsi: add bdev resize callback support Currently, the scsi bdev only supports the hotremove event, and the scsi library uses the deprecated `spdk_bdev_open` function. In this patch, add the resize event support, so the upper layer could do more actions, like vhost-scsi could notify the guest os. For the scsi compatibility, add _ext suffix for some public api. Change-Id: I3254d4570142893f953f7f42da31efb5a3685033 Signed-off-by: Li Feng Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4353 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto --- CHANGELOG.md | 8 ++++++ include/spdk/scsi.h | 47 +++++++++++++++++++++++++++++++ lib/scsi/Makefile | 2 +- lib/scsi/dev.c | 32 +++++++++++++++++++-- lib/scsi/lun.c | 30 +++++++++++++++++++- lib/scsi/scsi_internal.h | 8 ++++++ lib/scsi/spdk_scsi.map | 2 ++ test/unit/lib/scsi/dev.c/dev_ut.c | 2 ++ test/unit/lib/scsi/lun.c/lun_ut.c | 13 ++++++--- 9 files changed, 135 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efdef0b3a..590034173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,14 @@ library now no longer exists. The contents of the bdev_rpc library have been moved to the bdev library. The app_rpc library now no longer exists. +### scsi +Two new APIs have been added `spdk_scsi_dev_construct_ext` and +`spdk_scsi_dev_add_lun_ext` that allow the upper layer(e.g. vhost-scsi) to +receive the notification when the scsi bdev has been resized. + +The `spdk_scsi_dev_construct` and `spdk_scsi_dev_add_lun` eventually may be +deprecated and removed. + ## v20.07: SPDK CSI driver, new accel_fw commands, I/O abort support ### accel diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 1b3f75577..0bafea47d 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -342,6 +342,35 @@ struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx); +/** + * Construct a SCSI device object using the more given parameters. + * + * \param name Name for the SCSI device. + * \param bdev_name_list List of bdev names to attach to the LUNs for this SCSI + * device. + * \param lun_id_list List of LUN IDs for the LUN in this SCSI device. Caller is + * responsible for managing the memory containing this list. lun_id_list[x] is + * the LUN ID for lun_list[x]. + * \param num_luns Number of entries in lun_list and lun_id_list. + * \param protocol_id SCSI SPC protocol identifier to report in INQUIRY data + * \param resize_cb Callback of lun resize. + * \param resize_ctx Additional argument to resize_cb. + * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove + * is first triggered. + * \param hotremove_ctx Additional argument to hotremove_cb. + * + * \return the constructed spdk_scsi_dev object. + */ +struct spdk_scsi_dev *spdk_scsi_dev_construct_ext(const char *name, + const char *bdev_name_list[], + int *lun_id_list, + int num_luns, + uint8_t protocol_id, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx); + /** * Delete a logical unit of the given SCSI device. * @@ -364,6 +393,24 @@ int spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx); +/** + * Add a new logical unit to the given SCSI device with more callbacks. + * + * \param dev SCSI device. + * \param bdev_name Name of the bdev attached to the logical unit. + * \param lun_id LUN id for the new logical unit. + * \param resize_cb Callback of lun resize. + * \param resize_ctx Additional argument to resize_cb. + * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove + * is first triggered. + * \param hotremove_ctx Additional argument to hotremove_cb. + */ +int spdk_scsi_dev_add_lun_ext(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx); + /** * Create a new SCSI port. * diff --git a/lib/scsi/Makefile b/lib/scsi/Makefile index 8f8a8c326..b7d38e249 100644 --- a/lib/scsi/Makefile +++ b/lib/scsi/Makefile @@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..) include $(SPDK_ROOT_DIR)/mk/spdk.common.mk SO_VER := 3 -SO_MINOR := 0 +SO_MINOR := 1 C_SRCS = dev.c lun.c port.c scsi.c scsi_bdev.c scsi_pr.c scsi_rpc.c task.c LIBNAME = scsi diff --git a/lib/scsi/dev.c b/lib/scsi/dev.c index 6d3cfdf31..375fa319c 100644 --- a/lib/scsi/dev.c +++ b/lib/scsi/dev.c @@ -138,6 +138,18 @@ int spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx) +{ + return spdk_scsi_dev_add_lun_ext(dev, bdev_name, lun_id, + NULL, NULL, + hotremove_cb, hotremove_ctx); +} + +int +spdk_scsi_dev_add_lun_ext(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx) { struct spdk_bdev *bdev; struct spdk_scsi_lun *lun; @@ -158,7 +170,7 @@ spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_ } } - lun = scsi_lun_construct(bdev, hotremove_cb, hotremove_ctx); + lun = scsi_lun_construct(bdev, resize_cb, resize_ctx, hotremove_cb, hotremove_ctx); if (lun == NULL) { return -1; } @@ -195,6 +207,19 @@ struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name, const char *bdev int *lun_id_list, int num_luns, uint8_t protocol_id, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx) +{ + return spdk_scsi_dev_construct_ext(name, bdev_name_list, lun_id_list, + num_luns, protocol_id, + NULL, NULL, + hotremove_cb, hotremove_ctx); +} + +struct spdk_scsi_dev *spdk_scsi_dev_construct_ext(const char *name, const char *bdev_name_list[], + int *lun_id_list, int num_luns, uint8_t protocol_id, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, + void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), + void *hotremove_ctx) { struct spdk_scsi_dev *dev; size_t name_len; @@ -245,8 +270,9 @@ struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name, const char *bdev dev->protocol_id = protocol_id; for (i = 0; i < num_luns; i++) { - rc = spdk_scsi_dev_add_lun(dev, bdev_name_list[i], lun_id_list[i], - hotremove_cb, hotremove_ctx); + rc = spdk_scsi_dev_add_lun_ext(dev, bdev_name_list[i], lun_id_list[i], + resize_cb, resize_ctx, + hotremove_cb, hotremove_ctx); if (rc < 0) { spdk_scsi_dev_destruct(dev, NULL, NULL); return NULL; diff --git a/lib/scsi/lun.c b/lib/scsi/lun.c index 262137d80..ad635bbfd 100644 --- a/lib/scsi/lun.c +++ b/lib/scsi/lun.c @@ -393,6 +393,28 @@ scsi_lun_hot_remove(void *remove_ctx) } } +static void +bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, + void *event_ctx) +{ + struct spdk_scsi_lun *lun = (struct spdk_scsi_lun *)event_ctx; + switch (type) { + case SPDK_BDEV_EVENT_REMOVE: + SPDK_NOTICELOG("bdev name (%s) received event(SPDK_BDEV_EVENT_REMOVE)\n", spdk_bdev_get_name(bdev)); + scsi_lun_hot_remove(event_ctx); + break; + case SPDK_BDEV_EVENT_RESIZE: + SPDK_NOTICELOG("bdev name (%s) received event(SPDK_BDEV_EVENT_RESIZE)\n", spdk_bdev_get_name(bdev)); + if (lun->resize_cb) { + lun->resize_cb(lun, lun->resize_ctx); + } + break; + default: + SPDK_NOTICELOG("Unsupported bdev event: type %d\n", type); + break; + } +} + /** * \brief Constructs a new spdk_scsi_lun object based on the provided parameters. * @@ -402,6 +424,8 @@ scsi_lun_hot_remove(void *remove_ctx) * \return pointer to the new spdk_scsi_lun object otherwise */ struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx) { @@ -419,7 +443,7 @@ struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev, return NULL; } - rc = spdk_bdev_open(bdev, true, scsi_lun_hot_remove, lun, &lun->bdev_desc); + rc = spdk_bdev_open_ext(spdk_bdev_get_name(bdev), true, bdev_event_cb, lun, &lun->bdev_desc); if (rc != 0) { SPDK_ERRLOG("bdev %s cannot be opened, error=%d\n", spdk_bdev_get_name(bdev), rc); @@ -438,6 +462,10 @@ struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev, lun->io_channel = NULL; lun->hotremove_cb = hotremove_cb; lun->hotremove_ctx = hotremove_ctx; + + lun->resize_cb = resize_cb; + lun->resize_ctx = resize_ctx; + TAILQ_INIT(&lun->open_descs); TAILQ_INIT(&lun->reg_head); diff --git a/lib/scsi/scsi_internal.h b/lib/scsi/scsi_internal.h index 2da3a99a8..3b8e907b4 100644 --- a/lib/scsi/scsi_internal.h +++ b/lib/scsi/scsi_internal.h @@ -141,6 +141,12 @@ struct spdk_scsi_lun { /** Argument for hotremove_cb */ void *hotremove_ctx; + /** Callback to be fired when the bdev size of related LUN has changed. */ + void (*resize_cb)(const struct spdk_scsi_lun *, void *); + + /** Argument for resize_cb */ + void *resize_ctx; + /** Registrant head for I_T nexus */ TAILQ_HEAD(, spdk_scsi_pr_registrant) reg_head; /** Persistent Reservation Generation */ @@ -170,6 +176,8 @@ struct spdk_scsi_lun { }; struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx); void scsi_lun_destruct(struct spdk_scsi_lun *lun); diff --git a/lib/scsi/spdk_scsi.map b/lib/scsi/spdk_scsi.map index 643372699..b4d081251 100644 --- a/lib/scsi/spdk_scsi.map +++ b/lib/scsi/spdk_scsi.map @@ -44,6 +44,8 @@ spdk_scsi_port_set_iscsi_transport_id; spdk_scsi_lun_id_int_to_fmt; spdk_scsi_lun_id_fmt_to_int; + spdk_scsi_dev_construct_ext; + spdk_scsi_dev_add_lun_ext; local: *; }; diff --git a/test/unit/lib/scsi/dev.c/dev_ut.c b/test/unit/lib/scsi/dev.c/dev_ut.c index f738011fb..f08906f0d 100644 --- a/test/unit/lib/scsi/dev.c/dev_ut.c +++ b/test/unit/lib/scsi/dev.c/dev_ut.c @@ -82,6 +82,8 @@ spdk_scsi_task_put(struct spdk_scsi_task *task) } struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev, + void (*resize_cb)(const struct spdk_scsi_lun *, void *), + void *resize_ctx, void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), void *hotremove_ctx) { diff --git a/test/unit/lib/scsi/lun.c/lun_ut.c b/test/unit/lib/scsi/lun.c/lun_ut.c index 4efa8e364..7a7a52cd4 100644 --- a/test/unit/lib/scsi/lun.c/lun_ut.c +++ b/test/unit/lib/scsi/lun.c/lun_ut.c @@ -95,6 +95,11 @@ DEFINE_STUB(spdk_bdev_open, int, void *remove_ctx, struct spdk_bdev_desc **desc), 0); +DEFINE_STUB(spdk_bdev_open_ext, int, + (const char *bdev_name, bool write, spdk_bdev_event_cb_t event_cb, + void *event_ctx, struct spdk_bdev_desc **desc), + 0); + DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc)); DEFINE_STUB(spdk_bdev_get_name, const char *, @@ -144,7 +149,7 @@ static struct spdk_scsi_lun *lun_construct(void) struct spdk_scsi_lun *lun; struct spdk_bdev bdev; - lun = scsi_lun_construct(&bdev, NULL, NULL); + lun = scsi_lun_construct(&bdev, NULL, NULL, NULL, NULL); SPDK_CU_ASSERT_FATAL(lun != NULL); return lun; @@ -450,7 +455,7 @@ lun_construct_null_ctx(void) { struct spdk_scsi_lun *lun; - lun = scsi_lun_construct(NULL, NULL, NULL); + lun = scsi_lun_construct(NULL, NULL, NULL, NULL, NULL); /* lun should be NULL since we passed NULL for the ctx pointer. */ CU_ASSERT(lun == NULL); @@ -585,7 +590,7 @@ lun_check_pending_tasks_only_for_specific_initiator(void) struct spdk_scsi_port initiator_port2 = {}; struct spdk_scsi_port initiator_port3 = {}; - lun = scsi_lun_construct(&bdev, NULL, NULL); + lun = scsi_lun_construct(&bdev, NULL, NULL, NULL, NULL); task1.initiator_port = &initiator_port1; task2.initiator_port = &initiator_port2; @@ -651,7 +656,7 @@ abort_pending_mgmt_tasks_when_lun_is_removed(void) struct spdk_scsi_lun *lun; struct spdk_scsi_task task1, task2, task3; - lun = scsi_lun_construct(&bdev, NULL, NULL); + lun = scsi_lun_construct(&bdev, NULL, NULL, NULL, NULL); /* Normal case */ ut_init_task(&task1);