Re: [PATCH] cifs: truncate the inode and mapping when we simulate fcollapse

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx> 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@xxxxxxxxxx>
> Reported-by: kernel test robot <lkp@xxxxxxxxx>
> Signed-off-by: Ronnie Sahlberg <lsahlber@xxxxxxxxxx>
> ---
>  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



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux