[PATCH v2] erofs: update ctx->pos for every emitted dirent
hongnanLi
hongnan.li at linux.alibaba.com
Mon Jun 20 19:37:07 AEST 2022
on 2022/6/19 8:19, Chao Yu wrote:
> On 2022/6/9 11:40, Hongnan Li wrote:
>> 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.
>>
>> Fixes: 3e917cc305c6 ("erofs: make filesystem exportable")
>> Signed-off-by: Hongnan Li <hongnan.li at linux.alibaba.com>
>> ---
>> fs/erofs/dir.c | 20 ++++++++++----------
>> 1 file changed, 10 insertions(+), 10 deletions(-)
>>
>> diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c
>> index 18e59821c597..94ef5287237a 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,19 @@ static int erofs_readdir(struct file *f, struct
>> dir_context *ctx)
>> initial = false;
>> ofs = roundup(ofs, sizeof(struct erofs_dirent));
>> - if (ofs >= nameoff)
>> + if (ofs >= nameoff) {
>> + ctx->pos = blknr_to_addr(i) + ofs;
>> goto skip_this;
>> + }
>> }
>> - err = erofs_fill_dentries(dir, ctx, de, &ofs,
>> - nameoff, maxsize);
>> -skip_this:
>> ctx->pos = blknr_to_addr(i) + ofs;
>
> Why updating ctx->pos before erofs_fill_dentries()?
>
> Thanks,
It’s to ensure the ctx->pos is correct and up to date in
erofs_fill_dentries() so that we can update ctx->pos instead of ofs for
every emitted dirent.
>
>> -
>> + err = erofs_fill_dentries(dir, ctx, de, (void *)de + ofs,
>> + nameoff, maxsize);
>> if (err)
>> break;
>> + ctx->pos = blknr_to_addr(i) + maxsize;
>> +skip_this:
>> ++i;
>> ofs = 0;
>> }
More information about the Linux-erofs
mailing list