static int
ksocknal_recv_iov(struct ksock_conn *conn)
{
- struct kvec *iov = conn->ksnc_rx_iov;
int nob;
int rc;
- LASSERT(conn->ksnc_rx_niov > 0);
-
/*
- * Never touch conn->ksnc_rx_iov or change connection
+ * Never touch conn->ksnc_rx_to or change connection
* status inside ksocknal_lib_recv_iov
*/
rc = ksocknal_lib_recv_iov(conn);
mb(); /* order with setting rx_started */
conn->ksnc_rx_started = 1;
- conn->ksnc_rx_nob_wanted -= nob;
conn->ksnc_rx_nob_left -= nob;
- do {
- LASSERT(conn->ksnc_rx_niov > 0);
-
- if (nob < (int)iov->iov_len) {
- iov->iov_len -= nob;
- iov->iov_base += nob;
- return -EAGAIN;
- }
-
- nob -= iov->iov_len;
- conn->ksnc_rx_iov = ++iov;
- conn->ksnc_rx_niov--;
- } while (nob);
+ iov_iter_advance(&conn->ksnc_rx_to, nob);
+ if (iov_iter_count(&conn->ksnc_rx_to))
+ return -EAGAIN;
return rc;
}
static int
ksocknal_recv_kiov(struct ksock_conn *conn)
{
- struct bio_vec *kiov = conn->ksnc_rx_kiov;
int nob;
int rc;
- LASSERT(conn->ksnc_rx_nkiov > 0);
-
/*
- * Never touch conn->ksnc_rx_kiov or change connection
+ * Never touch conn->ksnc_rx_to or change connection
* status inside ksocknal_lib_recv_iov
*/
rc = ksocknal_lib_recv_kiov(conn);
mb(); /* order with setting rx_started */
conn->ksnc_rx_started = 1;
- conn->ksnc_rx_nob_wanted -= nob;
conn->ksnc_rx_nob_left -= nob;
-
- do {
- LASSERT(conn->ksnc_rx_nkiov > 0);
-
- if (nob < (int)kiov->bv_len) {
- kiov->bv_offset += nob;
- kiov->bv_len -= nob;
- return -EAGAIN;
- }
-
- nob -= kiov->bv_len;
- conn->ksnc_rx_kiov = ++kiov;
- conn->ksnc_rx_nkiov--;
- } while (nob);
+ iov_iter_advance(&conn->ksnc_rx_to, nob);
+ if (iov_iter_count(&conn->ksnc_rx_to))
+ return -EAGAIN;
return 1;
}
{
/*
* Return 1 on success, 0 on EOF, < 0 on error.
- * Caller checks ksnc_rx_nob_wanted to determine
+ * Caller checks ksnc_rx_to to determine
* progress/completion.
*/
int rc;
}
for (;;) {
- if (conn->ksnc_rx_niov)
+ if (conn->ksnc_rx_to.type & ITER_KVEC)
rc = ksocknal_recv_iov(conn);
else
rc = ksocknal_recv_kiov(conn);
/* Completed a fragment */
- if (!conn->ksnc_rx_nob_wanted) {
+ if (!iov_iter_count(&conn->ksnc_rx_to)) {
rc = 1;
break;
}
ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
{
static char ksocknal_slop_buffer[4096];
+ struct kvec *kvec = (struct kvec *)&conn->ksnc_rx_iov_space;
int nob;
unsigned int niov;
case KSOCK_PROTO_V2:
case KSOCK_PROTO_V3:
conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
- conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
- conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg;
-
- conn->ksnc_rx_nob_wanted = offsetof(struct ksock_msg, ksm_u);
+ kvec->iov_base = &conn->ksnc_msg;
+ kvec->iov_len = offsetof(struct ksock_msg, ksm_u);
conn->ksnc_rx_nob_left = offsetof(struct ksock_msg, ksm_u);
- conn->ksnc_rx_iov[0].iov_len = offsetof(struct ksock_msg, ksm_u);
+ iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec,
+ 1, offsetof(struct ksock_msg, ksm_u));
break;
case KSOCK_PROTO_V1:
/* Receiving bare struct lnet_hdr */
conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
- conn->ksnc_rx_nob_wanted = sizeof(struct lnet_hdr);
+ kvec->iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
+ kvec->iov_len = sizeof(struct lnet_hdr);
conn->ksnc_rx_nob_left = sizeof(struct lnet_hdr);
-
- conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
- conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
- conn->ksnc_rx_iov[0].iov_len = sizeof(struct lnet_hdr);
+ iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec,
+ 1, sizeof(struct lnet_hdr));
break;
default:
LBUG();
}
- conn->ksnc_rx_niov = 1;
-
- conn->ksnc_rx_kiov = NULL;
- conn->ksnc_rx_nkiov = 0;
conn->ksnc_rx_csum = ~0;
return 1;
}
*/
conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
conn->ksnc_rx_nob_left = nob_to_skip;
- conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
skipped = 0;
niov = 0;
do {
nob = min_t(int, nob_to_skip, sizeof(ksocknal_slop_buffer));
- conn->ksnc_rx_iov[niov].iov_base = ksocknal_slop_buffer;
- conn->ksnc_rx_iov[niov].iov_len = nob;
+ kvec[niov].iov_base = ksocknal_slop_buffer;
+ kvec[niov].iov_len = nob;
niov++;
skipped += nob;
nob_to_skip -= nob;
} while (nob_to_skip && /* mustn't overflow conn's rx iov */
niov < sizeof(conn->ksnc_rx_iov_space) / sizeof(struct iovec));
- conn->ksnc_rx_niov = niov;
- conn->ksnc_rx_kiov = NULL;
- conn->ksnc_rx_nkiov = 0;
- conn->ksnc_rx_nob_wanted = skipped;
+ iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec, niov, skipped);
return 0;
}
static int
ksocknal_process_receive(struct ksock_conn *conn)
{
+ struct kvec *kvec = (struct kvec *)&conn->ksnc_rx_iov_space;
struct lnet_hdr *lhdr;
struct lnet_process_id *id;
int rc;
conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER ||
conn->ksnc_rx_state == SOCKNAL_RX_SLOP);
again:
- if (conn->ksnc_rx_nob_wanted) {
+ if (iov_iter_count(&conn->ksnc_rx_to)) {
rc = ksocknal_receive(conn);
if (rc <= 0) {
return (!rc ? -ESHUTDOWN : rc);
}
- if (conn->ksnc_rx_nob_wanted) {
+ if (iov_iter_count(&conn->ksnc_rx_to)) {
/* short read */
return -EAGAIN;
}
}
conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
- conn->ksnc_rx_nob_wanted = sizeof(struct ksock_lnet_msg);
conn->ksnc_rx_nob_left = sizeof(struct ksock_lnet_msg);
- conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
- conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
- conn->ksnc_rx_iov[0].iov_len = sizeof(struct ksock_lnet_msg);
+ kvec->iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
+ kvec->iov_len = sizeof(struct ksock_lnet_msg);
- conn->ksnc_rx_niov = 1;
- conn->ksnc_rx_kiov = NULL;
- conn->ksnc_rx_nkiov = 0;
+ iov_iter_kvec(&conn->ksnc_rx_to, READ|ITER_KVEC, kvec,
+ 1, sizeof(struct ksock_lnet_msg));
goto again; /* read lnet header now */
LASSERT(to->nr_segs <= LNET_MAX_IOV);
conn->ksnc_cookie = msg;
- conn->ksnc_rx_nob_wanted = iov_iter_count(to);
conn->ksnc_rx_nob_left = rlen;
- if (to->type & ITER_KVEC) {
- conn->ksnc_rx_nkiov = 0;
- conn->ksnc_rx_kiov = NULL;
- conn->ksnc_rx_iov = conn->ksnc_rx_iov_space.iov;
- conn->ksnc_rx_niov =
- lnet_extract_iov(LNET_MAX_IOV, conn->ksnc_rx_iov,
- to->nr_segs, to->kvec,
- to->iov_offset, iov_iter_count(to));
- } else {
- conn->ksnc_rx_niov = 0;
- conn->ksnc_rx_iov = NULL;
- conn->ksnc_rx_kiov = conn->ksnc_rx_iov_space.kiov;
- conn->ksnc_rx_nkiov =
- lnet_extract_kiov(LNET_MAX_IOV, conn->ksnc_rx_kiov,
- to->nr_segs, to->bvec,
- to->iov_offset, iov_iter_count(to));
- }
+ conn->ksnc_rx_to = *to;
LASSERT(conn->ksnc_rx_scheduled);
conn->ksnc_rx_deadline)) {
/* Timed out incomplete incoming message */
ksocknal_conn_addref(conn);
- CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %d left %d\n",
+ CNETERR("Timeout receiving from %s (%pI4h:%d), state %d wanted %zd left %d\n",
libcfs_id2str(peer->ksnp_id),
&conn->ksnc_ipaddr,
conn->ksnc_port,
conn->ksnc_rx_state,
- conn->ksnc_rx_nob_wanted,
+ iov_iter_count(&conn->ksnc_rx_to),
conn->ksnc_rx_nob_left);
return conn;
}
int
ksocknal_lib_recv_iov(struct ksock_conn *conn)
{
- unsigned int niov = conn->ksnc_rx_niov;
- struct kvec *iov = conn->ksnc_rx_iov;
+ unsigned int niov = conn->ksnc_rx_to.nr_segs;
+ const struct iovec *iov = conn->ksnc_rx_to.iov;
struct msghdr msg = {
.msg_flags = 0
};
- int nob;
int i;
int rc;
int fragnob;
int sum;
__u32 saved_csum;
+ int off = conn->ksnc_rx_to.iov_offset;
- LASSERT(niov > 0);
-
- for (nob = i = 0; i < niov; i++)
- nob += iov[i].iov_len;
-
- LASSERT(nob <= conn->ksnc_rx_nob_wanted);
-
- iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, iov, niov, nob);
+ msg.msg_iter = conn->ksnc_rx_to;
rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);
saved_csum = 0;
for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
LASSERT(i < niov);
- fragnob = iov[i].iov_len;
+ fragnob = iov[i].iov_len - off;
if (fragnob > sum)
fragnob = sum;
conn->ksnc_rx_csum = crc32_le(conn->ksnc_rx_csum,
- iov[i].iov_base,
+ iov[i].iov_base + off,
fragnob);
+ off = 0;
}
conn->ksnc_msg.ksm_csum = saved_csum;
}
int
ksocknal_lib_recv_kiov(struct ksock_conn *conn)
{
- unsigned int niov = conn->ksnc_rx_nkiov;
- struct bio_vec *kiov = conn->ksnc_rx_kiov;
+ unsigned int niov = conn->ksnc_rx_to.nr_segs;
+ const struct bio_vec *kiov = conn->ksnc_rx_to.bvec;
+ int off = conn->ksnc_rx_to.iov_offset;
struct msghdr msg = {
.msg_flags = 0
};
- int nob;
int i;
int rc;
void *base;
int sum;
int fragnob;
- for (nob = i = 0; i < niov; i++)
- nob += kiov[i].bv_len;
-
- LASSERT(nob <= conn->ksnc_rx_nob_wanted);
-
- iov_iter_bvec(&msg.msg_iter, READ | ITER_BVEC, kiov, niov, nob);
+ msg.msg_iter = conn->ksnc_rx_to;
rc = sock_recvmsg(conn->ksnc_sock, &msg, MSG_DONTWAIT);
+ if (rc <= 0)
+ return rc;
if (conn->ksnc_msg.ksm_csum) {
for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
LASSERT(i < niov);
- base = kmap(kiov[i].bv_page) + kiov[i].bv_offset;
- fragnob = kiov[i].bv_len;
+ base = kmap(kiov[i].bv_page) + kiov[i].bv_offset + off;
+ fragnob = kiov[i].bv_len - off;
if (fragnob > sum)
fragnob = sum;
base, fragnob);
kunmap(kiov[i].bv_page);
+ off = 0;
}
}
return rc;