diff options
| -rw-r--r-- | fs/cifs/transport.c | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 8b922ffc2345..13c244dfb3c1 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -202,7 +202,7 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg, | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static unsigned long | 204 | static unsigned long |
| 205 | rqst_len(struct smb_rqst *rqst) | 205 | smb2_rqst_len(struct smb_rqst *rqst) |
| 206 | { | 206 | { |
| 207 | unsigned int i; | 207 | unsigned int i; |
| 208 | struct kvec *iov = rqst->rq_iov; | 208 | struct kvec *iov = rqst->rq_iov; |
| @@ -236,13 +236,14 @@ rqst_len(struct smb_rqst *rqst) | |||
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | static int | 238 | static int |
| 239 | __smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | 239 | __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, |
| 240 | struct smb_rqst *rqst) | ||
| 240 | { | 241 | { |
| 241 | int rc; | 242 | int rc = 0; |
| 242 | struct kvec *iov = rqst->rq_iov; | 243 | struct kvec *iov; |
| 243 | int n_vec = rqst->rq_nvec; | 244 | int n_vec; |
| 244 | unsigned int send_length; | 245 | unsigned int send_length = 0; |
| 245 | unsigned int i; | 246 | unsigned int i, j; |
| 246 | size_t total_len = 0, sent, size; | 247 | size_t total_len = 0, sent, size; |
| 247 | struct socket *ssocket = server->ssocket; | 248 | struct socket *ssocket = server->ssocket; |
| 248 | struct msghdr smb_msg; | 249 | struct msghdr smb_msg; |
| @@ -256,14 +257,14 @@ __smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | |||
| 256 | if (ssocket == NULL) | 257 | if (ssocket == NULL) |
| 257 | return -ENOTSOCK; | 258 | return -ENOTSOCK; |
| 258 | 259 | ||
| 259 | send_length = rqst_len(rqst); | ||
| 260 | rfc1002_marker = cpu_to_be32(send_length); | ||
| 261 | |||
| 262 | /* cork the socket */ | 260 | /* cork the socket */ |
| 263 | kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK, | 261 | kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK, |
| 264 | (char *)&val, sizeof(val)); | 262 | (char *)&val, sizeof(val)); |
| 265 | 263 | ||
| 266 | size = 0; | 264 | for (j = 0; j < num_rqst; j++) |
| 265 | send_length += smb2_rqst_len(&rqst[j]); | ||
| 266 | rfc1002_marker = cpu_to_be32(send_length); | ||
| 267 | |||
| 267 | /* Generate a rfc1002 marker for SMB2+ */ | 268 | /* Generate a rfc1002 marker for SMB2+ */ |
| 268 | if (server->vals->header_preamble_size == 0) { | 269 | if (server->vals->header_preamble_size == 0) { |
| 269 | struct kvec hiov = { | 270 | struct kvec hiov = { |
| @@ -280,35 +281,43 @@ __smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | |||
| 280 | send_length += 4; | 281 | send_length += 4; |
| 281 | } | 282 | } |
| 282 | 283 | ||
| 283 | cifs_dbg(FYI, "Sending smb: smb_len=%u\n", send_length); | 284 | for (j = 0; j < num_rqst; j++) { |
| 284 | dump_smb(iov[0].iov_base, iov[0].iov_len); | 285 | iov = rqst[j].rq_iov; |
| 285 | dump_smb(iov[1].iov_base, iov[1].iov_len); | 286 | n_vec = rqst[j].rq_nvec; |
| 286 | 287 | ||
| 287 | for (i = 0; i < n_vec; i++) | 288 | cifs_dbg(FYI, "Sending smb: smb_len=%u\n", send_length); |
| 288 | size += iov[i].iov_len; | 289 | dump_smb(iov[0].iov_base, iov[0].iov_len); |
| 290 | dump_smb(iov[1].iov_base, iov[1].iov_len); | ||
| 289 | 291 | ||
| 290 | iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, iov, n_vec, size); | 292 | size = 0; |
| 291 | 293 | for (i = 0; i < n_vec; i++) | |
| 292 | rc = smb_send_kvec(server, &smb_msg, &sent); | 294 | size += iov[i].iov_len; |
| 293 | if (rc < 0) | ||
| 294 | goto uncork; | ||
| 295 | 295 | ||
| 296 | total_len += sent; | 296 | iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, |
| 297 | iov, n_vec, size); | ||
| 297 | 298 | ||
| 298 | /* now walk the page array and send each page in it */ | ||
| 299 | for (i = 0; i < rqst->rq_npages; i++) { | ||
| 300 | struct bio_vec bvec; | ||
| 301 | |||
| 302 | bvec.bv_page = rqst->rq_pages[i]; | ||
| 303 | rqst_page_get_length(rqst, i, &bvec.bv_len, &bvec.bv_offset); | ||
| 304 | |||
| 305 | iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC, | ||
| 306 | &bvec, 1, bvec.bv_len); | ||
| 307 | rc = smb_send_kvec(server, &smb_msg, &sent); | 299 | rc = smb_send_kvec(server, &smb_msg, &sent); |
| 308 | if (rc < 0) | 300 | if (rc < 0) |
| 309 | break; | 301 | goto uncork; |
| 310 | 302 | ||
| 311 | total_len += sent; | 303 | total_len += sent; |
| 304 | |||
| 305 | /* now walk the page array and send each page in it */ | ||
| 306 | for (i = 0; i < rqst[j].rq_npages; i++) { | ||
| 307 | struct bio_vec bvec; | ||
| 308 | |||
| 309 | bvec.bv_page = rqst[j].rq_pages[i]; | ||
| 310 | rqst_page_get_length(&rqst[j], i, &bvec.bv_len, | ||
| 311 | &bvec.bv_offset); | ||
| 312 | |||
| 313 | iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC, | ||
| 314 | &bvec, 1, bvec.bv_len); | ||
| 315 | rc = smb_send_kvec(server, &smb_msg, &sent); | ||
| 316 | if (rc < 0) | ||
| 317 | break; | ||
| 318 | |||
| 319 | total_len += sent; | ||
| 320 | } | ||
| 312 | } | 321 | } |
| 313 | 322 | ||
| 314 | uncork: | 323 | uncork: |
| @@ -344,7 +353,7 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags) | |||
| 344 | int rc; | 353 | int rc; |
| 345 | 354 | ||
| 346 | if (!(flags & CIFS_TRANSFORM_REQ)) | 355 | if (!(flags & CIFS_TRANSFORM_REQ)) |
| 347 | return __smb_send_rqst(server, rqst); | 356 | return __smb_send_rqst(server, 1, rqst); |
| 348 | 357 | ||
| 349 | if (!server->ops->init_transform_rq || | 358 | if (!server->ops->init_transform_rq || |
| 350 | !server->ops->free_transform_rq) { | 359 | !server->ops->free_transform_rq) { |
| @@ -356,7 +365,7 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags) | |||
| 356 | if (rc) | 365 | if (rc) |
| 357 | return rc; | 366 | return rc; |
| 358 | 367 | ||
| 359 | rc = __smb_send_rqst(server, &cur_rqst); | 368 | rc = __smb_send_rqst(server, 1, &cur_rqst); |
| 360 | server->ops->free_transform_rq(&cur_rqst); | 369 | server->ops->free_transform_rq(&cur_rqst); |
| 361 | return rc; | 370 | return rc; |
| 362 | } | 371 | } |
| @@ -374,7 +383,7 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, | |||
| 374 | iov[1].iov_base = (char *)smb_buffer + 4; | 383 | iov[1].iov_base = (char *)smb_buffer + 4; |
| 375 | iov[1].iov_len = smb_buf_length; | 384 | iov[1].iov_len = smb_buf_length; |
| 376 | 385 | ||
| 377 | return __smb_send_rqst(server, &rqst); | 386 | return __smb_send_rqst(server, 1, &rqst); |
| 378 | } | 387 | } |
| 379 | 388 | ||
| 380 | static int | 389 | static int |
