diff options
author | Steve French <sfrench@us.ibm.com> | 2005-10-03 13:49:43 -0700 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-10-03 13:49:43 -0700 |
commit | 8cc64c6ecfef020d40829f3e1152aab006c13899 (patch) | |
tree | 0e7a9bbde73768d56a4428fb63ea3bcf71860617 /fs/cifs | |
parent | 3e84469d0101456caceffc6b22218a49017fcd3f (diff) | |
download | linux-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.c | 29 |
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; |