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 <fengli@smartx.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4353
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Li Feng 2020-09-08 23:32:48 +08:00 committed by Tomasz Zawadzki
parent 1e6152c185
commit 5029fe14b6
9 changed files with 135 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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