From: Edvard Conrad <edvard@tuta.io>
To: Amir Goldstein <amir73il@gmail.com>,
Christian Brauner <brauner@kernel.org>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
Alexander Viro <viro@zeniv.linux.org.uk>, Jan Kara <jack@suse.cz>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"linux-unionfs@vger.kernel.org" <linux-unionfs@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"stable@vger.kernel.org" <stable@vger.kernel.org>,
Edvard Conrad <edvard@tuta.io>
Subject: Re: [PATCH v3] fs: let backing files inherit FMODE_NONOTIFY from the user file
Date: Tue, 3 Nov 2026 14:01:29 +0100 (CET) [thread overview]
Message-ID: <P5WV0VL--F-9@tuta.io> (raw)
In-Reply-To: <CAOQ4uxh67+vs0mr-Lxmwz9-N+F8m29WUNz+8qFLLDpOVYB7=vg@mail.gmail.com>
On Mon, Nov 2, 2026 at 1:34 PM Amir Goldstein <amir73il@gmail.com> wrote:
> Good catch!
> Please test the attached v2 patch and post the new test cases.
v2 fixes the merged directory. An impure directory still deadlocks the
same way: ovl_iterate_real() reads it through ovl_cache_get_impure() and
ovl_dir_read_impure(), which v2 leaves without the user file, so
ovl_dir_read() opens the upper directory with plain ovl_path_open():
fanotify_handle_event
fsnotify
fsnotify_open_perm_and_set_mode
do_dentry_open
vfs_open
dentry_open
ovl_iterate_real
ovl_iterate
iterate_dir
__x64_sys_getdents64
That takes an upper-only directory that a lower file was renamed into,
on layers that share a filesystem, so ovl_need_adjust_d_ino() sends it
to ovl_iterate_real(). Passing the file down the same way v2 does for
the merged case fixes it for me, on top of v2:
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -670,7 +670,7 @@ static bool ovl_fill_plain(struct dir_context *ctx, const char *name,
}
static int ovl_dir_read_impure(const struct path *path, struct list_head *list,
- struct rb_root *root)
+ struct rb_root *root, const struct file *user_file)
{
int err;
struct path realpath;
@@ -678,6 +678,7 @@ static int ovl_dir_read_impure(const struct path *path, struct list_head *list,
struct ovl_readdir_data rdd = {
.ctx.actor = ovl_fill_plain,
.ctx.count = INT_MAX,
+ .user_file = user_file,
.list = list,
.root = root,
};
@@ -714,9 +715,10 @@ static int ovl_dir_read_impure(const struct path *path, struct list_head *list,
return 0;
}
-static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path)
+static struct ovl_dir_cache *ovl_cache_get_impure(struct file *file)
{
int res;
+ const struct path *path = &file->f_path;
struct dentry *dentry = path->dentry;
struct inode *inode = d_inode(dentry);
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
@@ -735,7 +737,7 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path)
return ERR_PTR(-ENOMEM);
cache->is_refcounted = false;
- res = ovl_dir_read_impure(path, &cache->entries, &cache->root);
+ res = ovl_dir_read_impure(path, &cache->entries, &cache->root, file);
if (res) {
ovl_cache_free(&cache->entries);
kfree(cache);
@@ -856,7 +858,7 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
dput(parent);
if (ovl_is_impure_dir(file)) {
- rdt.cache = ovl_cache_get_impure(&file->f_path);
+ rdt.cache = ovl_cache_get_impure(file);
if (IS_ERR(rdt.cache))
return PTR_ERR(rdt.cache);
}
Results in a VM on 6b4b543fa18, each kernel run once and with -i 2,
with the backing filesystem marked:
file dir merged dir impure dir
listed listed
+ c3d355f427ce PASS FAIL FAIL FAIL
+ your v1 PASS PASS FAIL FAIL
+ your v2 PASS PASS PASS FAIL
+ v2 and the diff above PASS PASS PASS PASS
The new cases are posted on top of the directory cases:
https://lore.kernel.org/ltp/P5WKBbq--F-9@tuta.io/
Thanks,
Edvard
next prev parent reply other threads:[~2026-11-03 13:01 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 21:18 [PATCH v3] fs: let backing files inherit FMODE_NONOTIFY from the user file Edvard Conrad
2026-10-30 9:26 ` Amir Goldstein
2026-10-30 14:57 ` Christian Brauner
2026-10-30 17:13 ` Amir Goldstein
2026-11-02 10:57 ` Edvard Conrad
2026-11-02 12:34 ` Amir Goldstein
2026-11-03 13:01 ` Edvard Conrad [this message]
2026-11-03 14:46 ` Amir Goldstein
2026-11-03 21:15 ` Edvard Conrad
2026-10-30 14:58 ` Christian Brauner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=P5WV0VL--F-9@tuta.io \
--to=edvard@tuta.io \
--cc=amir73il@gmail.com \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=stable@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.