From 91c8d27db87ec62ba05374a4045eea60dfa50caa Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 20 Jul 2014 05:59:31 +0000 Subject: [PATCH] iscsi-scst: Handle data buffers with non-zero offset correctly (merge r5683 from trunk) git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.0.x@5687 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/iscsi.c | 7 +++---- iscsi-scst/kernel/nthread.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index bba8976b6..87043aad0 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1542,9 +1542,8 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn, iscsi_extracheck_is_rd_thread(conn); buff_offs = offset; - idx = (offset + sg[0].offset) >> PAGE_SHIFT; - if (offset + sg[0].offset >= PAGE_SIZE) - offset += sg[0].offset; + offset += sg[0].offset; + idx = offset >> PAGE_SHIFT; offset &= ~PAGE_MASK; conn->read_msg.msg_iov = conn->read_iov; @@ -1565,7 +1564,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn, addr = (char __force __user *)(sg_virt(&sg[idx])); EXTRACHECKS_BUG_ON(addr == NULL); - sg_len = sg[idx].length - offset; + sg_len = sg[idx].offset + sg[idx].length - offset; conn->read_iov[i].iov_base = addr + offset; diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index a3b2a127e..9aed7b8c6 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -1396,16 +1396,24 @@ retry: sg_size = size; if (sg != write_cmnd->rsp_sg) { + /* + * Data scatterlist. It is assumed that only the first element + * has a non-zero offset and that all elements except the + * first and the last have a length that is equal to + * PAGE_SIZE. + */ offset = conn->write_offset + sg[0].offset; idx = offset >> PAGE_SHIFT; - if (offset + sg[0].offset >= PAGE_SIZE) - offset += sg[0].offset; offset &= ~PAGE_MASK; length = min(size, (int)PAGE_SIZE - offset); TRACE_WRITE("write_offset %d, sg_size %d, idx %d, offset %d, " "length %d", conn->write_offset, sg_size, idx, offset, length); } else { + /* + * Response scatterlist. No assumptions are made about the + * offset nor about the length of scatterlist elements. + */ idx = 0; offset = conn->write_offset; while (offset >= sg[idx].length) {