aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ncpfs/sock.c111
1 files changed, 41 insertions, 70 deletions
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index f32f272ee501..f013c92bb5d8 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -40,19 +40,12 @@ static int _recv(struct socket *sock, void *buf, int size, unsigned flags)
40 return kernel_recvmsg(sock, &msg, &iov, 1, size, flags); 40 return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);
41} 41}
42 42
43static inline int do_send(struct socket *sock, struct kvec *vec, int count,
44 int len, unsigned flags)
45{
46 struct msghdr msg = { .msg_flags = flags };
47 return kernel_sendmsg(sock, &msg, vec, count, len);
48}
49
50static int _send(struct socket *sock, const void *buff, int len) 43static int _send(struct socket *sock, const void *buff, int len)
51{ 44{
52 struct kvec vec; 45 struct msghdr msg = { .msg_flags = 0 };
53 vec.iov_base = (void *) buff; 46 struct kvec vec = {.iov_base = (void *)buff, .iov_len = len};
54 vec.iov_len = len; 47 iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &vec, 1, len);
55 return do_send(sock, &vec, 1, len, 0); 48 return sock_sendmsg(sock, &msg);
56} 49}
57 50
58struct ncp_request_reply { 51struct ncp_request_reply {
@@ -63,9 +56,7 @@ struct ncp_request_reply {
63 size_t datalen; 56 size_t datalen;
64 int result; 57 int result;
65 enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; 58 enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status;
66 struct kvec* tx_ciov; 59 struct iov_iter from;
67 size_t tx_totallen;
68 size_t tx_iovlen;
69 struct kvec tx_iov[3]; 60 struct kvec tx_iov[3];
70 u_int16_t tx_type; 61 u_int16_t tx_type;
71 u_int32_t sign[6]; 62 u_int32_t sign[6];
@@ -205,28 +196,22 @@ static inline void __ncptcp_abort(struct ncp_server *server)
205 196
206static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) 197static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req)
207{ 198{
208 struct kvec vec[3]; 199 struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT };
209 /* sock_sendmsg updates iov pointers for us :-( */ 200 return sock_sendmsg(sock, &msg);
210 memcpy(vec, req->tx_ciov, req->tx_iovlen * sizeof(vec[0]));
211 return do_send(sock, vec, req->tx_iovlen,
212 req->tx_totallen, MSG_DONTWAIT);
213} 201}
214 202
215static void __ncptcp_try_send(struct ncp_server *server) 203static void __ncptcp_try_send(struct ncp_server *server)
216{ 204{
217 struct ncp_request_reply *rq; 205 struct ncp_request_reply *rq;
218 struct kvec *iov; 206 struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT };
219 struct kvec iovc[3];
220 int result; 207 int result;
221 208
222 rq = server->tx.creq; 209 rq = server->tx.creq;
223 if (!rq) 210 if (!rq)
224 return; 211 return;
225 212
226 /* sock_sendmsg updates iov pointers for us :-( */ 213 msg.msg_iter = rq->from;
227 memcpy(iovc, rq->tx_ciov, rq->tx_iovlen * sizeof(iov[0])); 214 result = sock_sendmsg(server->ncp_sock, &msg);
228 result = do_send(server->ncp_sock, iovc, rq->tx_iovlen,
229 rq->tx_totallen, MSG_NOSIGNAL | MSG_DONTWAIT);
230 215
231 if (result == -EAGAIN) 216 if (result == -EAGAIN)
232 return; 217 return;
@@ -236,21 +221,12 @@ static void __ncptcp_try_send(struct ncp_server *server)
236 __ncp_abort_request(server, rq, result); 221 __ncp_abort_request(server, rq, result);
237 return; 222 return;
238 } 223 }
239 if (result >= rq->tx_totallen) { 224 if (!msg_data_left(&msg)) {
240 server->rcv.creq = rq; 225 server->rcv.creq = rq;
241 server->tx.creq = NULL; 226 server->tx.creq = NULL;
242 return; 227 return;
243 } 228 }
244 rq->tx_totallen -= result; 229 rq->from = msg.msg_iter;
245 iov = rq->tx_ciov;
246 while (iov->iov_len <= result) {
247 result -= iov->iov_len;
248 iov++;
249 rq->tx_iovlen--;
250 }
251 iov->iov_base += result;
252 iov->iov_len -= result;
253 rq->tx_ciov = iov;
254} 230}
255 231
256static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) 232static 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 239
264static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req) 240static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req)
265{ 241{
266 size_t signlen; 242 size_t signlen, len = req->tx_iov[1].iov_len;
267 struct ncp_request_header* h; 243 struct ncp_request_header *h = req->tx_iov[1].iov_base;
268 244
269 req->tx_ciov = req->tx_iov + 1;
270
271 h = req->tx_iov[1].iov_base;
272 ncp_init_header(server, req, h); 245 ncp_init_header(server, req, h);
273 signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, 246 signlen = sign_packet(server,
274 req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, 247 req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
275 cpu_to_le32(req->tx_totallen), req->sign); 248 len - sizeof(struct ncp_request_header) + 1,
249 cpu_to_le32(len), req->sign);
276 if (signlen) { 250 if (signlen) {
277 req->tx_ciov[1].iov_base = req->sign; 251 /* NCP over UDP appends signature */
278 req->tx_ciov[1].iov_len = signlen; 252 req->tx_iov[2].iov_base = req->sign;
279 req->tx_iovlen += 1; 253 req->tx_iov[2].iov_len = signlen;
280 req->tx_totallen += signlen;
281 } 254 }
255 iov_iter_kvec(&req->from, WRITE | ITER_KVEC,
256 req->tx_iov + 1, signlen ? 2 : 1, len + signlen);
282 server->rcv.creq = req; 257 server->rcv.creq = req;
283 server->timeout_last = server->m.time_out; 258 server->timeout_last = server->m.time_out;
284 server->timeout_retries = server->m.retry_count; 259 server->timeout_retries = server->m.retry_count;
@@ -292,24 +267,23 @@ static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request
292 267
293static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req) 268static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
294{ 269{
295 size_t signlen; 270 size_t signlen, len = req->tx_iov[1].iov_len;
296 struct ncp_request_header* h; 271 struct ncp_request_header *h = req->tx_iov[1].iov_base;
297 272
298 req->tx_ciov = req->tx_iov;
299 h = req->tx_iov[1].iov_base;
300 ncp_init_header(server, req, h); 273 ncp_init_header(server, req, h);
301 signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, 274 signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
302 req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, 275 len - sizeof(struct ncp_request_header) + 1,
303 cpu_to_be32(req->tx_totallen + 24), req->sign + 4) + 16; 276 cpu_to_be32(len + 24), req->sign + 4) + 16;
304 277
305 req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); 278 req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC);
306 req->sign[1] = htonl(req->tx_totallen + signlen); 279 req->sign[1] = htonl(len + signlen);
307 req->sign[2] = htonl(NCP_TCP_XMIT_VERSION); 280 req->sign[2] = htonl(NCP_TCP_XMIT_VERSION);
308 req->sign[3] = htonl(req->datalen + 8); 281 req->sign[3] = htonl(req->datalen + 8);
282 /* NCP over TCP prepends signature */
309 req->tx_iov[0].iov_base = req->sign; 283 req->tx_iov[0].iov_base = req->sign;
310 req->tx_iov[0].iov_len = signlen; 284 req->tx_iov[0].iov_len = signlen;
311 req->tx_iovlen += 1; 285 iov_iter_kvec(&req->from, WRITE | ITER_KVEC,
312 req->tx_totallen += signlen; 286 req->tx_iov, 2, len + signlen);
313 287
314 server->tx.creq = req; 288 server->tx.creq = req;
315 __ncptcp_try_send(server); 289 __ncptcp_try_send(server);
@@ -364,18 +338,17 @@ static void __ncp_next_request(struct ncp_server *server)
364static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len) 338static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len)
365{ 339{
366 if (server->info_sock) { 340 if (server->info_sock) {
367 struct kvec iov[2]; 341 struct msghdr msg = { .msg_flags = MSG_NOSIGNAL };
368 __be32 hdr[2]; 342 __be32 hdr[2] = {cpu_to_be32(len + 8), cpu_to_be32(id)};
369 343 struct kvec iov[2] = {
370 hdr[0] = cpu_to_be32(len + 8); 344 {.iov_base = hdr, .iov_len = 8},
371 hdr[1] = cpu_to_be32(id); 345 {.iov_base = (void *)data, .iov_len = len},
372 346 };
373 iov[0].iov_base = hdr; 347
374 iov[0].iov_len = 8; 348 iov_iter_kvec(&msg.msg_iter, ITER_KVEC | WRITE,
375 iov[1].iov_base = (void *) data; 349 iov, 2, len + 8);
376 iov[1].iov_len = len;
377 350
378 do_send(server->info_sock, iov, 2, len + 8, MSG_NOSIGNAL); 351 sock_sendmsg(server->info_sock, &msg);
379 } 352 }
380} 353}
381 354
@@ -711,8 +684,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
711 req->datalen = max_reply_size; 684 req->datalen = max_reply_size;
712 req->tx_iov[1].iov_base = server->packet; 685 req->tx_iov[1].iov_base = server->packet;
713 req->tx_iov[1].iov_len = size; 686 req->tx_iov[1].iov_len = size;
714 req->tx_iovlen = 1;
715 req->tx_totallen = size;
716 req->tx_type = *(u_int16_t*)server->packet; 687 req->tx_type = *(u_int16_t*)server->packet;
717 688
718 result = ncp_add_request(server, req); 689 result = ncp_add_request(server, req);