ovl_check_redirect() clears d->absolute_redirect before it checks that the path element has a redirect xattr. An element without one, such as an intermediate directory in a lower layer, then clears the flag set by the absolute redirect of a metacopy file found in a higher layer. The lookup of the data in the data-only layers is not deferred any more and the lookup fails with -EIO: # l2/f: metacopy, redirect "/dir/file"; l1/dir/ exists, no "file" mount -t overlay none -o metacopy=on,redirect_dir=on,\ lowerdir+=l2,lowerdir+=l1,datadir+=data m cat m/f # Input/output error Set d->absolute_redirect only when a redirect xattr was read. Fixes: 5436ab0a864e ("ovl: implement lookup in data-only layers") Link: https://sashiko.dev/#/bug/linux-2cc24e0b-fbdc-4cf1-aded-cfd19c2918ee Signed-off-by: Giuseppe Scrivano --- fs/overlayfs/namei.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index ca899fdfaafd..096e342f7e9f 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -39,13 +39,12 @@ static int ovl_check_redirect(const struct path *path, struct ovl_lookup_data *d char *buf; struct ovl_fs *ofs = OVL_FS(d->sb); - d->absolute_redirect = false; buf = ovl_get_redirect_xattr(ofs, path, prelen + strlen(post)); if (IS_ERR_OR_NULL(buf)) return PTR_ERR(buf); - if (buf[0] == '/') { - d->absolute_redirect = true; + d->absolute_redirect = buf[0] == '/'; + if (d->absolute_redirect) { /* * One of the ancestor path elements in an absolute path * lookup in ovl_lookup_layer() could have been opaque and -- 2.56.0