summaryrefslogtreecommitdiffstats
path: root/fs/cifs/transport.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-12-13 05:53:18 +0100
committerSteve French <sfrench@us.ibm.com>2005-12-13 05:53:18 +0100
commitec637e3ffb6b978143652477c7c5f96c9519b691 (patch)
tree32533b8f101e1d85b3499050eef29e78480e5cae /fs/cifs/transport.c
parentMerge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git (diff)
downloadlinux-ec637e3ffb6b978143652477c7c5f96c9519b691.tar.xz
linux-ec637e3ffb6b978143652477c7c5f96c9519b691.zip
[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.c38
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,
int
SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
- struct kvec *iov, int n_vec, int *pbytes_returned,
+ struct kvec *iov, int n_vec, int * pRespBufType /* ret */,
const int long_op)
{
int rc = 0;
@@ -306,6 +306,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
unsigned long timeout;
struct mid_q_entry *midQ;
struct smb_hdr *in_buf = iov[0].iov_base;
+
+ *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
if (ses == NULL) {
cERROR(1,("Null smb session"));
@@ -491,23 +493,20 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
if (midQ->resp_buf &&
(midQ->midState == MID_RESPONSE_RECEIVED)) {
- in_buf->smb_buf_length = receive_len;
- if(receive_len > 500) {
- /* use multiple buffers on way out */
- } else {
- memcpy((char *)in_buf + 4,
- (char *)midQ->resp_buf + 4,
- receive_len);
- iov[0].iov_len = receive_len + 4;
- iov[1].iov_len = 0;
- }
+ iov[0].iov_base = (char *)midQ->resp_buf;
+ if(midQ->largeBuf)
+ *pRespBufType = CIFS_LARGE_BUFFER;
+ else
+ *pRespBufType = CIFS_SMALL_BUFFER;
+ iov[0].iov_len = receive_len + 4;
+ iov[1].iov_len = 0;
- dump_smb(in_buf, 80);
+ dump_smb(midQ->resp_buf, 80);
/* convert the length into a more usable form */
if((receive_len > 24) &&
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
- rc = cifs_verify_signature(in_buf,
+ rc = cifs_verify_signature(midQ->resp_buf,
ses->server->mac_signing_key,
midQ->sequence_number+1);
if(rc) {
@@ -516,18 +515,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
}
}
- *pbytes_returned = in_buf->smb_buf_length;
-
/* BB special case reconnect tid and uid here? */
/* BB special case Errbadpassword and pwdexpired here */
- rc = map_smb_to_linux_error(in_buf);
+ rc = map_smb_to_linux_error(midQ->resp_buf);
/* convert ByteCount if necessary */
if (receive_len >=
sizeof (struct smb_hdr) -
4 /* do not count RFC1001 header */ +
- (2 * in_buf->WordCount) + 2 /* bcc */ )
- BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf));
+ (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
+ BCC(midQ->resp_buf) =
+ le16_to_cpu(BCC_LE(midQ->resp_buf));
+ midQ->resp_buf = NULL; /* mark it so will not be freed
+ by DeleteMidQEntry */
} else {
rc = -EIO;
cFYI(1,("Bad MID state?"));
@@ -793,7 +793,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
} else {
rc = -EIO;
- cERROR(1,("Bad MID state? "));
+ cERROR(1,("Bad MID state?"));
}
}
cifs_no_response_exit: