bdev/virtio: cleanup target scan
scan_finish function will now unconditionally finish the scan, while scan_next will continue scanning on the next target. Now that target scan be aborted from external sources (device removal during re-scan). There is simply a need for such scan_finish function. Change-Id: I49e0dd6ea7abdddc24c23af362313d657fe1dc66 Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/391866 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
f217aa4667
commit
b212741eeb
@ -126,9 +126,6 @@ struct virtio_scsi_scan_base {
|
|||||||
bdev_virtio_create_cb cb_fn;
|
bdev_virtio_create_cb cb_fn;
|
||||||
void *cb_arg;
|
void *cb_arg;
|
||||||
|
|
||||||
/* Currently queried target */
|
|
||||||
unsigned target;
|
|
||||||
|
|
||||||
/** Remaining attempts for sending the current request. */
|
/** Remaining attempts for sending the current request. */
|
||||||
unsigned retries;
|
unsigned retries;
|
||||||
|
|
||||||
@ -862,51 +859,30 @@ bdev_virtio_scsi_ch_destroy_cb(void *io_device, void *ctx_buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_virtio_scsi_dev_scan_abort(struct virtio_scsi_scan_base *base, int error)
|
_virtio_scsi_dev_scan_finish(struct virtio_scsi_scan_base *base, int errnum)
|
||||||
{
|
{
|
||||||
struct virtio_scsi_dev *svdev = base->svdev;
|
struct virtio_scsi_dev *svdev = base->svdev;
|
||||||
|
size_t bdevs_cnt;
|
||||||
spdk_put_io_channel(spdk_io_channel_from_ctx(base->channel));
|
|
||||||
|
|
||||||
if (base->cb_fn) {
|
|
||||||
base->cb_fn(base->cb_arg, error, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
spdk_dma_free(base);
|
|
||||||
svdev->scan_ctx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_virtio_scsi_dev_scan_finish(struct virtio_scsi_scan_base *base)
|
|
||||||
{
|
|
||||||
struct virtio_scsi_dev *svdev = base->svdev;
|
|
||||||
size_t bdevs_cnt = 0;
|
|
||||||
struct spdk_bdev *bdevs[BDEV_VIRTIO_MAX_TARGET];
|
struct spdk_bdev *bdevs[BDEV_VIRTIO_MAX_TARGET];
|
||||||
struct virtio_scsi_disk *disk;
|
struct virtio_scsi_disk *disk;
|
||||||
int rc, cb_errnum = 0;
|
|
||||||
|
|
||||||
base->target++;
|
spdk_put_io_channel(spdk_io_channel_from_ctx(base->channel));
|
||||||
if (base->target < BDEV_VIRTIO_MAX_TARGET) {
|
base->svdev->scan_ctx = NULL;
|
||||||
rc = _virtio_scsi_dev_scan_next(base);
|
|
||||||
if (rc != 0) {
|
if (base->cb_fn == NULL) {
|
||||||
assert(false);
|
spdk_dma_free(base);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdk_put_io_channel(spdk_io_channel_from_ctx(base->channel));
|
bdevs_cnt = 0;
|
||||||
|
if (errnum == 0) {
|
||||||
TAILQ_FOREACH(disk, &svdev->luns, link) {
|
TAILQ_FOREACH(disk, &svdev->luns, link) {
|
||||||
bdevs[bdevs_cnt] = &disk->bdev;
|
bdevs[bdevs_cnt] = &disk->bdev;
|
||||||
bdevs_cnt++;
|
bdevs_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
base->svdev->scan_ctx = NULL;
|
|
||||||
|
|
||||||
if (base->cb_fn) {
|
|
||||||
base->cb_fn(base->cb_arg, cb_errnum, bdevs, bdevs_cnt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base->cb_fn(base->cb_arg, errnum, bdevs, bdevs_cnt);
|
||||||
spdk_dma_free(base);
|
spdk_dma_free(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,6 +906,26 @@ send_scan_io(struct virtio_scsi_scan_base *base)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
send_inquiry(struct virtio_scsi_scan_base *base, uint8_t target_id)
|
||||||
|
{
|
||||||
|
struct iovec *iov = &base->iov;
|
||||||
|
struct virtio_scsi_cmd_req *req = &base->io_ctx.req;
|
||||||
|
struct spdk_scsi_cdb_inquiry *cdb;
|
||||||
|
|
||||||
|
memset(req, 0, sizeof(*req));
|
||||||
|
req->lun[0] = 1;
|
||||||
|
req->lun[1] = target_id;
|
||||||
|
|
||||||
|
iov->iov_len = BDEV_VIRTIO_SCAN_PAYLOAD_SIZE;
|
||||||
|
|
||||||
|
cdb = (struct spdk_scsi_cdb_inquiry *)req->cdb;
|
||||||
|
cdb->opcode = SPDK_SPC_INQUIRY;
|
||||||
|
to_be16(cdb->alloc_len, BDEV_VIRTIO_SCAN_PAYLOAD_SIZE);
|
||||||
|
|
||||||
|
return send_scan_io(base);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_inquiry_vpd(struct virtio_scsi_scan_base *base, uint8_t target_id, uint8_t page_code)
|
send_inquiry_vpd(struct virtio_scsi_scan_base *base, uint8_t target_id, uint8_t page_code)
|
||||||
{
|
{
|
||||||
@ -1262,7 +1258,7 @@ process_read_cap_10(struct virtio_scsi_scan_base *base)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
_virtio_scsi_dev_scan_finish(base);
|
_virtio_scsi_dev_scan_next(base);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1286,7 +1282,7 @@ process_read_cap_16(struct virtio_scsi_scan_base *base)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
_virtio_scsi_dev_scan_finish(base);
|
_virtio_scsi_dev_scan_next(base);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1301,7 +1297,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base)
|
|||||||
if (base->io_ctx.iov_req.iov_len < sizeof(struct virtio_scsi_cmd_req) ||
|
if (base->io_ctx.iov_req.iov_len < sizeof(struct virtio_scsi_cmd_req) ||
|
||||||
base->io_ctx.iov_resp.iov_len < sizeof(struct virtio_scsi_cmd_resp)) {
|
base->io_ctx.iov_resp.iov_len < sizeof(struct virtio_scsi_cmd_resp)) {
|
||||||
SPDK_ERRLOG("Received target scan message with invalid length.\n");
|
SPDK_ERRLOG("Received target scan message with invalid length.\n");
|
||||||
_virtio_scsi_dev_scan_finish(base);
|
_virtio_scsi_dev_scan_next(base);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,7 +1313,7 @@ process_scan_resp(struct virtio_scsi_scan_base *base)
|
|||||||
SPDK_NOTICELOG("Target %"PRIu8" is present, but unavailable.\n", target_id);
|
SPDK_NOTICELOG("Target %"PRIu8" is present, but unavailable.\n", target_id);
|
||||||
SPDK_TRACEDUMP(SPDK_LOG_VIRTIO, "CDB", req->cdb, sizeof(req->cdb));
|
SPDK_TRACEDUMP(SPDK_LOG_VIRTIO, "CDB", req->cdb, sizeof(req->cdb));
|
||||||
SPDK_TRACEDUMP(SPDK_LOG_VIRTIO, "SENSE DATA", resp->sense, sizeof(resp->sense));
|
SPDK_TRACEDUMP(SPDK_LOG_VIRTIO, "SENSE DATA", resp->sense, sizeof(resp->sense));
|
||||||
_virtio_scsi_dev_scan_finish(base);
|
_virtio_scsi_dev_scan_next(base);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1354,45 +1350,25 @@ process_scan_resp(struct virtio_scsi_scan_base *base)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
_virtio_scsi_dev_scan_finish(base);
|
_virtio_scsi_dev_scan_next(base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_virtio_scsi_dev_scan_next(struct virtio_scsi_scan_base *base)
|
_virtio_scsi_dev_scan_next(struct virtio_scsi_scan_base *base)
|
||||||
{
|
{
|
||||||
struct virtio_scsi_io_ctx *io_ctx;
|
uint8_t target_id;
|
||||||
struct virtio_scsi_cmd_req *req;
|
|
||||||
struct virtio_scsi_cmd_resp *resp;
|
target_id = base->info.target + 1;
|
||||||
struct spdk_scsi_cdb_inquiry *cdb;
|
if (target_id == BDEV_VIRTIO_MAX_TARGET) {
|
||||||
struct iovec *iov;
|
_virtio_scsi_dev_scan_finish(base, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&base->info, 0, sizeof(base->info));
|
memset(&base->info, 0, sizeof(base->info));
|
||||||
base->info.target = base->target;
|
base->info.target = target_id;
|
||||||
|
|
||||||
io_ctx = &base->io_ctx;
|
return send_inquiry(base, target_id);
|
||||||
req = &io_ctx->req;
|
|
||||||
resp = &io_ctx->resp;
|
|
||||||
iov = &base->iov;
|
|
||||||
|
|
||||||
io_ctx->iov_req.iov_base = req;
|
|
||||||
io_ctx->iov_req.iov_len = sizeof(*req);
|
|
||||||
|
|
||||||
io_ctx->iov_resp.iov_base = resp;
|
|
||||||
io_ctx->iov_resp.iov_len = sizeof(*resp);
|
|
||||||
|
|
||||||
iov[0].iov_base = (void *)&base->payload;
|
|
||||||
iov[0].iov_len = BDEV_VIRTIO_SCAN_PAYLOAD_SIZE;
|
|
||||||
|
|
||||||
req->lun[0] = 1;
|
|
||||||
req->lun[1] = base->info.target;
|
|
||||||
|
|
||||||
cdb = (struct spdk_scsi_cdb_inquiry *)req->cdb;
|
|
||||||
cdb->opcode = SPDK_SPC_INQUIRY;
|
|
||||||
to_be16(cdb->alloc_len, BDEV_VIRTIO_SCAN_PAYLOAD_SIZE);
|
|
||||||
|
|
||||||
base->retries = SCAN_REQUEST_RETRIES;
|
|
||||||
return send_scan_io(base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1467,6 +1443,9 @@ virtio_scsi_dev_scan(struct virtio_scsi_dev *svdev, bdev_virtio_create_cb cb_fn,
|
|||||||
{
|
{
|
||||||
struct virtio_scsi_scan_base *base;
|
struct virtio_scsi_scan_base *base;
|
||||||
struct spdk_io_channel *io_ch;
|
struct spdk_io_channel *io_ch;
|
||||||
|
struct virtio_scsi_io_ctx *io_ctx;
|
||||||
|
struct virtio_scsi_cmd_req *req;
|
||||||
|
struct virtio_scsi_cmd_resp *resp;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
io_ch = spdk_get_io_channel(svdev);
|
io_ch = spdk_get_io_channel(svdev);
|
||||||
@ -1487,7 +1466,22 @@ virtio_scsi_dev_scan(struct virtio_scsi_dev *svdev, bdev_virtio_create_cb cb_fn,
|
|||||||
|
|
||||||
base->channel = spdk_io_channel_get_ctx(io_ch);
|
base->channel = spdk_io_channel_get_ctx(io_ch);
|
||||||
svdev->scan_ctx = base;
|
svdev->scan_ctx = base;
|
||||||
rc = _virtio_scsi_dev_scan_next(base);
|
|
||||||
|
memset(&base->info, 0, sizeof(base->info));
|
||||||
|
base->info.target = 0;
|
||||||
|
|
||||||
|
base->iov.iov_base = base->payload;
|
||||||
|
io_ctx = &base->io_ctx;
|
||||||
|
req = &io_ctx->req;
|
||||||
|
resp = &io_ctx->resp;
|
||||||
|
io_ctx->iov_req.iov_base = req;
|
||||||
|
io_ctx->iov_req.iov_len = sizeof(*req);
|
||||||
|
io_ctx->iov_resp.iov_base = resp;
|
||||||
|
io_ctx->iov_resp.iov_len = sizeof(*resp);
|
||||||
|
|
||||||
|
base->retries = SCAN_REQUEST_RETRIES;
|
||||||
|
|
||||||
|
rc = send_inquiry(base, 0);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SPDK_ERRLOG("Failed to start target scan.\n");
|
SPDK_ERRLOG("Failed to start target scan.\n");
|
||||||
spdk_put_io_channel(io_ch);
|
spdk_put_io_channel(io_ch);
|
||||||
@ -1607,7 +1601,7 @@ virtio_scsi_dev_remove(struct virtio_scsi_dev *svdev)
|
|||||||
|
|
||||||
scan_ctx = svdev->scan_ctx;
|
scan_ctx = svdev->scan_ctx;
|
||||||
if (scan_ctx) {
|
if (scan_ctx) {
|
||||||
_virtio_scsi_dev_scan_abort(scan_ctx, -EINTR);
|
_virtio_scsi_dev_scan_finish(scan_ctx, -EINTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(disk, &svdev->luns, link, disk_tmp) {
|
TAILQ_FOREACH_SAFE(disk, &svdev->luns, link, disk_tmp) {
|
||||||
|
Loading…
Reference in New Issue
Block a user