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:
parent
4055a502ea
commit
fca35b7b96
@ -218,6 +218,15 @@ struct spdk_scsi_lun {
|
|||||||
/** Name for this LUN. */
|
/** Name for this LUN. */
|
||||||
char name[SPDK_SCSI_LUN_MAX_NAME_LENGTH];
|
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(tasks, spdk_scsi_task) tasks; /* submitted tasks */
|
||||||
TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; /* pending tasks */
|
TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; /* pending tasks */
|
||||||
};
|
};
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "scsi_internal.h"
|
#include "scsi_internal.h"
|
||||||
#include "spdk/endian.h"
|
#include "spdk/endian.h"
|
||||||
#include "spdk/io_channel.h"
|
#include "spdk/io_channel.h"
|
||||||
|
#include "spdk/event.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
|
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);
|
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_REMOVE(&lun->pending_tasks, task, scsi_link);
|
||||||
TAILQ_INSERT_TAIL(&lun->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) {
|
switch (rc) {
|
||||||
case SPDK_SCSI_TASK_PENDING:
|
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.
|
\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;
|
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);
|
SPDK_ERRLOG("LUN %s: bdev %s is already claimed\n", name, bdev->name);
|
||||||
free(lun);
|
free(lun);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -312,6 +341,7 @@ int
|
|||||||
spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun)
|
spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun)
|
||||||
{
|
{
|
||||||
spdk_bdev_unclaim(lun->bdev);
|
spdk_bdev_unclaim(lun->bdev);
|
||||||
|
spdk_poller_unregister(&lun->hotplug_poller, NULL);
|
||||||
spdk_scsi_lun_db_delete(lun);
|
spdk_scsi_lun_db_delete(lun);
|
||||||
|
|
||||||
free(lun);
|
free(lun);
|
||||||
@ -394,6 +424,8 @@ int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lun->lcore = spdk_app_get_current_core();
|
||||||
|
|
||||||
lun->io_channel = spdk_bdev_get_io_channel(lun->bdev, SPDK_IO_PRIORITY_DEFAULT);
|
lun->io_channel = spdk_bdev_get_io_channel(lun->bdev, SPDK_IO_PRIORITY_DEFAULT);
|
||||||
if (lun->io_channel == NULL) {
|
if (lun->io_channel == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -50,6 +50,24 @@ static bool g_lun_execute_fail = false;
|
|||||||
static int g_lun_execute_status = SPDK_SCSI_TASK_PENDING;
|
static int g_lun_execute_status = SPDK_SCSI_TASK_PENDING;
|
||||||
static uint32_t g_task_count = 0;
|
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,
|
void spdk_trace_record(uint16_t tpoint_id, uint16_t poller_id, uint32_t size,
|
||||||
uint64_t object_id, uint64_t arg1)
|
uint64_t object_id, uint64_t arg1)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user