Blob Blame History Raw
From 84d6e7f976d7a16a9e6d933611e10742a7ff91b1 Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Thu, 4 Feb 2016 10:18:04 +0100
Subject: [PATCH] libceph: fix scatterlist last_piece calculation
References: bsc#963746
Patch-mainline: Not yet, SES2 clustered LIO/RBD

It needs to take into account the initial offset into the sg. Otherwise
the following can occur for an IO that strides an RBD object boundary:
SCSI Write10(lba=4MB-1KB, len=4608)
->rbd_img_req(obj=0, offset=4MB-1KB, len=1KB)
  ->ceph_osd_data_sg_init(init_sg_off=0, len=1024, last_piece=true)
->rbd_img_req(obj=1, offset=0, len=3584)
  ->ceph_osd_data_sg_init(init_sg_off=1024, len=3584, last_piece=true)
								 ^^^^
With last_piece=true, we try to send 3584 bytes from an offset of 1024
into the sg, which exceeds the sg's length (4KB page size).

Signed-off-by: David Disseldorp <ddiss@suse.de>
---
 net/ceph/messenger.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -944,7 +944,10 @@ static void ceph_msg_data_sg_cursor_init
 	cursor->resid = min_t(u64, length, data->sgl_length);
 	cursor->sg = sg;
 	cursor->sg_consumed = data->sgl_init_offset;
-	cursor->last_piece = cursor->resid <= sg->length;
+	if (cursor->resid <= (sg->length - data->sgl_init_offset))
+		cursor->last_piece = true;
+	else
+		cursor->last_piece = false;
 }
 
 static struct page *ceph_msg_data_sg_next(struct ceph_msg_data_cursor *cursor,