bdev/split: call get buffer function before forwarding read I/O to the base bdev
iSCSI target does not allocate data buffer on read, and delegate allocation to the bdev. When the bdev is a split vbdev, the split vbdev does not allocate data buffer and delegate allocation to the backend bdev. In this case, iSCSI target expects the buffer is allocated until notifying completion to the split vbdev. However, the split vbdev notifies completion to the backend bdev when calling the callback of iSCSI target. The backend bdev frees the buffer immediately, but iSCSI target still uses the buffer. If the buffer is reused by another I/O, data corruption will occur. For this issue, vbdev_split_submti_request() calls spdk_bdev_io_get_buf() when the I/O is read, and its callback vbdev_split_get_buf_cb calls _vbdev_split_submit_request() then. This will ensure the buffer is allocated before forwarding I/O to the backed bdev. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Icfd0663b548479ac0bf6b5b49420f144142e3300 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/461348 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
5f5a5d4a58
commit
25532d08f8
@ -83,7 +83,7 @@ static int vbdev_split_config_json(struct spdk_json_write_ctx *w);
|
|||||||
static int vbdev_split_get_ctx_size(void);
|
static int vbdev_split_get_ctx_size(void);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io);
|
_vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io);
|
||||||
|
|
||||||
static struct spdk_bdev_module split_if = {
|
static struct spdk_bdev_module split_if = {
|
||||||
.name = "split",
|
.name = "split",
|
||||||
@ -126,7 +126,7 @@ vbdev_split_resubmit_io(void *arg)
|
|||||||
{
|
{
|
||||||
struct vbdev_split_bdev_io *split_io = (struct vbdev_split_bdev_io *)arg;
|
struct vbdev_split_bdev_io *split_io = (struct vbdev_split_bdev_io *)arg;
|
||||||
|
|
||||||
vbdev_split_submit_request(split_io->ch, split_io->bdev_io);
|
_vbdev_split_submit_request(split_io->ch, split_io->bdev_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -147,7 +147,7 @@ vbdev_split_queue_io(struct vbdev_split_bdev_io *split_io)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
|
_vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
|
||||||
{
|
{
|
||||||
struct vbdev_split_channel *ch = spdk_io_channel_get_ctx(_ch);
|
struct vbdev_split_channel *ch = spdk_io_channel_get_ctx(_ch);
|
||||||
struct vbdev_split_bdev_io *io_ctx = (struct vbdev_split_bdev_io *)bdev_io->driver_ctx;
|
struct vbdev_split_bdev_io *io_ctx = (struct vbdev_split_bdev_io *)bdev_io->driver_ctx;
|
||||||
@ -167,6 +167,31 @@ vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbdev_split_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, bool success)
|
||||||
|
{
|
||||||
|
if (!success) {
|
||||||
|
spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_vbdev_split_submit_request(ch, bdev_io);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbdev_split_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io)
|
||||||
|
{
|
||||||
|
switch (bdev_io->type) {
|
||||||
|
case SPDK_BDEV_IO_TYPE_READ:
|
||||||
|
spdk_bdev_io_get_buf(bdev_io, vbdev_split_get_buf_cb,
|
||||||
|
bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_vbdev_split_submit_request(_ch, bdev_io);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vbdev_split_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
|
vbdev_split_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user