On Mon, Apr 26, 2021 at 6:20 PM Amir Goldstein <amir73il@xxxxxxxxx> wrote: > > On the first getdents call, ovl_iterate() populates the readdir cache > with a list of entries, but for upper entries with origin lower inode, > p->ino remains zero. > > Following getdents calls traverse the readdir cache list and call > ovl_cache_update_ino() for entries with zero p->ino to lookup the entry > in the overlay and return d_ino that is consistent with st_ino. > > If the upper file was unlinked between the first getdents call and the > getdents call that lists the file entry, ovl_cache_update_ino() will not > find the entry and fall back to setting d_ino to the upper real st_ino, > which is inconsistent with how this object was presented to users. > > Instead of listing a stale entry with inconsistent d_ino, simply skip > the stale entry, which is better for users. > Miklos, I forgot to follow up on this patch. Upstream xfstest overlay/077 is failing without this patch. Please add: Link: https://lore.kernel.org/fstests/CAOQ4uxgR_cLnC_vdU5=seP3fwqVkuZM_-WfD6maFTMbMYq=a9w@xxxxxxxxxxxxxx/ Thanks, Amir. > Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> > --- > fs/overlayfs/readdir.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c > index cc1e80257064..10b7780e4bdc 100644 > --- a/fs/overlayfs/readdir.c > +++ b/fs/overlayfs/readdir.c > @@ -481,6 +481,8 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p) > } > this = lookup_one_len(p->name, dir, p->len); > if (IS_ERR_OR_NULL(this) || !this->d_inode) { > + /* Mark a stale entry */ > + p->is_whiteout = true; > if (IS_ERR(this)) { > err = PTR_ERR(this); > this = NULL; > @@ -776,6 +778,9 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) > if (err) > goto out; > } > + } > + /* ovl_cache_update_ino() sets is_whiteout on stale entry */ > + if (!p->is_whiteout) { > if (!dir_emit(ctx, p->name, p->len, p->ino, p->type)) > break; > } > -- > 2.25.1 >