diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2016-01-09 22:01:58 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-12-26 21:37:38 -0500 |
| commit | 2cebcc78fab5f56c9a9795fc49546d2436491312 (patch) | |
| tree | ab3ecb0bfb707ed84adf31b1be16d4781a2df2a9 /fs/ncpfs | |
| parent | 4b4fbad37f70f1dca26e060cf8dc71371b01899c (diff) | |
ncpfs: don't mess with manually advancing iovec on send
just keep iov_iter in req
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ncpfs')
| -rw-r--r-- | fs/ncpfs/sock.c | 69 |
1 files changed, 27 insertions, 42 deletions
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 97cfccefccc5..a13c0b54f078 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c | |||
| @@ -63,9 +63,7 @@ struct ncp_request_reply { | |||
| 63 | size_t datalen; | 63 | size_t datalen; |
| 64 | int result; | 64 | int result; |
| 65 | enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; | 65 | enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; |
| 66 | struct kvec* tx_ciov; | 66 | struct iov_iter from; |
| 67 | size_t tx_totallen; | ||
| 68 | size_t tx_iovlen; | ||
| 69 | struct kvec tx_iov[3]; | 67 | struct kvec tx_iov[3]; |
| 70 | u_int16_t tx_type; | 68 | u_int16_t tx_type; |
| 71 | u_int32_t sign[6]; | 69 | u_int32_t sign[6]; |
| @@ -205,22 +203,22 @@ static inline void __ncptcp_abort(struct ncp_server *server) | |||
| 205 | 203 | ||
| 206 | static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) | 204 | static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) |
| 207 | { | 205 | { |
| 208 | return do_send(sock, req->tx_ciov, req->tx_iovlen, | 206 | struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT }; |
| 209 | req->tx_totallen, MSG_DONTWAIT); | 207 | return sock_sendmsg(sock, &msg); |
| 210 | } | 208 | } |
| 211 | 209 | ||
| 212 | static void __ncptcp_try_send(struct ncp_server *server) | 210 | static void __ncptcp_try_send(struct ncp_server *server) |
| 213 | { | 211 | { |
| 214 | struct ncp_request_reply *rq; | 212 | struct ncp_request_reply *rq; |
| 215 | struct kvec *iov; | 213 | struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT }; |
| 216 | int result; | 214 | int result; |
| 217 | 215 | ||
| 218 | rq = server->tx.creq; | 216 | rq = server->tx.creq; |
| 219 | if (!rq) | 217 | if (!rq) |
| 220 | return; | 218 | return; |
| 221 | 219 | ||
| 222 | result = do_send(server->ncp_sock, rq->tx_ciov, rq->tx_iovlen, | 220 | msg.msg_iter = rq->from; |
| 223 | rq->tx_totallen, MSG_NOSIGNAL | MSG_DONTWAIT); | 221 | result = sock_sendmsg(server->ncp_sock, &msg); |
| 224 | 222 | ||
| 225 | if (result == -EAGAIN) | 223 | if (result == -EAGAIN) |
| 226 | return; | 224 | return; |
| @@ -230,21 +228,12 @@ static void __ncptcp_try_send(struct ncp_server *server) | |||
| 230 | __ncp_abort_request(server, rq, result); | 228 | __ncp_abort_request(server, rq, result); |
| 231 | return; | 229 | return; |
| 232 | } | 230 | } |
| 233 | if (result >= rq->tx_totallen) { | 231 | if (!msg_data_left(&msg)) { |
| 234 | server->rcv.creq = rq; | 232 | server->rcv.creq = rq; |
| 235 | server->tx.creq = NULL; | 233 | server->tx.creq = NULL; |
| 236 | return; | 234 | return; |
| 237 | } | 235 | } |
| 238 | rq->tx_totallen -= result; | 236 | rq->from = msg.msg_iter; |
| 239 | iov = rq->tx_ciov; | ||
| 240 | while (iov->iov_len <= result) { | ||
| 241 | result -= iov->iov_len; | ||
| 242 | iov++; | ||
| 243 | rq->tx_iovlen--; | ||
| 244 | } | ||
| 245 | iov->iov_base += result; | ||
| 246 | iov->iov_len -= result; | ||
| 247 | rq->tx_ciov = iov; | ||
| 248 | } | 237 | } |
| 249 | 238 | ||
| 250 | static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) | 239 | static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) |
| @@ -257,22 +246,21 @@ static inline void ncp_init_header(struct ncp_server *server, struct ncp_request | |||
| 257 | 246 | ||
| 258 | static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req) | 247 | static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req) |
| 259 | { | 248 | { |
| 260 | size_t signlen; | 249 | size_t signlen, len = req->tx_iov[1].iov_len; |
| 261 | struct ncp_request_header* h; | 250 | struct ncp_request_header *h = req->tx_iov[1].iov_base; |
| 262 | 251 | ||
| 263 | req->tx_ciov = req->tx_iov + 1; | ||
| 264 | |||
| 265 | h = req->tx_iov[1].iov_base; | ||
| 266 | ncp_init_header(server, req, h); | 252 | ncp_init_header(server, req, h); |
| 267 | signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, | 253 | signlen = sign_packet(server, |
| 268 | req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, | 254 | req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, |
| 269 | cpu_to_le32(req->tx_totallen), req->sign); | 255 | len - sizeof(struct ncp_request_header) + 1, |
| 256 | cpu_to_le32(len), req->sign); | ||
| 270 | if (signlen) { | 257 | if (signlen) { |
| 271 | req->tx_ciov[1].iov_base = req->sign; | 258 | /* NCP over UDP appends signature */ |
| 272 | req->tx_ciov[1].iov_len = signlen; | 259 | req->tx_iov[2].iov_base = req->sign; |
| 273 | req->tx_iovlen += 1; | 260 | req->tx_iov[2].iov_len = signlen; |
| 274 | req->tx_totallen += signlen; | ||
| 275 | } | 261 | } |
| 262 | iov_iter_kvec(&req->from, WRITE | ITER_KVEC, | ||
| 263 | req->tx_iov + 1, signlen ? 2 : 1, len + signlen); | ||
| 276 | server->rcv.creq = req; | 264 | server->rcv.creq = req; |
| 277 | server->timeout_last = server->m.time_out; | 265 | server->timeout_last = server->m.time_out; |
| 278 | server->timeout_retries = server->m.retry_count; | 266 | server->timeout_retries = server->m.retry_count; |
| @@ -286,24 +274,23 @@ static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request | |||
| 286 | 274 | ||
| 287 | static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req) | 275 | static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req) |
| 288 | { | 276 | { |
| 289 | size_t signlen; | 277 | size_t signlen, len = req->tx_iov[1].iov_len; |
| 290 | struct ncp_request_header* h; | 278 | struct ncp_request_header *h = req->tx_iov[1].iov_base; |
| 291 | 279 | ||
| 292 | req->tx_ciov = req->tx_iov; | ||
| 293 | h = req->tx_iov[1].iov_base; | ||
| 294 | ncp_init_header(server, req, h); | 280 | ncp_init_header(server, req, h); |
| 295 | signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, | 281 | signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, |
| 296 | req->tx_iov[1].iov_len - sizeof(struct ncp_request_header) + 1, | 282 | len - sizeof(struct ncp_request_header) + 1, |
| 297 | cpu_to_be32(req->tx_totallen + 24), req->sign + 4) + 16; | 283 | cpu_to_be32(len + 24), req->sign + 4) + 16; |
| 298 | 284 | ||
| 299 | req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); | 285 | req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); |
| 300 | req->sign[1] = htonl(req->tx_totallen + signlen); | 286 | req->sign[1] = htonl(len + signlen); |
| 301 | req->sign[2] = htonl(NCP_TCP_XMIT_VERSION); | 287 | req->sign[2] = htonl(NCP_TCP_XMIT_VERSION); |
| 302 | req->sign[3] = htonl(req->datalen + 8); | 288 | req->sign[3] = htonl(req->datalen + 8); |
| 289 | /* NCP over TCP prepends signature */ | ||
| 303 | req->tx_iov[0].iov_base = req->sign; | 290 | req->tx_iov[0].iov_base = req->sign; |
| 304 | req->tx_iov[0].iov_len = signlen; | 291 | req->tx_iov[0].iov_len = signlen; |
| 305 | req->tx_iovlen += 1; | 292 | iov_iter_kvec(&req->from, WRITE | ITER_KVEC, |
| 306 | req->tx_totallen += signlen; | 293 | req->tx_iov, 2, len + signlen); |
| 307 | 294 | ||
| 308 | server->tx.creq = req; | 295 | server->tx.creq = req; |
| 309 | __ncptcp_try_send(server); | 296 | __ncptcp_try_send(server); |
| @@ -705,8 +692,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, | |||
| 705 | req->datalen = max_reply_size; | 692 | req->datalen = max_reply_size; |
| 706 | req->tx_iov[1].iov_base = server->packet; | 693 | req->tx_iov[1].iov_base = server->packet; |
| 707 | req->tx_iov[1].iov_len = size; | 694 | req->tx_iov[1].iov_len = size; |
| 708 | req->tx_iovlen = 1; | ||
| 709 | req->tx_totallen = size; | ||
| 710 | req->tx_type = *(u_int16_t*)server->packet; | 695 | req->tx_type = *(u_int16_t*)server->packet; |
| 711 | 696 | ||
| 712 | result = ncp_add_request(server, req); | 697 | result = ncp_add_request(server, req); |
