diff options
author | Steve French <sfrench@us.ibm.com> | 2005-12-12 23:53:18 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-12-12 23:53:18 -0500 |
commit | ec637e3ffb6b978143652477c7c5f96c9519b691 (patch) | |
tree | 32533b8f101e1d85b3499050eef29e78480e5cae /fs/cifs/transport.c | |
parent | c89a86bb96307019867d11874ef0b86adaa0598e (diff) |
[CIFS] Avoid extra large buffer allocation (and memcpy) in cifs_readpages
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/transport.c')
-rw-r--r-- | fs/cifs/transport.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 0abfbf4e4a49..c96a148c39b2 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -298,7 +298,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, | |||
298 | 298 | ||
299 | int | 299 | int |
300 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | 300 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, |
301 | struct kvec *iov, int n_vec, int *pbytes_returned, | 301 | struct kvec *iov, int n_vec, int * pRespBufType /* ret */, |
302 | const int long_op) | 302 | const int long_op) |
303 | { | 303 | { |
304 | int rc = 0; | 304 | int rc = 0; |
@@ -306,6 +306,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
306 | unsigned long timeout; | 306 | unsigned long timeout; |
307 | struct mid_q_entry *midQ; | 307 | struct mid_q_entry *midQ; |
308 | struct smb_hdr *in_buf = iov[0].iov_base; | 308 | struct smb_hdr *in_buf = iov[0].iov_base; |
309 | |||
310 | *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ | ||
309 | 311 | ||
310 | if (ses == NULL) { | 312 | if (ses == NULL) { |
311 | cERROR(1,("Null smb session")); | 313 | cERROR(1,("Null smb session")); |
@@ -491,23 +493,20 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
491 | if (midQ->resp_buf && | 493 | if (midQ->resp_buf && |
492 | (midQ->midState == MID_RESPONSE_RECEIVED)) { | 494 | (midQ->midState == MID_RESPONSE_RECEIVED)) { |
493 | 495 | ||
494 | in_buf->smb_buf_length = receive_len; | 496 | iov[0].iov_base = (char *)midQ->resp_buf; |
495 | if(receive_len > 500) { | 497 | if(midQ->largeBuf) |
496 | /* use multiple buffers on way out */ | 498 | *pRespBufType = CIFS_LARGE_BUFFER; |
497 | } else { | 499 | else |
498 | memcpy((char *)in_buf + 4, | 500 | *pRespBufType = CIFS_SMALL_BUFFER; |
499 | (char *)midQ->resp_buf + 4, | 501 | iov[0].iov_len = receive_len + 4; |
500 | receive_len); | 502 | iov[1].iov_len = 0; |
501 | iov[0].iov_len = receive_len + 4; | ||
502 | iov[1].iov_len = 0; | ||
503 | } | ||
504 | 503 | ||
505 | dump_smb(in_buf, 80); | 504 | dump_smb(midQ->resp_buf, 80); |
506 | /* convert the length into a more usable form */ | 505 | /* convert the length into a more usable form */ |
507 | if((receive_len > 24) && | 506 | if((receive_len > 24) && |
508 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 507 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | |
509 | SECMODE_SIGN_ENABLED))) { | 508 | SECMODE_SIGN_ENABLED))) { |
510 | rc = cifs_verify_signature(in_buf, | 509 | rc = cifs_verify_signature(midQ->resp_buf, |
511 | ses->server->mac_signing_key, | 510 | ses->server->mac_signing_key, |
512 | midQ->sequence_number+1); | 511 | midQ->sequence_number+1); |
513 | if(rc) { | 512 | if(rc) { |
@@ -516,18 +515,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
516 | } | 515 | } |
517 | } | 516 | } |
518 | 517 | ||
519 | *pbytes_returned = in_buf->smb_buf_length; | ||
520 | |||
521 | /* BB special case reconnect tid and uid here? */ | 518 | /* BB special case reconnect tid and uid here? */ |
522 | /* BB special case Errbadpassword and pwdexpired here */ | 519 | /* BB special case Errbadpassword and pwdexpired here */ |
523 | rc = map_smb_to_linux_error(in_buf); | 520 | rc = map_smb_to_linux_error(midQ->resp_buf); |
524 | 521 | ||
525 | /* convert ByteCount if necessary */ | 522 | /* convert ByteCount if necessary */ |
526 | if (receive_len >= | 523 | if (receive_len >= |
527 | sizeof (struct smb_hdr) - | 524 | sizeof (struct smb_hdr) - |
528 | 4 /* do not count RFC1001 header */ + | 525 | 4 /* do not count RFC1001 header */ + |
529 | (2 * in_buf->WordCount) + 2 /* bcc */ ) | 526 | (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) |
530 | BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf)); | 527 | BCC(midQ->resp_buf) = |
528 | le16_to_cpu(BCC_LE(midQ->resp_buf)); | ||
529 | midQ->resp_buf = NULL; /* mark it so will not be freed | ||
530 | by DeleteMidQEntry */ | ||
531 | } else { | 531 | } else { |
532 | rc = -EIO; | 532 | rc = -EIO; |
533 | cFYI(1,("Bad MID state?")); | 533 | cFYI(1,("Bad MID state?")); |
@@ -793,7 +793,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
793 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | 793 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); |
794 | } else { | 794 | } else { |
795 | rc = -EIO; | 795 | rc = -EIO; |
796 | cERROR(1,("Bad MID state? ")); | 796 | cERROR(1,("Bad MID state?")); |
797 | } | 797 | } |
798 | } | 798 | } |
799 | cifs_no_response_exit: | 799 | cifs_no_response_exit: |