Linux filesystem development
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	 Chris Mason <mason@kernel.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	 Jan Kara <jack@suse.cz>, Jeff Layton <jlayton@kernel.org>,
	 Aleksa Sarai <cyphar@cyphar.com>,
	Amir Goldstein <amir73il@gmail.com>,
	 bpf@vger.kernel.org,
	"Christian Brauner (Amutable)" <brauner@kernel.org>,
	 stable@vger.kernel.org
Subject: [PATCH 14/17] fsnotify: detach the connector before destroying its marks
Date: Wed, 30 Sep 2026 15:32:06 +0200	[thread overview]
Message-ID: <20260930-work-mount-fixes-3-v1-14-be34c83956ae@kernel.org> (raw)
In-Reply-To: <20260930-work-mount-fixes-3-v1-0-be34c83956ae@kernel.org>

fsnotify_destroy_marks() removes every mark of an object that goes away.
It walks the mark list of the connector and has to drop the connector
lock around fsnotify_destroy_mark() since that sleeps. Afterwards it
continues from the mark it just destroyed. That mark stays on the list
because the function holds a reference to it. But while the lock is
dropped fsnotify_add_mark_list() can add a mark to the very same
connector and put it in front of the current one when group priority
dictates. fsnotify_grab_connector() hands out the connector until it is
detached and it only gets detached after the walk.

So the walk never sees that mark. The connector is detached from the
object with the new mark still attached to it. It never receives an
event nor IN_IGNORED. For inotify that's a watch descriptor that never
reports anything and doesn't show up in fdinfo either:

  wd1 = inotify_add_watch(/proc/self/fd/6) = 2
  events after the unlink:
    wd 1 mask 0x400 IN_DELETE_SELF
    wd 1 mask 0x8000 IN_IGNORED
  events after write() to the file:
    (none)

Detach the connector from the object before the marks are destroyed.
fsnotify_grab_connector() refuses a detached connector so a mark added
from then on gets a connector of its own. Nothing during the destruction
needs the connector. The inode reference of the connector is dropped
after the marks are gone as before.

Fixes: 6b3f05d24d35 ("fsnotify: Detach mark from object list when last reference is dropped")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 fs/notify/mark.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index b2640d836a71..f6891d39e42f 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -1112,6 +1112,16 @@ void fsnotify_destroy_marks(fsnotify_connp_t *connp)
 	conn = fsnotify_grab_connector(connp);
 	if (!conn)
 		return;
+	/*
+	 * Detach the connector from the object first. Once conn->lock is
+	 * dropped a mark could be added in front of the one we're at and the
+	 * walk would miss it. fsnotify_grab_connector() refuses a detached
+	 * connector so any mark added from now on gets a connector of its
+	 * own. This also stops pinning the inode until all mark references
+	 * get dropped. It would lead to strange results such as delaying
+	 * inode deletion or blocking unmount.
+	 */
+	objp = fsnotify_detach_connector_from_object(conn, &type);
 	/*
 	 * We have to be careful since we can race with e.g.
 	 * fsnotify_clear_marks_by_group() and once we drop the conn->lock, the
@@ -1128,12 +1138,6 @@ void fsnotify_destroy_marks(fsnotify_connp_t *connp)
 		fsnotify_destroy_mark(mark, mark->group);
 		spin_lock(&conn->lock);
 	}
-	/*
-	 * Detach list from object now so that we don't pin inode until all
-	 * mark references get dropped. It would lead to strange results such
-	 * as delaying inode deletion or blocking unmount.
-	 */
-	objp = fsnotify_detach_connector_from_object(conn, &type);
 	spin_unlock(&conn->lock);
 	if (old_mark)
 		fsnotify_put_mark(old_mark);

-- 
2.53.0


  parent reply	other threads:[~2026-09-30 13:32 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30 13:31 [PATCH 00/17] mount: more bugfixes, the Oprah edition Christian Brauner
2026-09-30 13:31 ` [PATCH 01/17] namespace: queue a mount only once for mount notifications Christian Brauner
2026-09-30 13:31 ` [PATCH 02/17] namespace: check a submount for references right before unmounting it Christian Brauner
2026-09-30 13:31 ` [PATCH 03/17] selftests/filesystems: check that a busy submount survives a synchronous umount Christian Brauner
2026-09-30 13:31 ` [PATCH 04/17] namespace: check a recursive bind mount for mount namespace loops Christian Brauner
2026-09-30 13:31 ` [PATCH 05/17] selftests/filesystems: check that a recursive bind mount can't pin the caller's mount namespace Christian Brauner
2026-09-30 13:31 ` [PATCH 06/17] namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE Christian Brauner
2026-09-30 13:31 ` [PATCH 07/17] selftests/filesystems: check that OPEN_TREE_NAMESPACE keeps mounts covered Christian Brauner
2026-09-30 13:32 ` [PATCH 08/17] namespace: look at the topmost mount for a mount namespace file Christian Brauner
2026-09-30 13:32 ` [PATCH 09/17] selftests/filesystems: check that a mount namespace file on top doesn't bury a mount Christian Brauner
2026-09-30 13:32 ` [PATCH 10/17] namespace: check the mounts before reading their parents in pivot_root() Christian Brauner
2026-09-30 13:32 ` [PATCH 11/17] namespace: don't reconfigure internal superblocks via remount and umount Christian Brauner
2026-09-30 13:32 ` [PATCH 12/17] selftests/filesystems: check that the nullfs root can't be reconfigured Christian Brauner
2026-09-30 13:32 ` [PATCH 13/17] namespace: remove the fsnotify marks of a mount namespace in process context Christian Brauner
2026-09-30 15:07   ` Amir Goldstein
2026-09-30 13:32 ` Christian Brauner [this message]
2026-10-01  9:31   ` [PATCH 14/17] fsnotify: detach the connector before destroying its marks Christian Brauner
2026-10-01 10:58     ` Amir Goldstein
2026-10-01 12:06       ` Christian Brauner
2026-09-30 13:32 ` [PATCH 15/17] dcache: don't put a mountpoint on a dentry that's being removed Christian Brauner
2026-09-30 13:32 ` [PATCH 16/17] unshare: don't drop active namespace references that were never taken Christian Brauner
2026-09-30 13:32 ` [PATCH 17/17] namespace: don't let a pseudo dentry become the root of a mount 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=20260930-work-mount-fixes-3-v1-14-be34c83956ae@kernel.org \
    --to=brauner@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=cyphar@cyphar.com \
    --cc=jack@suse.cz \
    --cc=jlayton@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mason@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.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