Skip to content

Commit

Permalink
cifs: fix data corruption in read after invalidate
Browse files Browse the repository at this point in the history
When invalidating a file as part of breaking a lease, the folios holding
the file data are disposed of, and truncate calls ->invalidate_folio()
to get rid of them rather than calling ->release_folio().  This means
that the netfs_inode::zero_point value didn't get updated in current
upstream code to reflect the point after which we can assume that the
server will only return zeroes, and future reads will then return blocks
of zeroes if the file got extended for any region beyond the old zero
point.

Fix this by updating zero_point before invalidating the inode in
cifs_revalidate_mapping().

Suggested-by: David Howells <dhowells@redhat.com>
Fixes: 3ee1a1f ("cifs: Cut over to using netfslib")
Reviewed-by: David Howells <dhowell@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
  • Loading branch information
Steve French committed May 15, 2024
1 parent 1ab1bd2 commit a395726
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion fs/smb/client/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2465,7 +2465,8 @@ int
cifs_revalidate_mapping(struct inode *inode)
{
int rc;
unsigned long *flags = &CIFS_I(inode)->flags;
struct cifsInodeInfo *cifs_inode = CIFS_I(inode);
unsigned long *flags = &cifs_inode->flags;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);

/* swapfiles are not supposed to be shared */
Expand All @@ -2482,6 +2483,7 @@ cifs_revalidate_mapping(struct inode *inode)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
goto skip_invalidate;

cifs_inode->netfs.zero_point = cifs_inode->netfs.remote_i_size;
rc = filemap_invalidate_inode(inode, true, 0, LLONG_MAX);
if (rc) {
cifs_dbg(VFS, "%s: invalidate inode %p failed with rc %d\n",
Expand Down

0 comments on commit a395726

Please sign in to comment.