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