lib/scsi: Pass bdev_name instead of bdev to scsi_lun_construct()
Pass not bdev but bdev_name to scsi_lun_construct() to fix the race condition due to the time gap between spdk_bdev_get_by_name() and spdk_bdev_open(). A pointer to a bdev is valid only while the bdev is opened. spdk_bdev_open() has been replaced recently by spdk_bdev_open_ext(), but the issue still existed. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Ic462422dbc2501c24907f56a36570fbb54fef65b Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4482 Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
357c9580a1
commit
ab808d2b68
@ -151,16 +151,8 @@ spdk_scsi_dev_add_lun_ext(struct spdk_scsi_dev *dev, const char *bdev_name, int
|
|||||||
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
void *hotremove_ctx)
|
void *hotremove_ctx)
|
||||||
{
|
{
|
||||||
struct spdk_bdev *bdev;
|
|
||||||
struct spdk_scsi_lun *lun;
|
struct spdk_scsi_lun *lun;
|
||||||
|
|
||||||
bdev = spdk_bdev_get_by_name(bdev_name);
|
|
||||||
if (bdev == NULL) {
|
|
||||||
SPDK_ERRLOG("device %s: cannot find bdev '%s' (target %d)\n",
|
|
||||||
dev->name, bdev_name, lun_id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search the lowest free LUN ID if LUN ID is default */
|
/* Search the lowest free LUN ID if LUN ID is default */
|
||||||
if (lun_id == -1) {
|
if (lun_id == -1) {
|
||||||
lun_id = scsi_dev_find_lowest_free_lun_id(dev);
|
lun_id = scsi_dev_find_lowest_free_lun_id(dev);
|
||||||
@ -170,7 +162,7 @@ spdk_scsi_dev_add_lun_ext(struct spdk_scsi_dev *dev, const char *bdev_name, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lun = scsi_lun_construct(bdev, resize_cb, resize_ctx, hotremove_cb, hotremove_ctx);
|
lun = scsi_lun_construct(bdev_name, resize_cb, resize_ctx, hotremove_cb, hotremove_ctx);
|
||||||
if (lun == NULL) {
|
if (lun == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -418,12 +418,12 @@ bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev,
|
|||||||
/**
|
/**
|
||||||
* \brief Constructs a new spdk_scsi_lun object based on the provided parameters.
|
* \brief Constructs a new spdk_scsi_lun object based on the provided parameters.
|
||||||
*
|
*
|
||||||
* \param bdev bdev associated with this LUN
|
* \param bdev_name Bdev name to open and associate with this LUN
|
||||||
*
|
*
|
||||||
* \return NULL if bdev == NULL
|
* \return NULL if bdev whose name matches is not found
|
||||||
* \return pointer to the new spdk_scsi_lun object otherwise
|
* \return pointer to the new spdk_scsi_lun object otherwise
|
||||||
*/
|
*/
|
||||||
struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev,
|
struct spdk_scsi_lun *scsi_lun_construct(const char *bdev_name,
|
||||||
void (*resize_cb)(const struct spdk_scsi_lun *, void *),
|
void (*resize_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
void *resize_ctx,
|
void *resize_ctx,
|
||||||
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
@ -432,8 +432,8 @@ struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev,
|
|||||||
struct spdk_scsi_lun *lun;
|
struct spdk_scsi_lun *lun;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (bdev == NULL) {
|
if (bdev_name == NULL) {
|
||||||
SPDK_ERRLOG("bdev must be non-NULL\n");
|
SPDK_ERRLOG("bdev_name must be non-NULL\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,10 +443,10 @@ struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = spdk_bdev_open_ext(spdk_bdev_get_name(bdev), true, bdev_event_cb, lun, &lun->bdev_desc);
|
rc = spdk_bdev_open_ext(bdev_name, true, bdev_event_cb, lun, &lun->bdev_desc);
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
SPDK_ERRLOG("bdev %s cannot be opened, error=%d\n", spdk_bdev_get_name(bdev), rc);
|
SPDK_ERRLOG("bdev %s cannot be opened, error=%d\n", bdev_name, rc);
|
||||||
free(lun);
|
free(lun);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -458,7 +458,8 @@ struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev,
|
|||||||
TAILQ_INIT(&lun->mgmt_tasks);
|
TAILQ_INIT(&lun->mgmt_tasks);
|
||||||
TAILQ_INIT(&lun->pending_mgmt_tasks);
|
TAILQ_INIT(&lun->pending_mgmt_tasks);
|
||||||
|
|
||||||
lun->bdev = bdev;
|
/* Bdev is not removed while it is opened. */
|
||||||
|
lun->bdev = spdk_bdev_desc_get_bdev(lun->bdev_desc);
|
||||||
lun->io_channel = NULL;
|
lun->io_channel = NULL;
|
||||||
lun->hotremove_cb = hotremove_cb;
|
lun->hotremove_cb = hotremove_cb;
|
||||||
lun->hotremove_ctx = hotremove_ctx;
|
lun->hotremove_ctx = hotremove_ctx;
|
||||||
|
@ -175,7 +175,7 @@ struct spdk_scsi_lun {
|
|||||||
struct spdk_poller *reset_poller;
|
struct spdk_poller *reset_poller;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev,
|
struct spdk_scsi_lun *scsi_lun_construct(const char *bdev_name,
|
||||||
void (*resize_cb)(const struct spdk_scsi_lun *, void *),
|
void (*resize_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
void *resize_ctx,
|
void *resize_ctx,
|
||||||
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
|
@ -43,25 +43,14 @@
|
|||||||
|
|
||||||
#include "spdk_internal/mock.h"
|
#include "spdk_internal/mock.h"
|
||||||
|
|
||||||
/* Unit test bdev mockup */
|
static char *g_bdev_names[] = {
|
||||||
struct spdk_bdev {
|
"malloc0",
|
||||||
char name[100];
|
"malloc1",
|
||||||
};
|
|
||||||
|
|
||||||
static struct spdk_bdev g_bdevs[] = {
|
|
||||||
{"malloc0"},
|
|
||||||
{"malloc1"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct spdk_scsi_port *g_initiator_port_with_pending_tasks = NULL;
|
static struct spdk_scsi_port *g_initiator_port_with_pending_tasks = NULL;
|
||||||
static struct spdk_scsi_port *g_initiator_port_with_pending_mgmt_tasks = NULL;
|
static struct spdk_scsi_port *g_initiator_port_with_pending_mgmt_tasks = NULL;
|
||||||
|
|
||||||
const char *
|
|
||||||
spdk_bdev_get_name(const struct spdk_bdev *bdev)
|
|
||||||
{
|
|
||||||
return bdev->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct spdk_scsi_task *
|
static struct spdk_scsi_task *
|
||||||
spdk_get_task(uint32_t *owner_task_ctr)
|
spdk_get_task(uint32_t *owner_task_ctr)
|
||||||
{
|
{
|
||||||
@ -81,20 +70,25 @@ spdk_scsi_task_put(struct spdk_scsi_task *task)
|
|||||||
free(task);
|
free(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_scsi_lun *scsi_lun_construct(struct spdk_bdev *bdev,
|
struct spdk_scsi_lun *scsi_lun_construct(const char *bdev_name,
|
||||||
void (*resize_cb)(const struct spdk_scsi_lun *, void *),
|
void (*resize_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
void *resize_ctx,
|
void *resize_ctx,
|
||||||
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
void (*hotremove_cb)(const struct spdk_scsi_lun *, void *),
|
||||||
void *hotremove_ctx)
|
void *hotremove_ctx)
|
||||||
{
|
{
|
||||||
struct spdk_scsi_lun *lun;
|
struct spdk_scsi_lun *lun;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
lun = calloc(1, sizeof(struct spdk_scsi_lun));
|
for (i = 0; i < SPDK_COUNTOF(g_bdev_names); i++) {
|
||||||
SPDK_CU_ASSERT_FATAL(lun != NULL);
|
if (strcmp(bdev_name, g_bdev_names[i]) == 0) {
|
||||||
|
lun = calloc(1, sizeof(struct spdk_scsi_lun));
|
||||||
|
SPDK_CU_ASSERT_FATAL(lun != NULL);
|
||||||
|
|
||||||
lun->bdev = bdev;
|
return lun;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return lun;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -103,20 +97,6 @@ scsi_lun_destruct(struct spdk_scsi_lun *lun)
|
|||||||
free(lun);
|
free(lun);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_bdev *
|
|
||||||
spdk_bdev_get_by_name(const char *bdev_name)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < SPDK_COUNTOF(g_bdevs); i++) {
|
|
||||||
if (strcmp(bdev_name, g_bdevs[i].name) == 0) {
|
|
||||||
return &g_bdevs[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_STUB_V(scsi_lun_execute_mgmt_task,
|
DEFINE_STUB_V(scsi_lun_execute_mgmt_task,
|
||||||
(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task));
|
(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task));
|
||||||
|
|
||||||
|
@ -105,6 +105,9 @@ DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
|
|||||||
DEFINE_STUB(spdk_bdev_get_name, const char *,
|
DEFINE_STUB(spdk_bdev_get_name, const char *,
|
||||||
(const struct spdk_bdev *bdev), "test");
|
(const struct spdk_bdev *bdev), "test");
|
||||||
|
|
||||||
|
DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *,
|
||||||
|
(struct spdk_bdev_desc *bdev_desc), NULL);
|
||||||
|
|
||||||
DEFINE_STUB_V(spdk_scsi_dev_queue_mgmt_task,
|
DEFINE_STUB_V(spdk_scsi_dev_queue_mgmt_task,
|
||||||
(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task));
|
(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task));
|
||||||
|
|
||||||
@ -147,9 +150,8 @@ DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *,
|
|||||||
static struct spdk_scsi_lun *lun_construct(void)
|
static struct spdk_scsi_lun *lun_construct(void)
|
||||||
{
|
{
|
||||||
struct spdk_scsi_lun *lun;
|
struct spdk_scsi_lun *lun;
|
||||||
struct spdk_bdev bdev;
|
|
||||||
|
|
||||||
lun = scsi_lun_construct(&bdev, NULL, NULL, NULL, NULL);
|
lun = scsi_lun_construct("ut_bdev", NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
SPDK_CU_ASSERT_FATAL(lun != NULL);
|
SPDK_CU_ASSERT_FATAL(lun != NULL);
|
||||||
return lun;
|
return lun;
|
||||||
@ -582,7 +584,6 @@ lun_reset_task_suspend_scsi_task(void)
|
|||||||
static void
|
static void
|
||||||
lun_check_pending_tasks_only_for_specific_initiator(void)
|
lun_check_pending_tasks_only_for_specific_initiator(void)
|
||||||
{
|
{
|
||||||
struct spdk_bdev bdev = {};
|
|
||||||
struct spdk_scsi_lun *lun;
|
struct spdk_scsi_lun *lun;
|
||||||
struct spdk_scsi_task task1 = {};
|
struct spdk_scsi_task task1 = {};
|
||||||
struct spdk_scsi_task task2 = {};
|
struct spdk_scsi_task task2 = {};
|
||||||
@ -590,7 +591,7 @@ lun_check_pending_tasks_only_for_specific_initiator(void)
|
|||||||
struct spdk_scsi_port initiator_port2 = {};
|
struct spdk_scsi_port initiator_port2 = {};
|
||||||
struct spdk_scsi_port initiator_port3 = {};
|
struct spdk_scsi_port initiator_port3 = {};
|
||||||
|
|
||||||
lun = scsi_lun_construct(&bdev, NULL, NULL, NULL, NULL);
|
lun = scsi_lun_construct("ut_bdev", NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
task1.initiator_port = &initiator_port1;
|
task1.initiator_port = &initiator_port1;
|
||||||
task2.initiator_port = &initiator_port2;
|
task2.initiator_port = &initiator_port2;
|
||||||
@ -652,11 +653,10 @@ lun_check_pending_tasks_only_for_specific_initiator(void)
|
|||||||
static void
|
static void
|
||||||
abort_pending_mgmt_tasks_when_lun_is_removed(void)
|
abort_pending_mgmt_tasks_when_lun_is_removed(void)
|
||||||
{
|
{
|
||||||
struct spdk_bdev bdev = {};
|
|
||||||
struct spdk_scsi_lun *lun;
|
struct spdk_scsi_lun *lun;
|
||||||
struct spdk_scsi_task task1, task2, task3;
|
struct spdk_scsi_task task1, task2, task3;
|
||||||
|
|
||||||
lun = scsi_lun_construct(&bdev, NULL, NULL, NULL, NULL);
|
lun = scsi_lun_construct("ut_bdev", NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
/* Normal case */
|
/* Normal case */
|
||||||
ut_init_task(&task1);
|
ut_init_task(&task1);
|
||||||
|
Loading…
Reference in New Issue
Block a user