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) {