[CIFS] Allow SMBWrite2 to work to older servers
Signed-off-by: Steve French (sfrench@us.ibm.com)
This commit is contained in:
parent
3e84469d01
commit
8cc64c6ecf
|
@ -1139,11 +1139,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||||
{
|
{
|
||||||
int rc = -EACCES;
|
int rc = -EACCES;
|
||||||
WRITE_REQ *pSMB = NULL;
|
WRITE_REQ *pSMB = NULL;
|
||||||
int bytes_returned;
|
int bytes_returned, wct;
|
||||||
int smb_hdr_len;
|
int smb_hdr_len;
|
||||||
|
|
||||||
cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
|
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)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
/* tcon and ses pointer are checked in smb_init */
|
/* 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->AndXCommand = 0xFF; /* none */
|
||||||
pSMB->Fid = netfid;
|
pSMB->Fid = netfid;
|
||||||
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
|
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->Reserved = 0xFFFFFFFF;
|
||||||
pSMB->WriteMode = 0;
|
pSMB->WriteMode = 0;
|
||||||
pSMB->Remaining = 0;
|
pSMB->Remaining = 0;
|
||||||
|
@ -1164,9 +1171,17 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||||
pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
|
pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
|
||||||
pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
|
pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
|
||||||
smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
|
smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
|
||||||
pSMB->hdr.smb_buf_length += count+1;
|
if(wct == 14)
|
||||||
pSMB->ByteCount = cpu_to_le16(count + 1);
|
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_base = pSMB;
|
||||||
iov[0].iov_len = smb_hdr_len + 4;
|
iov[0].iov_len = smb_hdr_len + 4;
|
||||||
|
|
||||||
|
@ -1174,7 +1189,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
||||||
long_op);
|
long_op);
|
||||||
cifs_stats_inc(&tcon->num_writes);
|
cifs_stats_inc(&tcon->num_writes);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, ("Send error in write = %d", rc));
|
cFYI(1, ("Send error Write2 = %d", rc));
|
||||||
*nbytes = 0;
|
*nbytes = 0;
|
||||||
} else {
|
} else {
|
||||||
WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
|
WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
|
||||||
|
|
Loading…
Reference in a new issue