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/cifssmb.c | |
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/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 17 |
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 | ||
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); |