iscsi-scst: Update for kernel 3.19 (merge r6187 from the trunk)

git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.0.x@6282 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2015-06-11 16:59:15 +00:00
parent af4e8f8aaa
commit 46ada09547
4 changed files with 92 additions and 53 deletions

View File

@@ -932,7 +932,7 @@ int iscsi_conn_alloc(struct iscsi_session *session,
conn->transport = t;
/* Changing it, change ISCSI_CONN_IOV_MAX as well !! */
conn->read_iov = (struct iovec *)get_zeroed_page(GFP_KERNEL);
conn->read_iov = (void *)get_zeroed_page(GFP_KERNEL);
if (conn->read_iov == NULL) {
res = -ENOMEM;
goto out_err_free_conn;

View File

@@ -1451,7 +1451,7 @@ static void cmnd_prepare_get_rejected_immed_data(struct iscsi_cmnd *cmnd)
struct iscsi_conn *conn = cmnd->conn;
struct scatterlist *sg = cmnd->sg;
char *addr;
u32 size;
u32 size, s, e;
unsigned int i;
TRACE_ENTRY();
@@ -1485,17 +1485,21 @@ static void cmnd_prepare_get_rejected_immed_data(struct iscsi_cmnd *cmnd)
}
addr = page_address(sg_page(&sg[0]));
conn->read_size = size;
for (i = 0; size > PAGE_SIZE; i++, size -= PAGE_SIZE) {
for (s = size, i = 0; s > 0; i++, s -= e) {
/* We already checked pdu.datasize in check_segment_length() */
sBUG_ON(i >= ISCSI_CONN_IOV_MAX);
conn->read_iov[i].iov_base = (void __force __user *)addr;
conn->read_iov[i].iov_len = PAGE_SIZE;
conn->read_iov[i].iov_base = addr;
e = min_t(u32, s, PAGE_SIZE);
conn->read_iov[i].iov_len = e;
}
conn->read_iov[i].iov_base = (void __force __user *)addr;
conn->read_iov[i].iov_len = size;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, i, size);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = ++i;
conn->read_msg.msg_iovlen = i;
conn->read_size = size;
#endif
out:
TRACE_EXIT();
@@ -1576,6 +1580,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
struct scatterlist *sg = cmd->sg;
unsigned int bufflen = cmd->bufflen;
unsigned int idx, i, buff_offs;
const u32 read_size = size;
int res = 0;
TRACE_ENTRY();
@@ -1590,9 +1595,6 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
idx = offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
conn->read_msg.msg_iov = conn->read_iov;
conn->read_size = size;
i = 0;
while (1) {
unsigned int sg_len;
@@ -1610,13 +1612,12 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
EXTRACHECKS_BUG_ON(addr == NULL);
sg_len = sg[idx].offset + sg[idx].length - offset;
conn->read_iov[i].iov_base = (void __force __user *)addr + offset;
conn->read_iov[i].iov_base = addr + offset;
if (size <= sg_len) {
TRACE_DBG("idx=%d, i=%d, offset=%u, size=%d, addr=%p",
idx, i, offset, size, addr);
conn->read_iov[i].iov_len = size;
conn->read_msg.msg_iovlen = i+1;
break;
}
conn->read_iov[i].iov_len = sg_len;
@@ -1635,16 +1636,26 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
size);
mark_conn_closed(conn);
res = -EINVAL;
break;
goto out;
}
idx++;
offset = 0;
}
TRACE_DBG("msg_iov=%p, msg_iovlen=%zd",
conn->read_msg.msg_iov, conn->read_msg.msg_iovlen);
i++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, i, read_size);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = i;
conn->read_size = read_size;
#endif
TRACE_DBG("msg_iov=%p, msg_iovlen=%u", conn->read_iov, i);
out:
TRACE_EXIT_RES(res);
return res;
}
@@ -1784,7 +1795,6 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
size = cmnd->pdu.datasize;
if (size && !conn->session->sess_params.rdma_extensions) {
conn->read_msg.msg_iov = conn->read_iov;
if (cmnd->pdu.bhs.itt != ISCSI_RESERVED_TAG) {
struct scatterlist *sg;
@@ -1805,10 +1815,9 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
for (i = 0; i < cmnd->sg_cnt; i++) {
conn->read_iov[i].iov_base =
(void __force __user *)(page_address(sg_page(&sg[i])));
page_address(sg_page(&sg[i]));
tmp = min_t(u32, size, PAGE_SIZE);
conn->read_iov[i].iov_len = tmp;
conn->read_size += tmp;
size -= tmp;
}
sBUG_ON(size != 0);
@@ -1820,10 +1829,9 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
*/
for (i = 0; i < (signed)ISCSI_CONN_IOV_MAX; i++) {
conn->read_iov[i].iov_base =
(void __force __user *)(page_address(dummy_page));
page_address(dummy_page);
tmp = min_t(u32, size, PAGE_SIZE);
conn->read_iov[i].iov_len = tmp;
conn->read_size += tmp;
size -= tmp;
}
@@ -1831,9 +1839,15 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
sBUG_ON(size != 0);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, i, cmnd->pdu.datasize);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = i;
TRACE_DBG("msg_iov=%p, msg_iovlen=%zd", conn->read_msg.msg_iov,
conn->read_msg.msg_iovlen);
conn->read_size = cmnd->pdu.datasize;
#endif
TRACE_DBG("msg_iov=%p, msg_iovlen=%d", conn->read_iov, i);
}
out:

