aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/transport.c79
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
204static unsigned long 204static unsigned long
205rqst_len(struct smb_rqst *rqst) 205smb2_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
238static int 238static 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
314uncork: 323uncork:
@@ -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
380static int 389static int