scsi: Add support for hotplug in scsi layer.

Change-Id: Ic779a79d41d60b6998f9bd05ca4a59c1301a10ac
Signed-off-by: Cunyin Chang <cunyin.chang@intel.com>
This commit is contained in:
Cunyin Chang 2017-01-16 21:18:12 +08:00 committed by cunyinch
parent 4055a502ea
commit fca35b7b96
3 changed files with 61 additions and 2 deletions

View File

@ -218,6 +218,15 @@ struct spdk_scsi_lun {
/** Name for this LUN. */
char name[SPDK_SCSI_LUN_MAX_NAME_LENGTH];
/** Poller to release the resource of the lun when it is hot removed */
struct spdk_poller *hotplug_poller;
/** The core hotplug_poller is assigned */
uint32_t lcore;
/** The LUN is removed */
bool removed;
TAILQ_HEAD(tasks, spdk_scsi_task) tasks; /* submitted tasks */
TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; /* pending tasks */
};

View File

@ -35,6 +35,7 @@
#include "scsi_internal.h"
#include "spdk/endian.h"
#include "spdk/io_channel.h"
#include "spdk/event.h"
void
spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
@ -235,7 +236,15 @@ spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun)
spdk_trace_record(TRACE_SCSI_TASK_START, lun->dev->id, task->length, (uintptr_t)task, 0);
TAILQ_REMOVE(&lun->pending_tasks, task, scsi_link);
TAILQ_INSERT_TAIL(&lun->tasks, task, scsi_link);
rc = spdk_bdev_scsi_execute(lun->bdev, task);
if (!lun->removed) {
rc = spdk_bdev_scsi_execute(lun->bdev, task);
} else {
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
SPDK_SCSI_SENSE_ABORTED_COMMAND,
SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
rc = SPDK_SCSI_TASK_COMPLETE;
}
switch (rc) {
case SPDK_SCSI_TASK_PENDING:
@ -251,6 +260,26 @@ spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun)
}
}
static void
spdk_scsi_lun_hotplug(void *arg)
{
struct spdk_scsi_lun *lun = (struct spdk_scsi_lun *)arg;
if (TAILQ_EMPTY(&lun->pending_tasks) && TAILQ_EMPTY(&lun->tasks)) {
spdk_scsi_lun_free_io_channel(lun);
spdk_scsi_lun_delete(lun->name);
}
}
static void spdk_scsi_lun_hot_remove(void *remove_ctx)
{
struct spdk_scsi_lun *lun = (struct spdk_scsi_lun *)remove_ctx;
lun->removed = true;
spdk_poller_register(&lun->hotplug_poller, spdk_scsi_lun_hotplug, lun,
lun->lcore, 0);
}
/*!
\brief Constructs a new spdk_scsi_lun object based on the provided parameters.
@ -285,7 +314,7 @@ spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev)
return NULL;
}
if (!spdk_bdev_claim(bdev, NULL, NULL)) {
if (!spdk_bdev_claim(bdev, spdk_scsi_lun_hot_remove, lun)) {
SPDK_ERRLOG("LUN %s: bdev %s is already claimed\n", name, bdev->name);
free(lun);
return NULL;
@ -312,6 +341,7 @@ int
spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun)
{
spdk_bdev_unclaim(lun->bdev);
spdk_poller_unregister(&lun->hotplug_poller, NULL);
spdk_scsi_lun_db_delete(lun);
free(lun);
@ -394,6 +424,8 @@ int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun)
return -1;
}
lun->lcore = spdk_app_get_current_core();
lun->io_channel = spdk_bdev_get_io_channel(lun->bdev, SPDK_IO_PRIORITY_DEFAULT);
if (lun->io_channel == NULL) {
return -1;

View File

@ -50,6 +50,24 @@ static bool g_lun_execute_fail = false;
static int g_lun_execute_status = SPDK_SCSI_TASK_PENDING;
static uint32_t g_task_count = 0;
void
spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg,
uint32_t lcore, uint64_t period_microseconds)
{
}
void
spdk_poller_unregister(struct spdk_poller **ppoller,
struct spdk_event *complete)
{
}
uint32_t
spdk_app_get_current_core(void)
{
return 0;
}
void spdk_trace_record(uint16_t tpoint_id, uint16_t poller_id, uint32_t size,
uint64_t object_id, uint64_t arg1)
{