aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-06-13 14:24:43 -0400
committerSteve French <sfrench@us.ibm.com>2005-06-13 14:24:43 -0400
commitd6e04ae64c6b06ef76a5d4fb49106b393b7fa50a (patch)
tree0ae0d4e7c94ccbba95e55d7512eb628d845eff20 /fs/cifs/cifssmb.c
parent2830077f7ae93ef2f7a312e3e489110963612e77 (diff)
[CIFS] CIFS writepage improvements - eliminate double copy
Signed-off-by: Steve French (sfrench@us.ibm.com)
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 3c628bf667a5..b4f7b9859e3b 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -951,56 +951,69 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
951} 951}
952 952
953#ifdef CONFIG_CIFS_EXPERIMENTAL 953#ifdef CONFIG_CIFS_EXPERIMENTAL
954int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 954int
955CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
955 const int netfid, const unsigned int count, 956 const int netfid, const unsigned int count,
956 const __u64 offset, unsigned int *nbytes, const char __user *buf, 957 const __u64 offset, unsigned int *nbytes, const char *buf,
957 const int long_op) 958 const int long_op)
958{ 959{
959 int rc = -EACCES; 960 int rc = -EACCES;
960 WRITE_REQ *pSMB = NULL; 961 WRITE_REQ *pSMB = NULL;
961 WRITE_RSP *pSMBr = NULL; 962 int bytes_returned;
962 /*int bytes_returned;*/ 963 int smb_hdr_len;
963 unsigned bytes_sent; 964 __u32 bytes_sent;
964 __u16 byte_count; 965 __u16 byte_count;
965 966
967 cERROR(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
966 rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); 968 rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
967
968 if (rc) 969 if (rc)
969 return rc; 970 return rc;
970
971 pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
972
973 /* tcon and ses pointer are checked in smb_init */ 971 /* tcon and ses pointer are checked in smb_init */
974 if (tcon->ses->server == NULL) 972 if (tcon->ses->server == NULL)
975 return -ECONNABORTED; 973 return -ECONNABORTED;
976 974
977 pSMB->AndXCommand = 0xFF; /* none */ 975 pSMB->AndXCommand = 0xFF; /* none */
978 pSMB->Fid = netfid; 976 pSMB->Fid = netfid;
979 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 977 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
980 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 978 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
981 pSMB->Reserved = 0xFFFFFFFF; 979 pSMB->Reserved = 0xFFFFFFFF;
982 pSMB->WriteMode = 0; 980 pSMB->WriteMode = 0;
983 pSMB->Remaining = 0; 981 pSMB->Remaining = 0;
984 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF; 982
983 /* Can increase buffer size if buffer is big enough in some cases - ie
984 can send more if LARGE_WRITE_X capability returned by the server and if
985 our buffer is big enough or if we convert to iovecs on socket writes
986 and eliminate the copy to the CIFS buffer */
987 if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
988 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
989 } else {
990 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
991 & ~0xFF;
992 }
993
985 if (bytes_sent > count) 994 if (bytes_sent > count)
986 bytes_sent = count; 995 bytes_sent = count;
987 pSMB->DataLengthHigh = 0;
988 pSMB->DataOffset = 996 pSMB->DataOffset =
989 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 997 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
990 998
991 byte_count = bytes_sent + 1 /* pad */ ; 999 byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
992 pSMB->DataLengthLow = cpu_to_le16(bytes_sent); 1000 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
993 pSMB->DataLengthHigh = 0; 1001 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
994 pSMB->hdr.smb_buf_length += byte_count; 1002 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
1003 pSMB->hdr.smb_buf_length += bytes_sent+1;
995 pSMB->ByteCount = cpu_to_le16(byte_count); 1004 pSMB->ByteCount = cpu_to_le16(byte_count);
996 1005
997/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, 1006 rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, smb_hdr_len,
998 (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */ 1007 buf, bytes_sent, &bytes_returned, long_op);
999 if (rc) { 1008 if (rc) {
1000 cFYI(1, ("Send error in write2 (large write) = %d", rc)); 1009 cFYI(1, ("Send error in write = %d", rc));
1001 *nbytes = 0; 1010 *nbytes = 0;
1002 } else 1011 } else {
1003 *nbytes = le16_to_cpu(pSMBr->Count); 1012 WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
1013 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1014 *nbytes = (*nbytes) << 16;
1015 *nbytes += le16_to_cpu(pSMBr->Count);
1016 }
1004 1017
1005 cifs_small_buf_release(pSMB); 1018 cifs_small_buf_release(pSMB);
1006 1019
@@ -1009,6 +1022,8 @@ int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1009 1022
1010 return rc; 1023 return rc;
1011} 1024}
1025
1026
1012#endif /* CIFS_EXPERIMENTAL */ 1027#endif /* CIFS_EXPERIMENTAL */
1013 1028
1014int 1029int