diff options
-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 ccad858d2d67..e93e3d2c69e6 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) |