diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2012-09-19 09:22:45 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:33 -0400 |
commit | 25078105fbe14e7b3270391eaa11514bec787a52 (patch) | |
tree | 13ae2774d194c9ae2c6566a885503164b5ed9434 /fs/cifs | |
parent | b8c32dbb0deb287a5fcb78251e4eae6c7275760d (diff) |
CIFS: Fix cache coherency for read oplock case
When we have a file opened with read oplock and we are writing a data
to this file, we need to store the data in the cache and then send to
the server to ensure that the next read operation will get a coherent
data.
Also mark it as CONFIG_CIFS_SMB2 because it's more suitable for SMB2
code but can fix some CIFS problems too (when server delays sending
an oplock break after a write request). We can drop this ifdefs
dependence in future.
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/file.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ccad858d2d6..e93e3d2c69e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2461,11 +2461,30 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2461 | iocb->ki_filp->private_data; | 2461 | iocb->ki_filp->private_data; |
2462 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 2462 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
2463 | 2463 | ||
2464 | #ifdef CONFIG_CIFS_SMB2 | ||
2464 | /* | 2465 | /* |
2465 | * In strict cache mode we need to write the data to the server exactly | 2466 | * If we have an oplock for read and want to write a data to the file |
2466 | * from the pos to pos+len-1 rather than flush all affected pages | 2467 | * we need to store it in the page cache and then push it to the server |
2467 | * because it may cause a error with mandatory locks on these pages but | 2468 | * to be sure the next read will get a valid data. |
2468 | * not on the region from pos to ppos+len-1. | 2469 | */ |
2470 | if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead) { | ||
2471 | ssize_t written; | ||
2472 | int rc; | ||
2473 | |||
2474 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
2475 | rc = filemap_fdatawrite(inode->i_mapping); | ||
2476 | if (rc) | ||
2477 | return (ssize_t)rc; | ||
2478 | |||
2479 | return written; | ||
2480 | } | ||
2481 | #endif | ||
2482 | |||
2483 | /* | ||
2484 | * For non-oplocked files in strict cache mode we need to write the data | ||
2485 | * to the server exactly from the pos to pos+len-1 rather than flush all | ||
2486 | * affected pages because it may cause a error with mandatory locks on | ||
2487 | * these pages but not on the region from pos to ppos+len-1. | ||
2469 | */ | 2488 | */ |
2470 | 2489 | ||
2471 | if (!cinode->clientCanCacheAll) | 2490 | if (!cinode->clientCanCacheAll) |