aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-05-26 02:02:00 -0400
committerSteve French <sfrench@us.ibm.com>2011-05-26 23:57:16 -0400
commitd4ffff1fa9695c5b5c0bf337e208d8833b88ff2d (patch)
treeacd4b6cfa7962a1cee7e9c81f11bd9ccb0d3ff24 /fs/cifs/file.c
parent25c7f41e9234f60af30e086278f1de7974f8816f (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.c82
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, &current_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 &current_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) {