aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/cifs/README3
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c8
-rw-r--r--fs/cifs/cifsglob.h1
-rw-r--r--fs/cifs/cifsproto.h5
-rw-r--r--fs/cifs/cifssmb.c17
-rw-r--r--fs/cifs/connect.c4
-rw-r--r--fs/cifs/file.c82
-rw-r--r--fs/cifs/inode.c11
-rw-r--r--fs/cifs/link.c22
10 files changed, 115 insertions, 39 deletions
diff --git a/fs/cifs/README b/fs/cifs/README
index 4a3ca0e5ca24..c5c2c5e5f0f2 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
457 otherwise - read from the server. All written data are stored 457 otherwise - read from the server. All written data are stored
458 in the cache, but if the client doesn't have Exclusive Oplock, 458 in the cache, but if the client doesn't have Exclusive Oplock,
459 it writes the data to the server. 459 it writes the data to the server.
460 rwpidforward Forward pid of a process who opened a file to any read or write
461 operation on that file. This prevent applications like WINE
462 from failing on read and write if we use mandatory brlock style.
460 acl Allow setfacl and getfacl to manage posix ACLs if server 463 acl Allow setfacl and getfacl to manage posix ACLs if server
461 supports them. (default) 464 supports them. (default)
462 noacl Do not allow setfacl and getfacl calls on this mount 465 noacl Do not allow setfacl and getfacl calls on this mount
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index c96b44b4e262..ffb1459dc6ec 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -41,6 +41,7 @@
41#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */ 41#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ 42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ 43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
44 45
45struct cifs_sb_info { 46struct cifs_sb_info {
46 struct rb_root tlink_tree; 47 struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 360fe2ec2a19..26981bf2cf3f 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -415,12 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
415 seq_printf(s, ",nocase"); 415 seq_printf(s, ",nocase");
416 if (tcon->retry) 416 if (tcon->retry)
417 seq_printf(s, ",hard"); 417 seq_printf(s, ",hard");
418 if (tcon->unix_ext)
419 seq_printf(s, ",unix");
420 else
421 seq_printf(s, ",nounix");
418 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 422 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
419 seq_printf(s, ",posixpaths"); 423 seq_printf(s, ",posixpaths");
420 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) 424 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
421 seq_printf(s, ",setuids"); 425 seq_printf(s, ",setuids");
422 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 426 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
423 seq_printf(s, ",serverino"); 427 seq_printf(s, ",serverino");
428 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
429 seq_printf(s, ",rwpidforward");
430 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
431 seq_printf(s, ",forcemand");
424 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 432 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
425 seq_printf(s, ",directio"); 433 seq_printf(s, ",directio");
426 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 434 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index ca0c3789206e..310cddabd3fd 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -200,6 +200,7 @@ struct smb_vol {
200 bool fsc:1; /* enable fscache */ 200 bool fsc:1; /* enable fscache */
201 bool mfsymlinks:1; /* use Minshall+French Symlinks */ 201 bool mfsymlinks:1; /* use Minshall+French Symlinks */
202 bool multiuser:1; 202 bool multiuser:1;
203 bool rwpidforward:1; /* pid forward for read/write operations */
203 unsigned int rsize; 204 unsigned int rsize;
204 unsigned int wsize; 205 unsigned int wsize;
205 bool sockopt_tcp_nodelay:1; 206 bool sockopt_tcp_nodelay:1;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index e41f6071cdd2..17063455918f 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -345,9 +345,8 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
345extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, 345extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
346 const int smb_file_id); 346 const int smb_file_id);
347 347
348extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 348extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
349 const int netfid, unsigned int count, 349 unsigned int *nbytes, char **buf,
350 const __u64 lseek, unsigned int *nbytes, char **buf,
351 int *return_buf_type); 350 int *return_buf_type);
352extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms, 351extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
353 unsigned int *nbytes, const char *buf, 352 unsigned int *nbytes, const char *buf,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f39fa08b9b0e..19fd8158bb47 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1382,8 +1382,7 @@ openRetry:
1382} 1382}
1383 1383
1384int 1384int
1385CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, 1385CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1386 const unsigned int count, const __u64 lseek, unsigned int *nbytes,
1387 char **buf, int *pbuf_type) 1386 char **buf, int *pbuf_type)
1388{ 1387{
1389 int rc = -EACCES; 1388 int rc = -EACCES;
@@ -1393,13 +1392,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1393 int wct; 1392 int wct;
1394 int resp_buf_type = 0; 1393 int resp_buf_type = 0;
1395 struct kvec iov[1]; 1394 struct kvec iov[1];
1395 __u32 pid = io_parms->pid;
1396 __u16 netfid = io_parms->netfid;
1397 __u64 offset = io_parms->offset;
1398 struct cifsTconInfo *tcon = io_parms->tcon;
1399 unsigned int count = io_parms->length;
1396 1400
1397 cFYI(1, "Reading %d bytes on fid %d", count, netfid); 1401 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1398 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1402 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1399 wct = 12; 1403 wct = 12;
1400 else { 1404 else {
1401 wct = 10; /* old style read */ 1405 wct = 10; /* old style read */
1402 if ((lseek >> 32) > 0) { 1406 if ((offset >> 32) > 0) {
1403 /* can not handle this big offset for old */ 1407 /* can not handle this big offset for old */
1404 return -EIO; 1408 return -EIO;
1405 } 1409 }
@@ -1410,15 +1414,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1410 if (rc) 1414 if (rc)
1411 return rc; 1415 return rc;
1412 1416
1417 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1418 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1419
1413 /* tcon and ses pointer are checked in smb_init */ 1420 /* tcon and ses pointer are checked in smb_init */
1414 if (tcon->ses->server == NULL) 1421 if (tcon->ses->server == NULL)
1415 return -ECONNABORTED; 1422 return -ECONNABORTED;
1416 1423
1417 pSMB->AndXCommand = 0xFF; /* none */ 1424 pSMB->AndXCommand = 0xFF; /* none */
1418 pSMB->Fid = netfid; 1425 pSMB->Fid = netfid;
1419 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 1426 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1420 if (wct == 12) 1427 if (wct == 12)
1421 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 1428 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1422 1429
1423 pSMB->Remaining = 0; 1430 pSMB->Remaining = 0;
1424 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1431 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 261ca81d5e49..21bc83586beb 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1359,6 +1359,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1359 vol->server_ino = 1; 1359 vol->server_ino = 1;
1360 } else if (strnicmp(data, "noserverino", 9) == 0) { 1360 } else if (strnicmp(data, "noserverino", 9) == 0) {
1361 vol->server_ino = 0; 1361 vol->server_ino = 0;
1362 } else if (strnicmp(data, "rwpidforward", 4) == 0) {
1363 vol->rwpidforward = 1;
1362 } else if (strnicmp(data, "cifsacl", 7) == 0) { 1364 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1363 vol->cifs_acl = 1; 1365 vol->cifs_acl = 1;
1364 } else if (strnicmp(data, "nocifsacl", 9) == 0) { 1366 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
@@ -2708,6 +2710,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2708 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; 2710 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2709 if (pvolume_info->mand_lock) 2711 if (pvolume_info->mand_lock)
2710 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; 2712 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2713 if (pvolume_info->rwpidforward)
2714 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
2711 if (pvolume_info->cifs_acl) 2715 if (pvolume_info->cifs_acl)
2712 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 2716 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2713 if (pvolume_info->override_uid) 2717 if (pvolume_info->override_uid)
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) {
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 53ea6250a51d..e2d9dd817ba0 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -374,6 +374,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
374 __u16 netfid; 374 __u16 netfid;
375 struct tcon_link *tlink; 375 struct tcon_link *tlink;
376 struct cifsTconInfo *tcon; 376 struct cifsTconInfo *tcon;
377 struct cifs_io_parms io_parms;
377 char buf[24]; 378 char buf[24];
378 unsigned int bytes_read; 379 unsigned int bytes_read;
379 char *pbuf; 380 char *pbuf;
@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
405 if (rc == 0) { 406 if (rc == 0) {
406 int buf_type = CIFS_NO_BUFFER; 407 int buf_type = CIFS_NO_BUFFER;
407 /* Read header */ 408 /* Read header */
408 rc = CIFSSMBRead(xid, tcon, netfid, 409 io_parms.netfid = netfid;
409 24 /* length */, 0 /* offset */, 410 io_parms.pid = current->tgid;
410 &bytes_read, &pbuf, &buf_type); 411 io_parms.tcon = tcon;
412 io_parms.offset = 0;
413 io_parms.length = 24;
414 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
415 &buf_type);
411 if ((rc == 0) && (bytes_read >= 8)) { 416 if ((rc == 0) && (bytes_read >= 8)) {
412 if (memcmp("IntxBLK", pbuf, 8) == 0) { 417 if (memcmp("IntxBLK", pbuf, 8) == 0) {
413 cFYI(1, "Block device"); 418 cFYI(1, "Block device");
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 1a6a388cf5d8..4682d44b6f5b 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -235,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
235 unsigned int bytes_read = 0; 235 unsigned int bytes_read = 0;
236 int buf_type = CIFS_NO_BUFFER; 236 int buf_type = CIFS_NO_BUFFER;
237 unsigned int link_len = 0; 237 unsigned int link_len = 0;
238 struct cifs_io_parms io_parms;
238 FILE_ALL_INFO file_info; 239 FILE_ALL_INFO file_info;
239 240
240 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, 241 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
@@ -253,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
253 if (!buf) 254 if (!buf)
254 return -ENOMEM; 255 return -ENOMEM;
255 pbuf = buf; 256 pbuf = buf;
257 io_parms.netfid = netfid;
258 io_parms.pid = current->tgid;
259 io_parms.tcon = tcon;
260 io_parms.offset = 0;
261 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
256 262
257 rc = CIFSSMBRead(xid, tcon, netfid, 263 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
258 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
259 0 /* offset */,
260 &bytes_read, &pbuf, &buf_type);
261 CIFSSMBClose(xid, tcon, netfid); 264 CIFSSMBClose(xid, tcon, netfid);
262 if (rc != 0) { 265 if (rc != 0) {
263 kfree(buf); 266 kfree(buf);
@@ -296,6 +299,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
296 __u16 netfid = 0; 299 __u16 netfid = 0;
297 struct tcon_link *tlink; 300 struct tcon_link *tlink;
298 struct cifsTconInfo *pTcon; 301 struct cifsTconInfo *pTcon;
302 struct cifs_io_parms io_parms;
299 u8 *buf; 303 u8 *buf;
300 char *pbuf; 304 char *pbuf;
301 unsigned int bytes_read = 0; 305 unsigned int bytes_read = 0;
@@ -332,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
332 goto out; 336 goto out;
333 } 337 }
334 pbuf = buf; 338 pbuf = buf;
339 io_parms.netfid = netfid;
340 io_parms.pid = current->tgid;
341 io_parms.tcon = pTcon;
342 io_parms.offset = 0;
343 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
335 344
336 rc = CIFSSMBRead(xid, pTcon, netfid, 345 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
337 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
338 0 /* offset */,
339 &bytes_read, &pbuf, &buf_type);
340 CIFSSMBClose(xid, pTcon, netfid); 346 CIFSSMBClose(xid, pTcon, netfid);
341 if (rc != 0) { 347 if (rc != 0) {
342 kfree(buf); 348 kfree(buf);