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 | |
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')
-rw-r--r-- | fs/cifs/README | 3 | ||||
-rw-r--r-- | fs/cifs/cifs_fs_sb.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 8 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 5 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 17 | ||||
-rw-r--r-- | fs/cifs/connect.c | 4 | ||||
-rw-r--r-- | fs/cifs/file.c | 82 | ||||
-rw-r--r-- | fs/cifs/inode.c | 11 | ||||
-rw-r--r-- | fs/cifs/link.c | 22 |
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 | ||
45 | struct cifs_sb_info { | 46 | struct 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, | |||
345 | extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, | 345 | extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, |
346 | const int smb_file_id); | 346 | const int smb_file_id); |
347 | 347 | ||
348 | extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | 348 | extern 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); |
352 | extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms, | 351 | extern 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 | ||
1384 | int | 1384 | int |
1385 | CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, | 1385 | CIFSSMBRead(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, ¤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) { |
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); |