Re: [PATCH] cifs: Set the file size after doing copychunk_range

From: Steve French
Date: Fri Nov 24 2023 - 22:23:08 EST


updated


On Fri, Nov 24, 2023 at 5:27 PM David Howells <dhowells@xxxxxxxxxx> wrote:
>
> David Howells <dhowells@xxxxxxxxxx> wrote:
>
> > + truncate_inode_pages_range(&target_inode->i_data, destoff, len);
>
> That should actually be:
>
> truncate_inode_pages_range(&target_inode->i_data, destoff, destoff + len);
>
> David
>
>


--
Thanks,

Steve
From c6008ad23422c0a29d1ba175905cd8a02b5df5b6 Mon Sep 17 00:00:00 2001
From: David Howells <dhowells@xxxxxxxxxx>
Date: Fri, 24 Nov 2023 21:51:16 +0000
Subject: [PATCH] cifs: Set the file size after doing copychunk_range

Set i_size on the inode after doing the copychunk_range operation as this
value may be used by various things internally. stat() hides the issue
because setting ->time to 0 causes cifs_getatr() to revalidate the
attributes.

Also reduce the pagecache truncation to only invalidate the range of bytes
that will be copied over otherwise we will discard dirty data that isn't
inside the target range.

Fixes: 620d8745b35d ("Introduce cifs_copy_file_range()")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
cc: Shyam Prasad N <nspmangalore@xxxxxxxxx>
cc: Rohith Surabattula <rohiths.msft@xxxxxxxxx>
cc: Jeff Layton <jlayton@xxxxxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
fs/smb/client/cifsfs.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index ea3a7a668b45..f845e735f116 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -1307,12 +1307,15 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
goto unlock;

/* should we flush first and last page first */
- truncate_inode_pages(&target_inode->i_data, 0);
+ truncate_inode_pages_range(&target_inode->i_data, destoff, destoff + len);

rc = file_modified(dst_file);
- if (!rc)
+ if (!rc) {
rc = target_tcon->ses->server->ops->copychunk_range(xid,
smb_file_src, smb_file_target, off, len, destoff);
+ if (rc > 0 && destoff + rc > i_size_read(target_inode))
+ truncate_setsize(target_inode, destoff + rc);
+ }

file_accessed(src_file);

--
2.39.2