diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-08 14:58:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-08 14:58:14 -0400 |
| commit | 9ddd3a31aedcdb55d5509b595c04b187041c8adb (patch) | |
| tree | 210582aade8b4342b2abfbc3682dd2014456d23b | |
| parent | d620a7cf05d4f12f5bbb1060d766e8139ab31458 (diff) | |
| parent | f05337c6ac48d19d354e0640a8eb8fc884f82bcc (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
not overwriting file_lock structure after GET_LK
cifs: Fix a kernel BUG with remote OS/2 server (try #3)
[CIFS] initialize nbytes at the beginning of CIFSSMBWrite()
[CIFS] Add mmap for direct, nobrl cifs mount types
| -rw-r--r-- | fs/cifs/cifsfs.c | 1 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 34 | ||||
| -rw-r--r-- | fs/cifs/file.c | 28 |
3 files changed, 59 insertions, 4 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5183bc2a1916..ded66be6597c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -808,6 +808,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { | |||
| 808 | .release = cifs_close, | 808 | .release = cifs_close, |
| 809 | .fsync = cifs_fsync, | 809 | .fsync = cifs_fsync, |
| 810 | .flush = cifs_flush, | 810 | .flush = cifs_flush, |
| 811 | .mmap = cifs_file_mmap, | ||
| 811 | .splice_read = generic_file_splice_read, | 812 | .splice_read = generic_file_splice_read, |
| 812 | #ifdef CONFIG_CIFS_POSIX | 813 | #ifdef CONFIG_CIFS_POSIX |
| 813 | .unlocked_ioctl = cifs_ioctl, | 814 | .unlocked_ioctl = cifs_ioctl, |
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: |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 058b390d3da8..9b11a8f56f3a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -839,8 +839,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
| 839 | 839 | ||
| 840 | } else { | 840 | } else { |
| 841 | /* if rc == ERR_SHARING_VIOLATION ? */ | 841 | /* if rc == ERR_SHARING_VIOLATION ? */ |
| 842 | rc = 0; /* do not change lock type to unlock | 842 | rc = 0; |
| 843 | since range in use */ | 843 | |
| 844 | if (lockType & LOCKING_ANDX_SHARED_LOCK) { | ||
| 845 | pfLock->fl_type = F_WRLCK; | ||
| 846 | } else { | ||
| 847 | rc = CIFSSMBLock(xid, tcon, netfid, length, | ||
| 848 | pfLock->fl_start, 0, 1, | ||
| 849 | lockType | LOCKING_ANDX_SHARED_LOCK, | ||
| 850 | 0 /* wait flag */); | ||
| 851 | if (rc == 0) { | ||
| 852 | rc = CIFSSMBLock(xid, tcon, netfid, | ||
| 853 | length, pfLock->fl_start, 1, 0, | ||
| 854 | lockType | | ||
| 855 | LOCKING_ANDX_SHARED_LOCK, | ||
| 856 | 0 /* wait flag */); | ||
| 857 | pfLock->fl_type = F_RDLCK; | ||
| 858 | if (rc != 0) | ||
| 859 | cERROR(1, ("Error unlocking " | ||
| 860 | "previously locked range %d " | ||
| 861 | "during test of lock", rc)); | ||
| 862 | rc = 0; | ||
| 863 | } else { | ||
| 864 | pfLock->fl_type = F_WRLCK; | ||
| 865 | rc = 0; | ||
| 866 | } | ||
| 867 | } | ||
| 844 | } | 868 | } |
| 845 | 869 | ||
| 846 | FreeXid(xid); | 870 | FreeXid(xid); |
