Re: [PATCH] use rbd_aio_readv/_writev instead of bounce_buffer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 05/06/2017 11:59 PM, David Butterfield wrote:
> This change may need adjustment for local style conventions;
> but it's what I did in my copy to use the rbd iovec functions
> instead of copying through a bounce_buffer.  Note all the extra
> conditional checks are done at compile-time.
> 
> Signed-off-by: David Butterfield <dab21774@xxxxxxxxx>
> ---
>  rbd.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-------------------
>  1 file changed, 49 insertions(+), 19 deletions(-)
> 
> diff --git a/rbd.c b/rbd.c
> index c8019b5..1b80d14 100644
> --- a/rbd.c
> +++ b/rbd.c
> @@ -37,6 +37,17 @@
>  
>  #include <rbd/librbd.h>
>  
> +/* Use  gcc -DCONFIG_TCMU_NO_IOV=0  to enable use of RBD iovec calls */
> +/* Use  gcc -DCONFIG_TCMU_NO_IOV=1  to disable use of RBD iovec calls */
> +#ifndef CONFIG_TCMU_NO_IOV
> +#define CONFIG_TCMU_NO_IOV true    /* default for now is to assume older library */
> +#endif
> +
> +#if CONFIG_TCMU_NO_IOV
> +#define rbd_aio_readv(image, iov, iov_cnt, offset, completion)	-EIO
> +#define rbd_aio_writev(image, iov, iov_cnt, offset, completion)	-EIO
> +#endif
> +

It think we can limit the checks and merge some common code. Here is a
completely untested patch.

diff --git a/rbd.c b/rbd.c
index 40f16ea..a37269b 100644
--- a/rbd.c
+++ b/rbd.c
@@ -61,6 +61,7 @@ struct rbd_aio_cb {
 	struct tcmulib_cmd *tcmulib_cmd;
 
 	int64_t length;
+	bool is_read;
 	char *bounce_buffer;
 };
 
@@ -451,13 +452,13 @@ static void tcmu_rbd_close(struct tcmu_device *dev)
  * allocation errors.
  */
 