View File

@@ -289,9 +289,13 @@ struct iscsi_conn {
*/
struct iscsi_cmnd *read_cmnd;
struct msghdr read_msg;
u32 read_size;
int read_state;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
struct kvec *read_iov;
#else
u32 read_size;
struct iovec *read_iov;
#endif
struct task_struct *rx_task;
uint32_t rpadding;

View File

@@ -618,11 +618,16 @@ EXPORT_SYMBOL(start_close_conn);
static inline void iscsi_conn_init_read(struct iscsi_conn *conn,
void *data, size_t len)
{
conn->read_iov[0].iov_base = (void __force __user *)data;
conn->read_iov[0].iov_base = data;
conn->read_iov[0].iov_len = len;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
iov_iter_kvec(&conn->read_msg.msg_iter, READ | ITER_KVEC,
conn->read_iov, 1, len);
#else
conn->read_msg.msg_iov = conn->read_iov;
conn->read_msg.msg_iovlen = 1;
conn->read_size = len;
#endif
return;
}
@@ -684,8 +689,12 @@ static int do_recv(struct iscsi_conn *conn)
{
int res;
mm_segment_t oldfs;
struct msghdr msg;
struct msghdr *msg;
int read_size;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
struct iovec *first_iov;
int first_len;
#endif
EXTRACHECKS_BUG_ON(conn->read_cmnd == NULL);
@@ -701,45 +710,48 @@ static int do_recv(struct iscsi_conn *conn)
*/
restart:
memset(&msg, 0, sizeof(msg));
msg.msg_iov = conn->read_msg.msg_iov;
msg.msg_iovlen = conn->read_msg.msg_iovlen;
first_len = msg.msg_iov->iov_len;
msg = &conn->read_msg;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
read_size = msg->msg_iter.count;
#else
read_size = conn->read_size;
first_iov = msg->msg_iov;
first_len = first_iov->iov_len;
#endif
oldfs = get_fs();
set_fs(get_ds());
res = sock_recvmsg(conn->sock, &msg, conn->read_size,
res = sock_recvmsg(conn->sock, msg, read_size,
MSG_DONTWAIT | MSG_NOSIGNAL);
set_fs(oldfs);
TRACE_DBG("msg_iovlen %zd, first_len %d, read_size %d, res %d",
msg.msg_iovlen, first_len, conn->read_size, res);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
TRACE_DBG("nr_segs %zd, bytes_left %zd, res %d",
msg->msg_iter.nr_segs, msg->msg_iter.count, res);
#else
TRACE_DBG("msg_iovlen %zd, read_size %d, res %d", msg->msg_iovlen,
read_size, res);
#endif
if (res > 0) {
/*
* To save some considerable effort and CPU power we
* suppose that TCP functions adjust
* conn->read_msg.msg_iov and conn->read_msg.msg_iovlen
* on amount of copied data. This BUG_ON is intended
* to catch if it is changed in the future.
* To save CPU cycles we suppose that sock_recvmsg() adjusts
* msg->msg_iov and msg->msg_iovlen. The BUG_ON() statements
* below verifies this.
*/
sBUG_ON((res >= first_len) &&
(conn->read_msg.msg_iov->iov_len != 0));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
sBUG_ON(msg->msg_iter.count + res != read_size);
res = msg->msg_iter.count;
#else
sBUG_ON((res >= first_len) && (first_iov->iov_len != 0));
conn->read_size -= res;
if (conn->read_size != 0) {
if (res >= first_len) {
int done = 1 + ((res - first_len) >> PAGE_SHIFT);
TRACE_DBG("done %d", done);
conn->read_msg.msg_iov += done;
conn->read_msg.msg_iovlen -= done;
}
}
res = conn->read_size;
#endif
} else {
switch (res) {
case -EAGAIN:
TRACE_DBG("EAGAIN received for conn %p", conn);
res = conn->read_size;
res = read_size;
break;
case -ERESTARTSYS:
TRACE_DBG("ERESTARTSYS received for conn %p", conn);
@@ -825,7 +837,7 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn)
static int process_read_io(struct iscsi_conn *conn, int *closed)
{
struct iscsi_cmnd *cmnd = conn->read_cmnd;
int res;
int bytes_left, res;
TRACE_ENTRY();
@@ -913,10 +925,15 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
break;
case RX_END:
if (unlikely(conn->read_size != 0)) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
bytes_left = conn->read_msg.msg_iter.count;
#else
bytes_left = conn->read_size;
#endif
if (unlikely(bytes_left != 0)) {
PRINT_CRIT_ERROR("conn read_size !=0 on RX_END "
"(conn %p, op %x, read_size %d)", conn,
cmnd_opcode(cmnd), conn->read_size);
cmnd_opcode(cmnd), bytes_left);
sBUG();
}
conn->read_cmnd = NULL;
@@ -924,7 +941,11 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
cmnd_rx_end(cmnd);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
EXTRACHECKS_BUG_ON(conn->read_msg.msg_iter.count != 0);
#else
EXTRACHECKS_BUG_ON(conn->read_size != 0);
#endif
/*
* To maintain fairness. Res must be 0 here anyway, the