summaryrefslogtreecommitdiff
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-10-03 13:49:43 -0700
committerSteve French <sfrench@us.ibm.com>2005-10-03 13:49:43 -0700
commit8cc64c6ecfef020d40829f3e1152aab006c13899 (patch)
tree0e7a9bbde73768d56a4428fb63ea3bcf71860617 /fs/cifs
parent3e84469d0101456caceffc6b22218a49017fcd3f (diff)
downloadlinux-3.10-8cc64c6ecfef020d40829f3e1152aab006c13899.tar.gz
linux-3.10-8cc64c6ecfef020d40829f3e1152aab006c13899.tar.bz2
linux-3.10-8cc64c6ecfef020d40829f3e1152aab006c13899.zip
[CIFS] Allow SMBWrite2 to work to older servers
Signed-off-by: Steve French (sfrench@us.ibm.com)
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifssmb.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 365949c1464..41996a24014 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1139,11 +1139,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
{
int rc = -EACCES;
WRITE_REQ *pSMB = NULL;
- int bytes_returned;
+ int bytes_returned, wct;
int smb_hdr_len;
cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
- rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
+ if(tcon->ses->capabilities & CAP_LARGE_FILES)
+ wct = 14;
+ else
+ wct = 12;
+ rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
if (rc)
return rc;
/* tcon and ses pointer are checked in smb_init */
@@ -1153,7 +1157,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+ if(wct == 14)
+ pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
+ else if((offset >> 32) > 0) /* can not handle this big offset for old */
+ return -EIO;
pSMB->Reserved = 0xFFFFFFFF;
pSMB->WriteMode = 0;
pSMB->Remaining = 0;
@@ -1164,9 +1171,17 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
- pSMB->hdr.smb_buf_length += count+1;
- pSMB->ByteCount = cpu_to_le16(count + 1);
-
+ if(wct == 14)
+ pSMB->hdr.smb_buf_length += count+1;
+ else /* wct == 12 */
+ pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
+ if(wct == 14)
+ pSMB->ByteCount = cpu_to_le16(count + 1);
+ else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
+ struct smb_com_writex_req * pSMBW =
+ (struct smb_com_writex_req *)pSMB;
+ pSMBW->ByteCount = cpu_to_le16(count + 5);
+ }
iov[0].iov_base = pSMB;
iov[0].iov_len = smb_hdr_len + 4;
@@ -1174,7 +1189,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
long_op);
cifs_stats_inc(&tcon->num_writes);
if (rc) {
- cFYI(1, ("Send error in write = %d", rc));
+ cFYI(1, ("Send error Write2 = %d", rc));
*nbytes = 0;
} else {
WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;