Skip to content

Commit 8101d6e

Browse files
dhowellsSteve French
authored andcommitted
cifs: Fix copy offload to flush destination region
Fix cifs_file_copychunk_range() to flush the destination region before invalidating it to avoid potential loss of data should the copy fail, in whole or in part, in some way. Fixes: 7b2404a ("cifs: Fix flushing, invalidation and file size with copy_file_range()") Signed-off-by: David Howells <dhowells@redhat.com> cc: Steve French <stfrench@microsoft.com> cc: Paulo Alcantara <pc@manguebit.com> cc: Shyam Prasad N <nspmangalore@gmail.com> cc: Rohith Surabattula <rohiths.msft@gmail.com> cc: Matthew Wilcox <willy@infradead.org> cc: Jeff Layton <jlayton@kernel.org> cc: linux-cifs@vger.kernel.org cc: linux-mm@kvack.org cc: linux-fsdevel@vger.kernel.org Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 1da29f2 commit 8101d6e

File tree

1 file changed

+4
-17
lines changed

1 file changed

+4
-17
lines changed

fs/smb/client/cifsfs.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
13411341
struct cifsFileInfo *smb_file_target;
13421342
struct cifs_tcon *src_tcon;
13431343
struct cifs_tcon *target_tcon;
1344-
unsigned long long destend, fstart, fend;
13451344
ssize_t rc;
13461345

13471346
cifs_dbg(FYI, "copychunk range\n");
@@ -1391,25 +1390,13 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
13911390
goto unlock;
13921391
}
13931392

1394-
destend = destoff + len - 1;
1395-
1396-
/* Flush the folios at either end of the destination range to prevent
1397-
* accidental loss of dirty data outside of the range.
1393+
/* Flush and invalidate all the folios in the destination region. If
1394+
* the copy was successful, then some of the flush is extra overhead,
1395+
* but we need to allow for the copy failing in some way (eg. ENOSPC).
13981396
*/
1399-
fstart = destoff;
1400-
fend = destend;
1401-
1402-
rc = cifs_flush_folio(target_inode, destoff, &fstart, &fend, true);
1397+
rc = filemap_invalidate_inode(target_inode, true, destoff, destoff + len - 1);
14031398
if (rc)
14041399
goto unlock;
1405-
rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false);
1406-
if (rc)
1407-
goto unlock;
1408-
if (fend > target_cifsi->netfs.zero_point)
1409-
target_cifsi->netfs.zero_point = fend + 1;
1410-
1411-
/* Discard all the folios that overlap the destination region. */
1412-
truncate_inode_pages_range(&target_inode->i_data, fstart, fend);
14131400

14141401
fscache_invalidate(cifs_inode_cookie(target_inode), NULL,
14151402
i_size_read(target_inode), 0);

0 commit comments

Comments
 (0)