lkml.org 
[lkml]   [2022]   [Aug]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.19 0304/1157] erofs: update ctx->pos for every emitted dirent
    Date
    From: Hongnan Li <hongnan.li@linux.alibaba.com>

    [ Upstream commit ecce9212d0fd7a2d4a4998f0c4623a66887e14c8 ]

    erofs_readdir update ctx->pos after filling a batch of dentries
    and it may cause dir/files duplication for NFS readdirplus which
    depends on ctx->pos to fill dir correctly. So update ctx->pos for
    every emitted dirent in erofs_fill_dentries to fix it.

    Also fix the update of ctx->pos when the initial file position has
    exceeded nameoff.

    Fixes: 3e917cc305c6 ("erofs: make filesystem exportable")
    Signed-off-by: Hongnan Li <hongnan.li@linux.alibaba.com>
    Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com>
    Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
    Reviewed-by: Chao Yu <chao@kernel.org>
    Link: https://lore.kernel.org/r/20220722082732.30935-1-jefflexu@linux.alibaba.com
    Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/erofs/dir.c | 16 +++++++---------
    1 file changed, 7 insertions(+), 9 deletions(-)

    diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c
    index 18e59821c597..47c85f1b80d8 100644
    --- a/fs/erofs/dir.c
    +++ b/fs/erofs/dir.c
    @@ -22,10 +22,9 @@ static void debug_one_dentry(unsigned char d_type, const char *de_name,
    }

    static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
    - void *dentry_blk, unsigned int *ofs,
    + void *dentry_blk, struct erofs_dirent *de,
    unsigned int nameoff, unsigned int maxsize)
    {
    - struct erofs_dirent *de = dentry_blk + *ofs;
    const struct erofs_dirent *end = dentry_blk + nameoff;

    while (de < end) {
    @@ -59,9 +58,8 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
    /* stopped by some reason */
    return 1;
    ++de;
    - *ofs += sizeof(struct erofs_dirent);
    + ctx->pos += sizeof(struct erofs_dirent);
    }
    - *ofs = maxsize;
    return 0;
    }

    @@ -95,7 +93,7 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
    "invalid de[0].nameoff %u @ nid %llu",
    nameoff, EROFS_I(dir)->nid);
    err = -EFSCORRUPTED;
    - goto skip_this;
    + break;
    }

    maxsize = min_t(unsigned int,
    @@ -106,17 +104,17 @@ static int erofs_readdir(struct file *f, struct dir_context *ctx)
    initial = false;

    ofs = roundup(ofs, sizeof(struct erofs_dirent));
    + ctx->pos = blknr_to_addr(i) + ofs;
    if (ofs >= nameoff)
    goto skip_this;
    }

    - err = erofs_fill_dentries(dir, ctx, de, &ofs,
    + err = erofs_fill_dentries(dir, ctx, de, (void *)de + ofs,
    nameoff, maxsize);
    -skip_this:
    - ctx->pos = blknr_to_addr(i) + ofs;
    -
    if (err)
    break;
    +skip_this:
    + ctx->pos = blknr_to_addr(i) + maxsize;
    ++i;
    ofs = 0;
    }
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-16 01:19    [W:4.021 / U:0.988 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site