lib/scsi: Check pending tasks for the LUN only from the specific initiator

Refine helper functions spdk_scsi_lun_has_pending_mgmt_tasks() and
spdk_scsi_lun_has_pending_tasks() to be able to check tasks only from the
specific initiator.

SCSI port is used by passing the pointer and so simple pointer
comparison is appropriate in the functions.

Add UT code to test the updated functions.

The next patch will change spdk_scsi_dev_has_pending_tasks() to
get not only SCSI device but also initiator port and make iSCSI
target use the function to fix the issue.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I89c33e05bc6ab21baa6cbebf60950039a3dcecd0
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471336
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-10-15 16:22:38 +09:00 committed by Tomasz Zawadzki
parent 4787395283
commit f9583f2c0d
5 changed files with 123 additions and 10 deletions

View File

@ -425,8 +425,8 @@ spdk_scsi_dev_has_pending_tasks(const struct spdk_scsi_dev *dev)
for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; ++i) { for (i = 0; i < SPDK_SCSI_DEV_MAX_LUN; ++i) {
if (dev->lun[i] && if (dev->lun[i] &&
(spdk_scsi_lun_has_pending_tasks(dev->lun[i]) || (spdk_scsi_lun_has_pending_tasks(dev->lun[i], NULL) ||
spdk_scsi_lun_has_pending_mgmt_tasks(dev->lun[i]))) { spdk_scsi_lun_has_pending_mgmt_tasks(dev->lun[i], NULL))) {
return true; return true;
} }
} }

View File

@ -504,15 +504,53 @@ spdk_scsi_lun_get_dev(const struct spdk_scsi_lun *lun)
} }
bool bool
spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun) spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun,
const struct spdk_scsi_port *initiator_port)
{ {
return scsi_lun_has_pending_mgmt_tasks(lun); struct spdk_scsi_task *task;
if (initiator_port == NULL) {
return scsi_lun_has_pending_mgmt_tasks(lun);
}
TAILQ_FOREACH(task, &lun->pending_mgmt_tasks, scsi_link) {
if (task->initiator_port == initiator_port) {
return true;
}
}
TAILQ_FOREACH(task, &lun->mgmt_tasks, scsi_link) {
if (task->initiator_port == initiator_port) {
return true;
}
}
return false;
} }
bool bool
spdk_scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun) spdk_scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun,
const struct spdk_scsi_port *initiator_port)
{ {
return scsi_lun_has_pending_tasks(lun); struct spdk_scsi_task *task;
if (initiator_port == NULL) {
return scsi_lun_has_pending_tasks(lun);
}
TAILQ_FOREACH(task, &lun->pending_tasks, scsi_link) {
if (task->initiator_port == initiator_port) {
return true;
}
}
TAILQ_FOREACH(task, &lun->tasks, scsi_link) {
if (task->initiator_port == initiator_port) {
return true;
}
}
return false;
} }
bool bool

View File

@ -182,10 +182,12 @@ void spdk_scsi_lun_append_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task
void spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun); void spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun);
void spdk_scsi_lun_append_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); void spdk_scsi_lun_append_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task);
void spdk_scsi_lun_execute_mgmt_task(struct spdk_scsi_lun *lun); void spdk_scsi_lun_execute_mgmt_task(struct spdk_scsi_lun *lun);
bool spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun); bool spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun,
const struct spdk_scsi_port *initiator_port);
void spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); void spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task);
void spdk_scsi_lun_complete_reset_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); void spdk_scsi_lun_complete_reset_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task);
bool spdk_scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun); bool spdk_scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun,
const struct spdk_scsi_port *initiator_port);
int _spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun); int _spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun);
void _spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun *lun); void _spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun *lun);

View File

