From c60ae3c356490f6c59ee001404904836a6ea595a Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Fri, 27 Jul 2018 12:23:26 -0700 Subject: [PATCH] raid: get buffer on reads before sending child ios For front-ends like iSCSI (and NVMe-oF in the future) which want the backend to specify the data buffer, the RAID module doesn't copy the pointer to the allocated buffer from the child IO back to the parent IO. It really can't copy the pointer - the child IO owns it and will free it. So the RAID module needs to allocate the buffer first and then pass it down. Signed-off-by: Jim Harris Change-Id: I3b1eceac9b1cdd26130e59e1d400c9869a19f881 Reviewed-on: https://review.gerrithub.io/420677 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Chandler-Test-Pool: SPDK Automated Test System --- lib/bdev/raid/bdev_raid.c | 8 ++++++++ test/unit/lib/bdev/bdev_raid.c/bdev_raid_ut.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/lib/bdev/raid/bdev_raid.c b/lib/bdev/raid/bdev_raid.c index 5b09db10a..ffd9a614b 100644 --- a/lib/bdev/raid/bdev_raid.c +++ b/lib/bdev/raid/bdev_raid.c @@ -647,6 +647,14 @@ raid_bdev_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_i { switch (bdev_io->type) { case SPDK_BDEV_IO_TYPE_READ: + if (bdev_io->u.bdev.iovs[0].iov_base == NULL) { + spdk_bdev_io_get_buf(bdev_io, _raid_bdev_submit_rw_request, + bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); + } else { + /* Just call it directly if iov_base is already populated. */ + _raid_bdev_submit_rw_request(ch, bdev_io); + } + break; case SPDK_BDEV_IO_TYPE_WRITE: _raid_bdev_submit_rw_request(ch, bdev_io); break; diff --git a/test/unit/lib/bdev/bdev_raid.c/bdev_raid_ut.c b/test/unit/lib/bdev/bdev_raid.c/bdev_raid_ut.c index 02b73c52d..489f4c2b9 100644 --- a/test/unit/lib/bdev/bdev_raid.c/bdev_raid_ut.c +++ b/test/unit/lib/bdev/bdev_raid.c/bdev_raid_ut.c @@ -165,6 +165,13 @@ reset_globals(void) rpc_req_size = 0; } +void +spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, + uint64_t len) +{ + CU_ASSERT(false); +} + /* Store the IO completion status in global variable to verify by various tests */ void spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)