[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-cifs
Subject: Re: [PATCH] cifs: truncate the inode and mapping when we simulate fcollapse
From: Steve French <smfrench () gmail ! com>
Date: 2022-02-23 2:44:02
Message-ID: CAH2r5mth2tMZq5k2Z89aSC9Tv1+k-WWN9a_5TGBJ5kTQGDWYUg () mail ! gmail ! com
[Download RAW message or body]
Tentatively merged into cifs-2.6.git for-next pending review and testing
On Tue, Feb 22, 2022 at 7:14 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> RHBZ:1997367
>
> When we collapse a range in smb3_collapse_range() we must make sure
> we update the inode size and pagecache accordingly.
>
> If not, both inode size and pagecahce may be stale until it is refreshed.
>
> This can be demonstrated for the inode size by running :
>
> xfs_io -i -f -c "truncate 320k" -c "fcollapse 64k 128k" -c "fiemap -v" \
> /mnt/testfile
>
> where we can see the result of stale data in the fiemap output.
> The third line of the output is wrong, all this data should be truncated.
>
> EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS
> 0: [0..127]: hole 128
> 1: [128..383]: 128..383 256 0x1
> 2: [384..639]: hole 256
>
> And the correct output, when the inode size has been updated correctly should
> look like this:
>
> EXT: FILE-OFFSET BLOCK-RANGE TOTAL FLAGS
> 0: [0..127]: hole 128
> 1: [128..383]: 128..383 256 0x1
>
> Reported-by: Xiaoli Feng <xifeng@redhat.com>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
> fs/cifs/smb2ops.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index af5d0830bc8a..891b11576e55 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -25,6 +25,7 @@
> #include "smb2glob.h"
> #include "cifs_ioctl.h"
> #include "smbdirect.h"
> +#include "fscache.h"
> #include "fs_context.h"
>
> /* Change credits for different ops and return the total number of credits */
> @@ -3887,29 +3888,38 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
> {
> int rc;
> unsigned int xid;
> + struct inode *inode;
> struct cifsFileInfo *cfile = file->private_data;
> + struct cifsInodeInfo *cifsi;
> __le64 eof;
>
> xid = get_xid();
>
> - if (off >= i_size_read(file->f_inode) ||
> - off + len >= i_size_read(file->f_inode)) {
> + inode = d_inode(cfile->dentry);
> + cifsi = CIFS_I(inode);
> +
> + if (off >= i_size_read(inode) ||
> + off + len >= i_size_read(inode)) {
> rc = -EINVAL;
> goto out;
> }
>
> rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
> - i_size_read(file->f_inode) - off - len, off);
> + i_size_read(inode) - off - len, off);
> if (rc < 0)
> goto out;
>
> - eof = cpu_to_le64(i_size_read(file->f_inode) - len);
> + eof = cpu_to_le64(i_size_read(inode) - len);
> rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
> cfile->fid.volatile_fid, cfile->pid, &eof);
> if (rc < 0)
> goto out;
>
> 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:
> free_xid(xid);
> return rc;
> --
> 2.30.2
>
--
Thanks,
Steve
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic