mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®