Skip to content

Commit cfc63fc

Browse files
author
Steve French
committed
smb3: fix cached file size problems in duplicate extents (reflink)
There were two problems (one of which could cause data corruption) that were noticed with duplicate extents (ie reflink) when debugging why various xfstests were being incorrectly skipped (e.g. generic/138, generic/140, generic/142). First, we were not updating the file size locally in the cache when extending a file due to reflink (it would refresh after actimeo expires) but xfstest was checking the size immediately which was still 0 so caused the test to be skipped. Second, we were setting the target file size (which could shrink the file) in all cases to the end of the reflinked range rather than only setting the target file size when reflink would extend the file. CC: <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 219481a commit cfc63fc

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

fs/cifs/smb2ops.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,7 @@ smb2_duplicate_extents(const unsigned int xid,
20382038
{
20392039
int rc;
20402040
unsigned int ret_data_len;
2041+
struct inode *inode;
20412042
struct duplicate_extents_to_file dup_ext_buf;
20422043
struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
20432044

@@ -2054,10 +2055,21 @@ smb2_duplicate_extents(const unsigned int xid,
20542055
cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
20552056
src_off, dest_off, len);
20562057

2057-
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
2058-
if (rc)
2059-
goto duplicate_extents_out;
2058+
inode = d_inode(trgtfile->dentry);
2059+
if (inode->i_size < dest_off + len) {
2060+
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
2061+
if (rc)
2062+
goto duplicate_extents_out;
20602063

2064+
/*
2065+
* Although also could set plausible allocation size (i_blocks)
2066+
* here in addition to setting the file size, in reflink
2067+
* it is likely that the target file is sparse. Its allocation
2068+
* size will be queried on next revalidate, but it is important
2069+
* to make sure that file's cached size is updated immediately
2070+
*/
2071+
cifs_setsize(inode, dest_off + len);
2072+
}
20612073
rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid,
20622074
trgtfile->fid.volatile_fid,
20632075
FSCTL_DUPLICATE_EXTENTS_TO_FILE,

0 commit comments

Comments
 (0)