aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-10-03 16:37:24 -0400
committerSteve French <sfrench@us.ibm.com>2005-10-03 16:37:24 -0400
commit3e84469d0101456caceffc6b22218a49017fcd3f (patch)
tree2e52687ade7f3e52b5621142997ca6e7b38df70a /fs/cifs/cifssmb.c
parent70ca734a14366b634224a1e4586d43b36b65ab67 (diff)
[CIFS] Add writepages support to shrink memory usage on writes,
eliminate the double copy, and improve cifs write performance and help the server by upping the typical write size from 4K to 16K (or even larger if wsize set explicitly) for servers which support this. Part 1 of 2 Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c41
1 files changed, 17 insertions, 24 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 52caac063a77..365949c14646 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -125,6 +125,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
125 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon 125 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
126 , nls_codepage); 126 , nls_codepage);
127 up(&tcon->ses->sesSem); 127 up(&tcon->ses->sesSem);
128 /* BB FIXME add code to check if wsize needs
129 update due to negotiated smb buffer size
130 shrinking */
128 if(rc == 0) 131 if(rc == 0)
129 atomic_inc(&tconInfoReconnectCount); 132 atomic_inc(&tconInfoReconnectCount);
130 133
@@ -220,6 +223,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
220 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 223 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
221 tcon, nls_codepage); 224 tcon, nls_codepage);
222 up(&tcon->ses->sesSem); 225 up(&tcon->ses->sesSem);
226 /* BB FIXME add code to check if wsize needs
227 update due to negotiated smb buffer size
228 shrinking */
223 if(rc == 0) 229 if(rc == 0)
224 atomic_inc(&tconInfoReconnectCount); 230 atomic_inc(&tconInfoReconnectCount);
225 231
@@ -1128,15 +1134,13 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1128int 1134int
1129CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 1135CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1130 const int netfid, const unsigned int count, 1136 const int netfid, const unsigned int count,
1131 const __u64 offset, unsigned int *nbytes, const char *buf, 1137 const __u64 offset, unsigned int *nbytes, struct kvec *iov,
1132 const int long_op) 1138 int n_vec, const int long_op)
1133{ 1139{
1134 int rc = -EACCES; 1140 int rc = -EACCES;
1135 WRITE_REQ *pSMB = NULL; 1141 WRITE_REQ *pSMB = NULL;
1136 int bytes_returned; 1142 int bytes_returned;
1137 int smb_hdr_len; 1143 int smb_hdr_len;
1138 __u32 bytes_sent;
1139 __u16 byte_count;
1140 1144
1141 cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */ 1145 cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
1142 rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); 1146 rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
@@ -1154,31 +1158,20 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1154 pSMB->WriteMode = 0; 1158 pSMB->WriteMode = 0;
1155 pSMB->Remaining = 0; 1159 pSMB->Remaining = 0;
1156 1160
1157 /* Can increase buffer size if buffer is big enough in some cases - ie
1158 can send more if LARGE_WRITE_X capability returned by the server and if
1159 our buffer is big enough or if we convert to iovecs on socket writes
1160 and eliminate the copy to the CIFS buffer */
1161 if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
1162 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
1163 } else {
1164 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
1165 & ~0xFF;
1166 }
1167
1168 if (bytes_sent > count)
1169 bytes_sent = count;
1170 pSMB->DataOffset = 1161 pSMB->DataOffset =
1171 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1162 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
1172 1163
1173 byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */ 1164 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
1174 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1165 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
1175 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
1176 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */ 1166 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
1177 pSMB->hdr.smb_buf_length += bytes_sent+1; 1167 pSMB->hdr.smb_buf_length += count+1;
1178 pSMB->ByteCount = cpu_to_le16(byte_count); 1168 pSMB->ByteCount = cpu_to_le16(count + 1);
1169
1170 iov[0].iov_base = pSMB;
1171 iov[0].iov_len = smb_hdr_len + 4;
1179 1172
1180 rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len, 1173 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
1181 buf, bytes_sent, &bytes_returned, long_op); 1174 long_op);
1182 cifs_stats_inc(&tcon->num_writes); 1175 cifs_stats_inc(&tcon->num_writes);
1183 if (rc) { 1176 if (rc) {
1184 cFYI(1, ("Send error in write = %d", rc)); 1177 cFYI(1, ("Send error in write = %d", rc));