[PATCH v2][SMB3 client] smb3: use filemap_write_and_wait_range instead of filemap_write_and_wait
From: Steve French
Date: Mon Aug 29 2022 - 22:16:02 EST
When doing insert range and collapse range we should be
writing out the cached pages for the ranges affected but not
the whole file (and also checking for errors if writing them out
fails)
See attached
--
Thanks,
Steve
From 90ca08b3ee69f15c5a6e3d8d76d516d8f03ccf15 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@xxxxxxxxxxxxx>
Date: Mon, 29 Aug 2022 11:53:41 -0500
Subject: [PATCH] smb3: use filemap_write_and_wait_range instead of
filemap_write_and_wait
When doing insert range and collapse range we should be
writing out the cached pages for the ranges affected but not
the whole file.
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
fs/cifs/cifsfs.c | 8 ++++++--
fs/cifs/smb2ops.c | 13 +++++++++----
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index e9fb338b8e7e..8042d7280dec 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1219,8 +1219,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
cifs_dbg(FYI, "copychunk range\n");
- filemap_write_and_wait(src_inode->i_mapping);
-
if (!src_file->private_data || !dst_file->private_data) {
rc = -EBADF;
cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
@@ -1250,6 +1248,12 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
lock_two_nondirectories(target_inode, src_inode);
cifs_dbg(FYI, "about to flush pages\n");
+
+ rc = filemap_write_and_wait_range(src_inode->i_mapping, off,
+ off + len - 1);
+ if (rc)
+ goto out;
+
/* should we flush first and last page first */
truncate_inode_pages(&target_inode->i_data, 0);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 7c941ce1e7a9..f1d36b70cef7 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -3687,7 +3687,10 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
}
filemap_invalidate_lock(inode->i_mapping);
- filemap_write_and_wait(inode->i_mapping);
+ rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof - 1);
+ if (rc < 0)
+ goto out_2;
+
truncate_pagecache_range(inode, off, old_eof);
rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
@@ -3708,7 +3711,7 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
fscache_resize_cookie(cifs_inode_cookie(inode), cifsi->server_eof);
out_2:
filemap_invalidate_unlock(inode->i_mapping);
- out:
+out:
inode_unlock(inode);
free_xid(xid);
return rc;
@@ -3738,7 +3741,9 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
eof = cpu_to_le64(old_eof + len);
filemap_invalidate_lock(inode->i_mapping);
- filemap_write_and_wait(inode->i_mapping);
+ rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof + len - 1);
+ if (rc < 0)
+ goto out_2;
truncate_pagecache_range(inode, off, old_eof);
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
@@ -3757,7 +3762,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
rc = 0;
out_2:
filemap_invalidate_unlock(inode->i_mapping);
- out:
+out:
inode_unlock(inode);
free_xid(xid);
return rc;
--
2.34.1