diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index e8e690fbb..2a0c31596 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -895,7 +895,7 @@ static int iscsi_conn_alloc(struct iscsi_session *session, (unsigned long long int)session->sid, info->cid); /* 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; diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index f73608b02..d6e075f98 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1444,13 +1444,18 @@ static void cmnd_prepare_get_rejected_immed_data(struct iscsi_cmnd *cmnd) 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_base = addr; e = min_t(u32, s, PAGE_SIZE); conn->read_iov[i].iov_len = e; } +#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_size = size; +#endif out: TRACE_EXIT(); @@ -1595,9 +1600,14 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn, } 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); @@ -1761,7 +1771,7 @@ 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; size -= tmp; @@ -1775,7 +1785,7 @@ 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; size -= tmp; @@ -1785,9 +1795,14 @@ 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; conn->read_size = cmnd->pdu.datasize; +#endif TRACE_DBG("msg_iov=%p, msg_iovlen=%d", conn->read_iov, i); } diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index 47b474502..7f29fb8cd 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -285,9 +285,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; diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index ff08181d6..26412069f 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -615,11 +615,16 @@ static void start_close_conn(struct iscsi_conn *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; } @@ -698,7 +703,11 @@ static int do_recv(struct iscsi_conn *conn) restart: 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; +#endif oldfs = get_fs(); set_fs(get_ds()); @@ -706,8 +715,13 @@ restart: MSG_DONTWAIT | MSG_NOSIGNAL); set_fs(oldfs); +#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) { /* @@ -715,9 +729,14 @@ restart: * msg->msg_iov and msg->msg_iovlen. The BUG_ON() statement * below verifies this. */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) + sBUG_ON(msg->msg_iter.count + res != read_size); + res = msg->msg_iter.count; +#else /* To do: restore msg->msg_iov check. */ conn->read_size -= res; res = conn->read_size; +#endif } else { switch (res) { case -EAGAIN: @@ -896,7 +915,11 @@ static int process_read_io(struct iscsi_conn *conn, int *closed) break; case RX_END: +#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, @@ -908,7 +931,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