aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.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/cifssmb.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/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c17
1 files changed, 12 insertions, 5 deletions
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);