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 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®