Commit 4038a2a3 authored by Al Viro's avatar Al Viro

Merge branches 'sendmsg.misc' and 'sendmsg.ncpfs' into work.sendmsg

parents 61ff6e9b b8e2df1f
...@@ -40,19 +40,12 @@ static int _recv(struct socket *sock, void *buf, int size, unsigned flags) ...@@ -40,19 +40,12 @@ static int _recv(struct socket *sock, void *buf, int size, unsigned flags)
return kernel_recvmsg(sock, &msg, &iov, 1, size, flags); return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);
} }
static inline int do_send(struct socket *sock, struct kvec *vec, int count,
int len, unsigned flags)
{
struct msghdr msg = { .msg_flags = flags };
return kernel_sendmsg(sock, &msg, vec, count, len);
}
static int _send(struct socket *sock, const void *buff, int len) static int _send(struct socket *sock, const void *buff, int len)
{ {
struct kvec vec; struct msghdr msg = { .msg_flags = 0 };
vec.iov_base = (void *) buff; struct kvec vec = {.iov_base = (void *)buff, .iov_len = len};
vec.iov_len = len; iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &vec, 1, len);
return do_send(sock, &vec, 1, len, 0); return sock_sendmsg(sock, &msg);
} }
struct ncp_request_reply { struct ncp_request_reply {
...@@ -63,9 +56,7 @@ struct ncp_request_reply { ...@@ -63,9 +56,7 @@ struct ncp_request_reply {
size_t datalen; size_t datalen;
int result; int result;
enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status;
struct kvec* tx_ciov; struct iov_iter from;
size_t tx_totallen;
size_t tx_iovlen;
struct kvec tx_iov[3]; struct kvec tx_iov[3];
u_int16_t tx_type; u_int16_t tx_type;
u_int32_t sign[6]; u_int32_t sign[6];
...@@ -205,28 +196,22 @@ static inline void __ncptcp_abort(struct ncp_server *server) ...@@ -205,28 +196,22 @@ static inline void __ncptcp_abort(struct ncp_server *server)
static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req)
{ {
struct kvec vec[3]; struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT };
/* sock_sendmsg updates iov pointers for us :-( */ return sock_sendmsg(sock, &msg);
memcpy(vec, req->tx_ciov, req->tx_iovlen * sizeof(vec[0]));
return do_send(sock, vec, req->tx_iovlen,
req->tx_totallen, MSG_DONTWAIT);
} }
static void __ncptcp_try_send(struct ncp_server *server) static void __ncptcp_try_send(struct ncp_server *server)
{ {
struct ncp_request_reply *rq; struct ncp_request_reply *rq;
struct kvec *iov; struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT };
struct kvec iovc[3];
int result; int result;
rq = server->tx.creq; rq = server->tx.creq;
if (!rq) if (!rq)
return; return;
/* sock_sendmsg updates iov pointers for us :-( */ msg.msg_iter = rq->from;
memcpy(iovc, rq->tx_ciov, rq->tx_iovlen * sizeof(iov[0])); result = sock_sendmsg(server->ncp_sock, &msg);
result = do_send(server->ncp_sock, iovc, rq->tx_iovlen,
rq->tx_totallen, MSG_NOSIGNAL | MSG_DONTWAIT);
if (result == -EAGAIN) if (result == -EAGAIN)
return; return;
...@@ -236,21 +221,12 @@ static void __ncptcp_try_send(struct ncp_server *server) ...@@ -236,21 +221,12 @@ static void __ncptcp_try_send(struct ncp_server *server)
__ncp_abort_request(server, rq, result); __ncp_abort_request(server, rq, result);
return; return;
} }
if (result >= rq->tx_totallen) { if (!msg_data_left(&msg)) {
server->rcv.creq = rq; server->rcv.creq = rq;
server->tx.creq = NULL; server->tx.creq = NULL;
return; return;
} }
rq->tx_totallen -= result; rq->from = msg.msg_iter;
iov = rq->tx_ciov;
while (iov->iov_len <= result) {
result -= iov->iov_len;
iov++;
rq->tx_iovlen--;
}
iov->iov_base += result;
iov->iov_len -= result;
rq->tx_ciov = iov;
} }
static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h)
...@@ -263,22 +239,21 @@ static inline void ncp_init_header(struct ncp_server *server, struct ncp_request ...@@ -263,22 +239,21 @@ static inline void ncp_init_header(struct ncp_server *server, struct ncp_request
static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req) static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req)
{ {
size_t signlen; size_t signlen, len = req->tx_iov[1].iov_len;
struct ncp_request_header* h; struct ncp_request_header *h = req->tx_iov[1].iov_base;
req->tx_ciov = req->tx_iov + 1;
h = req->tx_iov[1].iov_base;
ncp_init_header(server, req, h); ncp_init_header(server, req, h);
signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, signlen = sign_packet(server,
req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
cpu_to_le32(req->tx_totallen), req->sign); len - sizeof(struct ncp_request_header) + 1,
cpu_to_le32(len), req->sign);
if (signlen) { if (signlen) {
req->tx_ciov[1].iov_base = req->sign; /* NCP over UDP appends signature */
req->tx_ciov[1].iov_len = signlen; req->tx_iov[2].iov_base = req->sign;
req->tx_iovlen += 1; req->tx_iov[2].iov_len = signlen;
req->tx_totallen += signlen;
} }
iov_iter_kvec(&req->from, WRITE | ITER_KVEC,
req->tx_iov + 1, signlen ? 2 : 1, len + signlen);
server->rcv.creq = req; server->rcv.creq = req;
server->timeout_last = server->m.time_out; server->timeout_last = server->m.time_out;
server->timeout_retries = server->m.retry_count; server->timeout_retries = server->m.retry_count;
...@@ -292,24 +267,23 @@ static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request ...@@ -292,24 +267,23 @@ static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request
static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req) static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
{ {
size_t signlen; size_t signlen, len = req->tx_iov[1].iov_len;
struct ncp_request_header* h; struct ncp_request_header *h = req->tx_iov[1].iov_base;
req->tx_ciov = req->tx_iov;
h = req->tx_iov[1].iov_base;
ncp_init_header(server, req, h); ncp_init_header(server, req, h);
signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, len - sizeof(struct ncp_request_header) + 1,
cpu_to_be32(req->tx_totallen + 24), req->sign + 4) + 16; cpu_to_be32(len + 24), req->sign + 4) + 16;
req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC);
req->sign[1] = htonl(req->tx_totallen + signlen); req->sign[1] = htonl(len + signlen);
req->sign[2] = htonl(NCP_TCP_XMIT_VERSION); req->sign[2] = htonl(NCP_TCP_XMIT_VERSION);
req->sign[3] = htonl(req->datalen + 8); req->sign[3] = htonl(req->datalen + 8);
/* NCP over TCP prepends signature */
req->tx_iov[0].iov_base = req->sign; req->tx_iov[0].iov_base = req->sign;
req->tx_iov[0].iov_len = signlen; req->tx_iov[0].iov_len = signlen;
req->tx_iovlen += 1; iov_iter_kvec(&req->from, WRITE | ITER_KVEC,
req->tx_totallen += signlen; req->tx_iov, 2, len + signlen);
server->tx.creq = req; server->tx.creq = req;
__ncptcp_try_send(server); __ncptcp_try_send(server);
...@@ -364,18 +338,17 @@ static void __ncp_next_request(struct ncp_server *server) ...@@ -364,18 +338,17 @@ static void __ncp_next_request(struct ncp_server *server)
static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len) static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len)
{ {
if (server->info_sock) { if (server->info_sock) {
struct kvec iov[2]; struct msghdr msg = { .msg_flags = MSG_NOSIGNAL };
__be32 hdr[2]; __be32 hdr[2] = {cpu_to_be32(len + 8), cpu_to_be32(id)};
struct kvec iov[2] = {
hdr[0] = cpu_to_be32(len + 8); {.iov_base = hdr, .iov_len = 8},
hdr[1] = cpu_to_be32(id); {.iov_base = (void *)data, .iov_len = len},
};
iov[0].iov_base = hdr;
iov[0].iov_len = 8; iov_iter_kvec(&msg.msg_iter, ITER_KVEC | WRITE,
iov[1].iov_base = (void *) data; iov, 2, len + 8);
iov[1].iov_len = len;
do_send(server->info_sock, iov, 2, len + 8, MSG_NOSIGNAL); sock_sendmsg(server->info_sock, &msg);
} }
} }
...@@ -711,8 +684,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, ...@@ -711,8 +684,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
req->datalen = max_reply_size; req->datalen = max_reply_size;
req->tx_iov[1].iov_base = server->packet; req->tx_iov[1].iov_base = server->packet;
req->tx_iov[1].iov_len = size; req->tx_iov[1].iov_len = size;
req->tx_iovlen = 1;
req->tx_totallen = size;
req->tx_type = *(u_int16_t*)server->packet; req->tx_type = *(u_int16_t*)server->packet;
result = ncp_add_request(server, req); result = ncp_add_request(server, req);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment