From d59f21c2e3deafa0188af589987601ce27292bad Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Fri, 21 Dec 2012 15:07:52 +0400 Subject: [PATCH] --- yaml --- r: 348331 b: refs/heads/master c: 88cf75aaaf27a652b3e85960ac3060172dd3edac h: refs/heads/master i: 348329: f5d6a0787098c7242ec13ab2f3a2b1ceada82581 348327: 138904c3453dd86d61b3c9000036ec6700fab2b9 v: v3 --- [refs] | 2 +- trunk/fs/cifs/file.c | 48 ++++++++++++++++++-------------------------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/[refs] b/[refs] index f27b3c9b11c4..3e6133837a79 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ca8aa29c60238720af2ca2a5caab25fa0c70067e +refs/heads/master: 88cf75aaaf27a652b3e85960ac3060172dd3edac diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 1b322d041f1e..22c37254b64e 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -2505,42 +2505,34 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, struct cifsFileInfo *cfile = (struct cifsFileInfo *) iocb->ki_filp->private_data; struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + ssize_t written; -#ifdef CONFIG_CIFS_SMB2 - /* - * If we have an oplock for read and want to write a data to the file - * we need to store it in the page cache and then push it to the server - * to be sure the next read will get a valid data. - */ - if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead) { - ssize_t written; - int rc; - - written = generic_file_aio_write(iocb, iov, nr_segs, pos); - rc = filemap_fdatawrite(inode->i_mapping); - if (rc) - return (ssize_t)rc; - - return written; + if (cinode->clientCanCacheAll) { + if (cap_unix(tcon->ses) && + (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) + && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) + return generic_file_aio_write(iocb, iov, nr_segs, pos); + return cifs_writev(iocb, iov, nr_segs, pos); } -#endif - /* * For non-oplocked files in strict cache mode we need to write the data * to the server exactly from the pos to pos+len-1 rather than flush all * affected pages because it may cause a error with mandatory locks on * these pages but not on the region from pos to ppos+len-1. */ - - if (!cinode->clientCanCacheAll) - return cifs_user_writev(iocb, iov, nr_segs, pos); - - if (cap_unix(tcon->ses) && - (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) - return generic_file_aio_write(iocb, iov, nr_segs, pos); - - return cifs_writev(iocb, iov, nr_segs, pos); + written = cifs_user_writev(iocb, iov, nr_segs, pos); + if (written > 0 && cinode->clientCanCacheRead) { + /* + * Windows 7 server can delay breaking level2 oplock if a write + * request comes - break it on the client to prevent reading + * an old data. + */ + cifs_invalidate_mapping(inode); + cFYI(1, "Set no oplock for inode=%p after a write operation", + inode); + cinode->clientCanCacheRead = false; + } + return written; } static struct cifs_readdata *