diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index d2120f772..2a4020b79 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1536,7 +1536,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; + offset += sg[0].offset; + idx = offset >> PAGE_SHIFT; offset &= ~PAGE_MASK; conn->read_msg.msg_iov = conn->read_iov; @@ -1557,7 +1558,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 ece666295..1bc295e1a 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -1412,6 +1412,12 @@ 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; offset &= ~PAGE_MASK; @@ -1420,6 +1426,10 @@ retry: "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) {