From b6765e8efaccca6005db77021a5fa8ccf510211d Mon Sep 17 00:00:00 2001 From: Vitaliy Mysak Date: Mon, 27 May 2019 21:10:06 +0000 Subject: [PATCH] ocf: fix offset check This patch fixes submission of partial IOs in bottom adapter Existing check (if offset > 0) was not sufficient to detect partial IOs because there could be an IO with offset = 0 but length < total size of iovs. This patch changes the check, but also free operation on completion because now the old free does not cover all situations when we allocate iovs. `Partial IOs` are the IOs handled by bottom adapter which specify only part of the internal iovs vector. So their length is less that the length of internal iovs vector. They exist because sometimes parts of single IO from top adapter need to be sent to different locations. Also, in general, IOs initiated by OCF (such as cleaner IOs) are represented as single big iov that is submitted by parts in form of 'Partial IOs'. Signed-off-by: Vitaliy Mysak Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/455821 (master) (cherry picked from commit 2bfa860dfe89d0803ff54e4b81c62c1e4778064e) Change-Id: I8ae47659fb34904c593a696d74d683a418ac9962 Signed-off-by: Tomasz Zawadzki Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/457587 Reviewed-by: Ben Walker Reviewed-by: Darek Stojaczyk Tested-by: SPDK CI Jenkins --- lib/bdev/ocf/volume.c | 18 ++++-------------- lib/bdev/ocf/volume.h | 1 + 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/bdev/ocf/volume.c b/lib/bdev/ocf/volume.c index aa7b15d31..8bc615962 100644 --- a/lib/bdev/ocf/volume.c +++ b/lib/bdev/ocf/volume.c @@ -177,19 +177,8 @@ vbdev_ocf_volume_submit_io_cb(struct spdk_bdev_io *bdev_io, bool success, void * io_ctx->error |= 1; } - if (io_ctx->offset && bdev_io != NULL) { - switch (bdev_io->type) { - case SPDK_BDEV_IO_TYPE_READ: - case SPDK_BDEV_IO_TYPE_WRITE: - env_free(bdev_io->u.bdev.iovs); - break; - case SPDK_BDEV_IO_TYPE_FLUSH: - /* No iovs were allocated for flush request */ - break; - default: - assert(false); - break; - } + if (io_ctx->iovs_allocated && bdev_io != NULL) { + env_free(bdev_io->u.bdev.iovs); } if (io_ctx->error) { @@ -313,7 +302,7 @@ vbdev_ocf_volume_submit_io(struct ocf_io *io) len = io->bytes; offset = io_ctx->offset; - if (offset) { + if (len < io_ctx->data->size) { i = get_starting_vec(io_ctx->data->iovs, io_ctx->data->iovcnt, &offset); if (i < 0) { @@ -324,6 +313,7 @@ vbdev_ocf_volume_submit_io(struct ocf_io *io) iovcnt = io_ctx->data->iovcnt - i; + io_ctx->iovs_allocated = true; iovs = env_malloc(sizeof(*iovs) * iovcnt, ENV_MEM_NOIO); if (!iovs) { diff --git a/lib/bdev/ocf/volume.h b/lib/bdev/ocf/volume.h index 040b11c71..6ae7488b5 100644 --- a/lib/bdev/ocf/volume.h +++ b/lib/bdev/ocf/volume.h @@ -49,6 +49,7 @@ struct ocf_io_ctx { int ref; int rq_cnt; int error; + bool iovs_allocated; }; int vbdev_ocf_volume_init(void);