diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
| -rw-r--r-- | fs/cifs/cifssmb.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3f4fbd670507..5d3f29fef532 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -1431,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
| 1431 | __u32 bytes_sent; | 1431 | __u32 bytes_sent; |
| 1432 | __u16 byte_count; | 1432 | __u16 byte_count; |
| 1433 | 1433 | ||
| 1434 | *nbytes = 0; | ||
| 1435 | |||
| 1434 | /* cFYI(1, ("write at %lld %d bytes", offset, count));*/ | 1436 | /* cFYI(1, ("write at %lld %d bytes", offset, count));*/ |
| 1435 | if (tcon->ses == NULL) | 1437 | if (tcon->ses == NULL) |
| 1436 | return -ECONNABORTED; | 1438 | return -ECONNABORTED; |
| @@ -1513,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
| 1513 | cifs_stats_inc(&tcon->num_writes); | 1515 | cifs_stats_inc(&tcon->num_writes); |
| 1514 | if (rc) { | 1516 | if (rc) { |
| 1515 | cFYI(1, ("Send error in write = %d", rc)); | 1517 | cFYI(1, ("Send error in write = %d", rc)); |
| 1516 | *nbytes = 0; | ||
| 1517 | } else { | 1518 | } else { |
| 1518 | *nbytes = le16_to_cpu(pSMBr->CountHigh); | 1519 | *nbytes = le16_to_cpu(pSMBr->CountHigh); |
| 1519 | *nbytes = (*nbytes) << 16; | 1520 | *nbytes = (*nbytes) << 16; |
| 1520 | *nbytes += le16_to_cpu(pSMBr->Count); | 1521 | *nbytes += le16_to_cpu(pSMBr->Count); |
| 1522 | |||
| 1523 | /* | ||
| 1524 | * Mask off high 16 bits when bytes written as returned by the | ||
| 1525 | * server is greater than bytes requested by the client. Some | ||
| 1526 | * OS/2 servers are known to set incorrect CountHigh values. | ||
| 1527 | */ | ||
| 1528 | if (*nbytes > count) | ||
| 1529 | *nbytes &= 0xFFFF; | ||
| 1521 | } | 1530 | } |
| 1522 | 1531 | ||
| 1523 | cifs_buf_release(pSMB); | 1532 | cifs_buf_release(pSMB); |
| @@ -1606,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
| 1606 | *nbytes = le16_to_cpu(pSMBr->CountHigh); | 1615 | *nbytes = le16_to_cpu(pSMBr->CountHigh); |
| 1607 | *nbytes = (*nbytes) << 16; | 1616 | *nbytes = (*nbytes) << 16; |
| 1608 | *nbytes += le16_to_cpu(pSMBr->Count); | 1617 | *nbytes += le16_to_cpu(pSMBr->Count); |
| 1618 | |||
| 1619 | /* | ||
| 1620 | * Mask off high 16 bits when bytes written as returned by the | ||
| 1621 | * server is greater than bytes requested by the client. OS/2 | ||
| 1622 | * servers are known to set incorrect CountHigh values. | ||
| 1623 | */ | ||
| 1624 | if (*nbytes > count) | ||
| 1625 | *nbytes &= 0xFFFF; | ||
| 1609 | } | 1626 | } |
| 1610 | 1627 | ||
| 1611 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ | 1628 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ |
| @@ -1794,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1794 | } | 1811 | } |
| 1795 | parm_data = (struct cifs_posix_lock *) | 1812 | parm_data = (struct cifs_posix_lock *) |
| 1796 | ((char *)&pSMBr->hdr.Protocol + data_offset); | 1813 | ((char *)&pSMBr->hdr.Protocol + data_offset); |
| 1797 | if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) | 1814 | if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK)) |
| 1798 | pLockData->fl_type = F_UNLCK; | 1815 | pLockData->fl_type = F_UNLCK; |
| 1816 | else { | ||
| 1817 | if (parm_data->lock_type == | ||
| 1818 | __constant_cpu_to_le16(CIFS_RDLCK)) | ||
| 1819 | pLockData->fl_type = F_RDLCK; | ||
| 1820 | else if (parm_data->lock_type == | ||
| 1821 | __constant_cpu_to_le16(CIFS_WRLCK)) | ||
| 1822 | pLockData->fl_type = F_WRLCK; | ||
| 1823 | |||
| 1824 | pLockData->fl_start = parm_data->start; | ||
| 1825 | pLockData->fl_end = parm_data->start + | ||
| 1826 | parm_data->length - 1; | ||
| 1827 | pLockData->fl_pid = parm_data->pid; | ||
| 1828 | } | ||
| 1799 | } | 1829 | } |
| 1800 | 1830 | ||
| 1801 | plk_err_exit: | 1831 | plk_err_exit: |