@ -119,7 +119,8 @@ DEFINE_STUB_V(spdk_scsi_lun_append_mgmt_task,
DEFINE_STUB_V(spdk_scsi_lun_execute_mgmt_task, (struct spdk_scsi_lun *lun)); DEFINE_STUB_V(spdk_scsi_lun_execute_mgmt_task, (struct spdk_scsi_lun *lun));
DEFINE_STUB(spdk_scsi_lun_has_pending_mgmt_tasks, bool, DEFINE_STUB(spdk_scsi_lun_has_pending_mgmt_tasks, bool,
(const struct spdk_scsi_lun *lun), false); (const struct spdk_scsi_lun *lun, const struct spdk_scsi_port *initiator_port),
false);
DEFINE_STUB_V(spdk_scsi_lun_append_task, DEFINE_STUB_V(spdk_scsi_lun_append_task,
(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)); (struct spdk_scsi_lun *lun, struct spdk_scsi_task *task));
@ -132,7 +133,8 @@ DEFINE_STUB(_spdk_scsi_lun_allocate_io_channel, int,
DEFINE_STUB_V(_spdk_scsi_lun_free_io_channel, (struct spdk_scsi_lun *lun)); DEFINE_STUB_V(_spdk_scsi_lun_free_io_channel, (struct spdk_scsi_lun *lun));
DEFINE_STUB(spdk_scsi_lun_has_pending_tasks, bool, DEFINE_STUB(spdk_scsi_lun_has_pending_tasks, bool,
(const struct spdk_scsi_lun *lun), false); (const struct spdk_scsi_lun *lun, const struct spdk_scsi_port *initiator_port),
false);
static void static void
dev_destruct_null_dev(void) dev_destruct_null_dev(void)

View File

@ -597,6 +597,75 @@ lun_reset_task_suspend_scsi_task(void)
CU_ASSERT_EQUAL(g_task_count, 0); CU_ASSERT_EQUAL(g_task_count, 0);
} }
static void
lun_check_pending_tasks_only_for_specific_initiator(void)
{
struct spdk_bdev bdev = {};
struct spdk_scsi_lun *lun;
struct spdk_scsi_task task1 = {};
struct spdk_scsi_task task2 = {};
struct spdk_scsi_port initiator_port1 = {};
struct spdk_scsi_port initiator_port2 = {};
struct spdk_scsi_port initiator_port3 = {};
lun = spdk_scsi_lun_construct(&bdev, NULL, NULL);
task1.initiator_port = &initiator_port1;
task2.initiator_port = &initiator_port2;
TAILQ_INSERT_TAIL(&lun->tasks, &task1, scsi_link);
TAILQ_INSERT_TAIL(&lun->tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_outstanding_tasks(lun) == true);
CU_ASSERT(scsi_lun_has_pending_tasks(lun) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port1) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port2) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port3) == false);
TAILQ_REMOVE(&lun->tasks, &task1, scsi_link);
TAILQ_REMOVE(&lun->tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_pending_tasks(lun) == false);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == false);
TAILQ_INSERT_TAIL(&lun->pending_tasks, &task1, scsi_link);
TAILQ_INSERT_TAIL(&lun->pending_tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_outstanding_tasks(lun) == false);
CU_ASSERT(scsi_lun_has_pending_tasks(lun) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port1) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port2) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, &initiator_port3) == false);
TAILQ_REMOVE(&lun->pending_tasks, &task1, scsi_link);
TAILQ_REMOVE(&lun->pending_tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_pending_tasks(lun) == false);
CU_ASSERT(spdk_scsi_lun_has_pending_tasks(lun, NULL) == false);
TAILQ_INSERT_TAIL(&lun->mgmt_tasks, &task1, scsi_link);
TAILQ_INSERT_TAIL(&lun->mgmt_tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port1) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port2) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port3) == false);
TAILQ_REMOVE(&lun->mgmt_tasks, &task1, scsi_link);
TAILQ_REMOVE(&lun->mgmt_tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == false);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == false);
TAILQ_INSERT_TAIL(&lun->pending_mgmt_tasks, &task1, scsi_link);
TAILQ_INSERT_TAIL(&lun->pending_mgmt_tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port1) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port2) == true);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, &initiator_port3) == false);
TAILQ_REMOVE(&lun->pending_mgmt_tasks, &task1, scsi_link);
TAILQ_REMOVE(&lun->pending_mgmt_tasks, &task2, scsi_link);
CU_ASSERT(scsi_lun_has_pending_mgmt_tasks(lun) == false);
CU_ASSERT(spdk_scsi_lun_has_pending_mgmt_tasks(lun, NULL) == false);
scsi_lun_remove(lun);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
@ -639,6 +708,8 @@ main(int argc, char **argv)
lun_reset_task_wait_scsi_task_complete) == NULL lun_reset_task_wait_scsi_task_complete) == NULL
|| CU_add_test(suite, "reset task suspend subsequent scsi task", || CU_add_test(suite, "reset task suspend subsequent scsi task",
lun_reset_task_suspend_scsi_task) == NULL lun_reset_task_suspend_scsi_task) == NULL
|| CU_add_test(suite, "check pending tasks only for specific initiator",
lun_check_pending_tasks_only_for_specific_initiator) == NULL
) { ) {
CU_cleanup_registry(); CU_cleanup_registry();
return CU_get_error(); return CU_get_error();