diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-05-26 02:02:00 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-05-26 23:57:16 -0400 |
commit | d4ffff1fa9695c5b5c0bf337e208d8833b88ff2d (patch) | |
tree | acd4b6cfa7962a1cee7e9c81f11bd9ccb0d3ff24 /fs/cifs/file.c | |
parent | 25c7f41e9234f60af30e086278f1de7974f8816f (diff) |
CIFS: Add rwpidforward mount option
Add rwpidforward mount option that switches on a mode when we forward
pid of a process who opened a file to any read and write operation.
This can prevent applications like WINE from failing on read or write
operation on a previously locked file region from the same netfd from
another process if we use mandatory brlock style.
It is actual for WINE because during a run of WINE program two processes
work on the same netfd - share the same file struct between several VFS
fds:
1) WINE-server does open and lock;
2) WINE-application does read and write.
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 82 |
1 files changed, 62 insertions, 20 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dfc0d35b1470..7db74d17a429 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
725 | else | 725 | else |
726 | posix_lock_type = CIFS_WRLCK; | 726 | posix_lock_type = CIFS_WRLCK; |
727 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, | 727 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, |
728 | length, pfLock, | 728 | length, pfLock, posix_lock_type, |
729 | posix_lock_type, wait_flag); | 729 | wait_flag); |
730 | FreeXid(xid); | 730 | FreeXid(xid); |
731 | return rc; | 731 | return rc; |
732 | } | 732 | } |
@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
797 | posix_lock_type = CIFS_UNLCK; | 797 | posix_lock_type = CIFS_UNLCK; |
798 | 798 | ||
799 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, | 799 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, |
800 | length, pfLock, | 800 | length, pfLock, posix_lock_type, |
801 | posix_lock_type, wait_flag); | 801 | wait_flag); |
802 | } else { | 802 | } else { |
803 | struct cifsFileInfo *fid = file->private_data; | 803 | struct cifsFileInfo *fid = file->private_data; |
804 | 804 | ||
@@ -1346,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
1346 | { | 1346 | { |
1347 | int rc; | 1347 | int rc; |
1348 | struct inode *inode = mapping->host; | 1348 | struct inode *inode = mapping->host; |
1349 | struct cifsFileInfo *cfile = file->private_data; | ||
1350 | struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); | ||
1351 | __u32 pid; | ||
1352 | |||
1353 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | ||
1354 | pid = cfile->pid; | ||
1355 | else | ||
1356 | pid = current->tgid; | ||
1349 | 1357 | ||
1350 | cFYI(1, "write_end for page %p from pos %lld with %d bytes", | 1358 | cFYI(1, "write_end for page %p from pos %lld with %d bytes", |
1351 | page, pos, copied); | 1359 | page, pos, copied); |
@@ -1369,8 +1377,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
1369 | /* BB check if anything else missing out of ppw | 1377 | /* BB check if anything else missing out of ppw |
1370 | such as updating last write time */ | 1378 | such as updating last write time */ |
1371 | page_data = kmap(page); | 1379 | page_data = kmap(page); |
1372 | rc = cifs_write(file->private_data, current->tgid, | 1380 | rc = cifs_write(cfile, pid, page_data + offset, copied, &pos); |
1373 | page_data + offset, copied, &pos); | ||
1374 | /* if (rc < 0) should we set writebehind rc? */ | 1381 | /* if (rc < 0) should we set writebehind rc? */ |
1375 | kunmap(page); | 1382 | kunmap(page); |
1376 | 1383 | ||
@@ -1523,6 +1530,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
1523 | struct cifs_sb_info *cifs_sb; | 1530 | struct cifs_sb_info *cifs_sb; |
1524 | struct cifs_io_parms io_parms; | 1531 | struct cifs_io_parms io_parms; |
1525 | int xid, rc; | 1532 | int xid, rc; |
1533 | __u32 pid; | ||
1526 | 1534 | ||
1527 | len = iov_length(iov, nr_segs); | 1535 | len = iov_length(iov, nr_segs); |
1528 | if (!len) | 1536 | if (!len) |
@@ -1554,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
1554 | 1562 | ||
1555 | xid = GetXid(); | 1563 | xid = GetXid(); |
1556 | open_file = file->private_data; | 1564 | open_file = file->private_data; |
1565 | |||
1566 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | ||
1567 | pid = open_file->pid; | ||
1568 | else | ||
1569 | pid = current->tgid; | ||
1570 | |||
1557 | pTcon = tlink_tcon(open_file->tlink); | 1571 | pTcon = tlink_tcon(open_file->tlink); |
1558 | inode = file->f_path.dentry->d_inode; | 1572 | inode = file->f_path.dentry->d_inode; |
1559 | 1573 | ||
@@ -1581,7 +1595,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
1581 | break; | 1595 | break; |
1582 | } | 1596 | } |
1583 | io_parms.netfid = open_file->netfid; | 1597 | io_parms.netfid = open_file->netfid; |
1584 | io_parms.pid = current->tgid; | 1598 | io_parms.pid = pid; |
1585 | io_parms.tcon = pTcon; | 1599 | io_parms.tcon = pTcon; |
1586 | io_parms.offset = *poffset; | 1600 | io_parms.offset = *poffset; |
1587 | io_parms.length = cur_len; | 1601 | io_parms.length = cur_len; |
@@ -1682,7 +1696,9 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, | |||
1682 | struct cifsTconInfo *pTcon; | 1696 | struct cifsTconInfo *pTcon; |
1683 | struct cifsFileInfo *open_file; | 1697 | struct cifsFileInfo *open_file; |
1684 | struct smb_com_read_rsp *pSMBr; | 1698 | struct smb_com_read_rsp *pSMBr; |
1699 | struct cifs_io_parms io_parms; | ||
1685 | char *read_data; | 1700 | char *read_data; |
1701 | __u32 pid; | ||
1686 | 1702 | ||
1687 | if (!nr_segs) | 1703 | if (!nr_segs) |
1688 | return 0; | 1704 | return 0; |
@@ -1697,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, | |||
1697 | open_file = file->private_data; | 1713 | open_file = file->private_data; |
1698 | pTcon = tlink_tcon(open_file->tlink); | 1714 | pTcon = tlink_tcon(open_file->tlink); |
1699 | 1715 | ||
1716 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | ||
1717 | pid = open_file->pid; | ||
1718 | else | ||
1719 | pid = current->tgid; | ||
1720 | |||
1700 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1721 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1701 | cFYI(1, "attempting read on write only file instance"); | 1722 | cFYI(1, "attempting read on write only file instance"); |
1702 | 1723 | ||
@@ -1712,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov, | |||
1712 | if (rc != 0) | 1733 | if (rc != 0) |
1713 | break; | 1734 | break; |
1714 | } | 1735 | } |
1715 | rc = CIFSSMBRead(xid, pTcon, open_file->netfid, | 1736 | io_parms.netfid = open_file->netfid; |
1716 | cur_len, *poffset, &bytes_read, | 1737 | io_parms.pid = pid; |
1738 | io_parms.tcon = pTcon; | ||
1739 | io_parms.offset = *poffset; | ||
1740 | io_parms.length = len; | ||
1741 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, | ||
1717 | &read_data, &buf_type); | 1742 | &read_data, &buf_type); |
1718 | pSMBr = (struct smb_com_read_rsp *)read_data; | 1743 | pSMBr = (struct smb_com_read_rsp *)read_data; |
1719 | if (read_data) { | 1744 | if (read_data) { |
@@ -1794,7 +1819,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1794 | int xid; | 1819 | int xid; |
1795 | char *current_offset; | 1820 | char *current_offset; |
1796 | struct cifsFileInfo *open_file; | 1821 | struct cifsFileInfo *open_file; |
1822 | struct cifs_io_parms io_parms; | ||
1797 | int buf_type = CIFS_NO_BUFFER; | 1823 | int buf_type = CIFS_NO_BUFFER; |
1824 | __u32 pid; | ||
1798 | 1825 | ||
1799 | xid = GetXid(); | 1826 | xid = GetXid(); |
1800 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 1827 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
@@ -1807,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1807 | open_file = file->private_data; | 1834 | open_file = file->private_data; |
1808 | pTcon = tlink_tcon(open_file->tlink); | 1835 | pTcon = tlink_tcon(open_file->tlink); |
1809 | 1836 | ||
1837 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | ||
1838 | pid = open_file->pid; | ||
1839 | else | ||
1840 | pid = current->tgid; | ||
1841 | |||
1810 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1842 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1811 | cFYI(1, "attempting read on write only file instance"); | 1843 | cFYI(1, "attempting read on write only file instance"); |
1812 | 1844 | ||
@@ -1829,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1829 | if (rc != 0) | 1861 | if (rc != 0) |
1830 | break; | 1862 | break; |
1831 | } | 1863 | } |
1832 | rc = CIFSSMBRead(xid, pTcon, | 1864 | io_parms.netfid = open_file->netfid; |
1833 | open_file->netfid, | 1865 | io_parms.pid = pid; |
1834 | current_read_size, *poffset, | 1866 | io_parms.tcon = pTcon; |
1835 | &bytes_read, ¤t_offset, | 1867 | io_parms.offset = *poffset; |
1836 | &buf_type); | 1868 | io_parms.length = current_read_size; |
1869 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, | ||
1870 | ¤t_offset, &buf_type); | ||
1837 | } | 1871 | } |
1838 | if (rc || (bytes_read == 0)) { | 1872 | if (rc || (bytes_read == 0)) { |
1839 | if (total_read) { | 1873 | if (total_read) { |
@@ -1970,7 +2004,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1970 | char *smb_read_data = NULL; | 2004 | char *smb_read_data = NULL; |
1971 | struct smb_com_read_rsp *pSMBr; | 2005 | struct smb_com_read_rsp *pSMBr; |
1972 | struct cifsFileInfo *open_file; | 2006 | struct cifsFileInfo *open_file; |
2007 | struct cifs_io_parms io_parms; | ||
1973 | int buf_type = CIFS_NO_BUFFER; | 2008 | int buf_type = CIFS_NO_BUFFER; |
2009 | __u32 pid; | ||
1974 | 2010 | ||
1975 | xid = GetXid(); | 2011 | xid = GetXid(); |
1976 | if (file->private_data == NULL) { | 2012 | if (file->private_data == NULL) { |
@@ -1992,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1992 | goto read_complete; | 2028 | goto read_complete; |
1993 | 2029 | ||
1994 | cFYI(DBG2, "rpages: num pages %d", num_pages); | 2030 | cFYI(DBG2, "rpages: num pages %d", num_pages); |
2031 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) | ||
2032 | pid = open_file->pid; | ||
2033 | else | ||
2034 | pid = current->tgid; | ||
2035 | |||
1995 | for (i = 0; i < num_pages; ) { | 2036 | for (i = 0; i < num_pages; ) { |
1996 | unsigned contig_pages; | 2037 | unsigned contig_pages; |
1997 | struct page *tmp_page; | 2038 | struct page *tmp_page; |
@@ -2033,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2033 | if (rc != 0) | 2074 | if (rc != 0) |
2034 | break; | 2075 | break; |
2035 | } | 2076 | } |
2036 | 2077 | io_parms.netfid = open_file->netfid; | |
2037 | rc = CIFSSMBRead(xid, pTcon, | 2078 | io_parms.pid = pid; |
2038 | open_file->netfid, | 2079 | io_parms.tcon = pTcon; |
2039 | read_size, offset, | 2080 | io_parms.offset = offset; |
2040 | &bytes_read, &smb_read_data, | 2081 | io_parms.length = read_size; |
2041 | &buf_type); | 2082 | rc = CIFSSMBRead(xid, &io_parms, &bytes_read, |
2083 | &smb_read_data, &buf_type); | ||
2042 | /* BB more RC checks ? */ | 2084 | /* BB more RC checks ? */ |
2043 | if (rc == -EAGAIN) { | 2085 | if (rc == -EAGAIN) { |
2044 | if (smb_read_data) { | 2086 | if (smb_read_data) { |