-static void rbd_finish_aio_read(rbd_completion_t completion,
+static void tcmu_rbd_finish_aio(rbd_completion_t completion,
 				struct rbd_aio_cb *aio_cb)
 {
 	struct tcmu_device *dev = aio_cb->dev;
-	struct tcmulib_cmd *tcmulib_cmd = aio_cb->tcmulib_cmd;
-	struct iovec *iovec = tcmulib_cmd->iovec;
-	size_t iov_cnt = tcmulib_cmd->iov_cnt;
+	struct tcmulib_cmd *cmd = aio_cb->tcmulib_cmd;
+	struct iovec *iovec = cmd->iovec;
+	size_t iov_cnt = cmd->iov_cnt;
 	int64_t ret;
 	int tcmu_r;
 
@@ -465,29 +466,92 @@ static void rbd_finish_aio_read(rbd_completion_t completion,
 	rbd_aio_release(completion);
 
 	if (ret == -ESHUTDOWN) {
-		tcmu_r = tcmu_set_sense_data(tcmulib_cmd->sense_buf,
+		tcmu_r = tcmu_set_sense_data(cmd->sense_buf,
 					     NOT_READY, ASC_PORT_IN_STANDBY,
 					     NULL);
 	} else if (ret < 0) {
-		tcmu_r = tcmu_set_sense_data(tcmulib_cmd->sense_buf,
-					     MEDIUM_ERROR, ASC_READ_ERROR, NULL);
+		tcmu_r = tcmu_set_sense_data(cmd->sense_buf, MEDIUM_ERROR,
+					     aio_cb->is_read ? ASC_READ_ERROR :
+					     ASC_WRITE_ERROR, NULL);
 	} else {
+		if (aio_cb->is_read && aio_cb->bounce_buffer)
+			tcmu_memcpy_into_iovec(iovec, iov_cnt,
+					       aio_cb->bounce_buffer,
+					       aio_cb->length);
 		tcmu_r = SAM_STAT_GOOD;
-		tcmu_memcpy_into_iovec(iovec, iov_cnt,
-				       aio_cb->bounce_buffer, aio_cb->length);
 	}
 
-	tcmulib_cmd->done(dev, tcmulib_cmd, tcmu_r);
+	cmd->done(dev, cmd, tcmu_r);
 
-	free(aio_cb->bounce_buffer);
+	if (aio_cb->bounce_buffer)
+		free(aio_cb->bounce_buffer);
 	free(aio_cb);
 }
 
-static int tcmu_rbd_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
-			     struct iovec *iov, size_t iov_cnt, size_t length,
-			     off_t offset)
+#ifdef LIBRBD_SUPPORTS_IOVEC
+
+static rbd_image_t tcmu_dev_to_image(struct tcmu_device *dev)
+{
+	struct tcmu_rbd_state *state = tcmu_get_dev_private(dev);
+	return state->image;
+}
+
+#define tcmu_rbd_aio_read(dev, aio_cb, completion, iov, iov_cnt, length, offset)
+	rbd_aio_readv(tcmu_dev_to_image(dev), iov, iov_cnt, offset, completion);
+
+#define tcmu_rbd_aio_write(dev, aio_cb, completion, iov, iov_cnt, length, offset
+	rbd_aio_writev(tcmu_dev_to_image(dev), iov, iov_cnt, offset, completion);
+
+#else
+
+static int tcmu_rbd_aio_read(struct tcmu_device *dev, struct rbd_aio_cb *aio_cb,
+			     rbd_completion_t completion, struct iovec *iov,
+			     size_t iov_cnt, size_t length, off_t offset)
 {
 	struct tcmu_rbd_state *state = tcmu_get_dev_private(dev);
+	int ret;
+
+	aio_cb->bounce_buffer = malloc(length);
+	if (!aio_cb->bounce_buffer) {
+		tcmu_dev_err(dev, "Could not allocate bounce buffer.\n");
+		return -ENOMEM;
+	}
+
+	ret = rbd_aio_read(state->image, offset, length, aio_cb->bounce_buffer,
+			   completion);
+	if (ret < 0)
+		free(aio_cb->bounce_buffer);
+	return ret;
+}
+
+static int tcmu_rbd_aio_write(struct tcmu_device *dev, struct rbd_aio_cb *aio_cb,
+			      rbd_completion_t completion, struct iovec *iov,
+			      size_t iov_cnt, size_t length, off_t offset)
+{
+	struct tcmu_rbd_state *state = tcmu_get_dev_private(dev);
+	int ret;
+
+	aio_cb->bounce_buffer = malloc(length);
+	if (!aio_cb->bounce_buffer) {
+		tcmu_dev_err(dev, "Failed to allocate bounce buffer.\n");
+		return -ENOMEM;;
+	}
+
+	tcmu_memcpy_from_iovec(aio_cb->bounce_buffer, length, iov, iov_cnt);
+
+	ret = rbd_aio_write(state->image, offset,
+			    length, aio_cb->bounce_buffer, completion);
+	if (ret < 0)
+		free(aio_cb->bounce_buffer);
+	return ret;
+}
+
+#endif
+
+static int tcmu_rbd_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
+			 struct iovec *iov, size_t iov_cnt, size_t length,
+			 off_t offset)
+{
 	struct rbd_aio_cb *aio_cb;
 	rbd_completion_t completion;
 	ssize_t ret;
@@ -501,21 +565,15 @@ static int tcmu_rbd_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
 	aio_cb->dev = dev;
 	aio_cb->length = length;
 	aio_cb->tcmulib_cmd = cmd;
+	aio_cb->is_read = 1;
 
-	aio_cb->bounce_buffer = malloc(length);
-	if (!aio_cb->bounce_buffer) {
-		tcmu_dev_err(dev, "Could not allocate bounce buffer.\n");
+	ret = rbd_aio_create_completion(aio_cb, (rbd_callback_t)
+					tcmu_rbd_finish_aio, &completion);
+	if (ret < 0)
 		goto out_free_aio_cb;
-	}
 
-	ret = rbd_aio_create_completion
-		(aio_cb, (rbd_callback_t) rbd_finish_aio_read, &completion);
-	if (ret < 0) {
-		goto out_free_bounce_buffer;
-	}
-
-	ret = rbd_aio_read(state->image, offset, length, aio_cb->bounce_buffer,
-			   completion);
+	ret = tcmu_rbd_aio_read(dev, aio_cb, completion, iov, iov_cnt,
+				length, offset);
 	if (ret < 0) {
 		goto out_remove_tracked_aio;
 	}
@@ -524,51 +582,17 @@ static int tcmu_rbd_read(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
 
 out_remove_tracked_aio:
 	rbd_aio_release(completion);
-out_free_bounce_buffer:
-	free(aio_cb->bounce_buffer);
 out_free_aio_cb:
 	free(aio_cb);
 out:
 	return SAM_STAT_TASK_SET_FULL;
 }
 
-static void rbd_finish_aio_generic(rbd_completion_t completion,
-				   struct rbd_aio_cb *aio_cb)
-{
-	struct tcmu_device *dev = aio_cb->dev;
-	struct tcmulib_cmd *tcmulib_cmd = aio_cb->tcmulib_cmd;
-	int64_t ret;
-	int tcmu_r;
-
-	ret = rbd_aio_get_return_value(completion);
-	rbd_aio_release(completion);
-
-	if (ret == -ESHUTDOWN) {
-		tcmu_r = tcmu_set_sense_data(tcmulib_cmd->sense_buf,
-					     NOT_READY, ASC_PORT_IN_STANDBY,
-					     NULL);
-	} else if (ret < 0) {
-		tcmu_r = tcmu_set_sense_data(tcmulib_cmd->sense_buf,
-					     MEDIUM_ERROR, ASC_WRITE_ERROR,
-					     NULL);
-	} else {
-		tcmu_r = SAM_STAT_GOOD;
-	}
-
-	tcmulib_cmd->done(dev, tcmulib_cmd, tcmu_r);
-
-	if (aio_cb->bounce_buffer) {
-		free(aio_cb->bounce_buffer);
-	}
-	free(aio_cb);
-}
-
 static int tcmu_rbd_write(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
 			  struct iovec *iov, size_t iov_cnt, size_t length,
 			  off_t offset)
 {
 
-	struct tcmu_rbd_state *state = tcmu_get_dev_private(dev);
 	struct rbd_aio_cb *aio_cb;
 	rbd_completion_t completion;
 	ssize_t ret;
@@ -583,22 +607,14 @@ static int tcmu_rbd_write(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
 	aio_cb->length = length;
 	aio_cb->tcmulib_cmd = cmd;
 
-	aio_cb->bounce_buffer = malloc(length);
-	if (!aio_cb->bounce_buffer) {
-		tcmu_dev_err(dev, "Failed to allocate bounce buffer.\n");
-		goto out_free_aio_cb;
-	}
-
-	tcmu_memcpy_from_iovec(aio_cb->bounce_buffer, length, iov, iov_cnt);
-
-	ret = rbd_aio_create_completion
-		(aio_cb, (rbd_callback_t) rbd_finish_aio_generic, &completion);
+	ret = rbd_aio_create_completion(aio_cb, (rbd_callback_t)
+					tcmu_rbd_finish_aio, &completion);
 	if (ret < 0) {
-		goto out_free_bounce_buffer;
+		goto out_free_aio_cb;
 	}
 
-	ret = rbd_aio_write(state->image, offset,
-			    length, aio_cb->bounce_buffer, completion);
+	ret = tcmu_rbd_aio_write(dev, aio_cb, completion, iov, iov_cnt,
+				 length, offset);
 	if (ret < 0) {
 		goto out_remove_tracked_aio;
 	}
@@ -607,8 +623,6 @@ static int tcmu_rbd_write(struct tcmu_device *dev, struct tcmulib_cmd *cmd,
 
 out_remove_tracked_aio:
 	rbd_aio_release(completion);
-out_free_bounce_buffer:
-	free(aio_cb->bounce_buffer);
 out_free_aio_cb:
 	free(aio_cb);
 out:
@@ -632,8 +646,8 @@ static int tcmu_rbd_flush(struct tcmu_device *dev, struct tcmulib_cmd *cmd)
 	aio_cb->tcmulib_cmd = cmd;
 	aio_cb->bounce_buffer = NULL;
 
-	ret = rbd_aio_create_completion
-		(aio_cb, (rbd_callback_t) rbd_finish_aio_generic, &completion);
+	ret = rbd_aio_create_completion(aio_cb, (rbd_callback_t)
+					tcmu_rbd_finish_aio, &completion);
 	if (ret < 0) {
 		goto out_free_aio_cb;
 	}

[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux