FAILED: patch "[PATCH] smb3: fix temporary data corruption in collapse range" failed to apply to 5.19-stable tree
[email protected]
maintainerThe patch below does not apply to the 5.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From fa30a81f255a56cccd89552cd6ce7ea6e8d8acc4 Mon Sep 17 00:00:00 2001
From: Steve French <[email protected]>
Date: Tue, 23 Aug 2022 14:07:41 +0100
Subject: [PATCH] smb3: fix temporary data corruption in collapse range
collapse range doesn't discard the affected cached region so can risk temporarily corrupting the file data. This fixes xfstest generic/031
I also decided to merge a minor cleanup to this into the same patch (avoiding rereading inode size repeatedly unnecessarily) to make it clearer.
fs/cifs/smb2ops.c +16 -10
@@ -3669,41 +3669,47 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon, {int rc;unsigned int xid; -struct inode *inode; +struct inode *inode =file_inode (file);struct cifsFileInfo *cfile = file->private_data; -struct cifsInodeInfo *cifsi; +struct cifsInodeInfo *cifsi =CIFS_I (inode);__le64 eof; +loff_t old_eof; xid =get_xid (); - inode =d_inode (cfile->dentry); - cifsi =CIFS_I (inode); +inode_lock (inode); -if (off >=i_size_read (inode) || - off + len >=i_size_read (inode)) { + old_eof =i_size_read (inode); +if ((off >= old_eof) || + off + len >= old_eof) { rc = -EINVAL ; goto out; } +filemap_invalidate_lock (inode->i_mapping);filemap_write_and_wait (inode->i_mapping); +truncate_pagecache_range (inode, off, old_eof); rc =smb2_copychunk_range (xid, cfile, cfile, off + len, -i_size_read (inode) - off - len, off); + old_eof - off - len, off);if (rc <0 ) - goto out; + goto out_2; - eof =cpu_to_le64 (i_size_read (inode) - len); + eof =cpu_to_le64 (old_eof - len); rc =SMB2_set_eof (xid, tcon, cfile->fid.persistent_fid, cfile->fid.volatile_fid, cfile->pid, &eof);if (rc <0 ) - goto out; + goto out_2; rc =0 ; cifsi->server_eof =i_size_read (inode) - len;truncate_setsize (inode, cifsi->server_eof);fscache_resize_cookie (cifs_inode_cookie (inode), cifsi->server_eof); +out_2: +filemap_invalidate_unlock (inode->i_mapping); out: +inode_unlock (inode);free_xid (xid);return rc; }