|
@@ -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 *
|