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); |