All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Masami Hiramatsu <mhiramat@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Al Viro <viro@zeniv.linux.org.uk>,
	"Steven Rostedt (Google)" <rostedt@goodmis.org>
Subject: [PATCH 6.6 08/30] eventfs: Use simple_recursive_removal() to clean up dentries
Date: Mon,  6 Nov 2023 14:03:26 +0100	[thread overview]
Message-ID: <20231106130258.225254857@linuxfoundation.org> (raw)
In-Reply-To: <20231106130257.903265688@linuxfoundation.org>

6.6-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

commit 407c6726ca71b33330d2d6345d9ea7ebc02575e9 upstream

Looking at how dentry is removed via the tracefs system, I found that
eventfs does not do everything that it did under tracefs. The tracefs
removal of a dentry calls simple_recursive_removal() that does a lot more
than a simple d_invalidate().

As it should be a requirement that any eventfs_inode that has a dentry, so
does its parent. When removing a eventfs_inode, if it has a dentry, a call
to simple_recursive_removal() on that dentry should clean up all the
dentries underneath it.

Add WARN_ON_ONCE() to check for the parent having a dentry if any children
do.

Link: https://lore.kernel.org/all/20231101022553.GE1957730@ZenIV/
Link: https://lkml.kernel.org/r/20231101172650.552471568@goodmis.org

Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Fixes: 5bdcd5f5331a2 ("eventfs: Implement removal of meta data from eventfs")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/tracefs/event_inode.c |   71 +++++++++++++++++++++--------------------------
 1 file changed, 33 insertions(+), 38 deletions(-)

--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -54,12 +54,10 @@ struct eventfs_file {
 	/*
 	 * Union - used for deletion
 	 * @llist:	for calling dput() if needed after RCU
-	 * @del_list:	list of eventfs_file to delete
 	 * @rcu:	eventfs_file to delete in RCU
 	 */
 	union {
 		struct llist_node	llist;
-		struct list_head	del_list;
 		struct rcu_head		rcu;
 	};
 	void				*data;
@@ -276,7 +274,6 @@ static void free_ef(struct eventfs_file
  */
 void eventfs_set_ef_status_free(struct tracefs_inode *ti, struct dentry *dentry)
 {
-	struct tracefs_inode *ti_parent;
 	struct eventfs_inode *ei;
 	struct eventfs_file *ef;
 
@@ -297,10 +294,6 @@ void eventfs_set_ef_status_free(struct t
 
 	mutex_lock(&eventfs_mutex);
 
-	ti_parent = get_tracefs(dentry->d_parent->d_inode);
-	if (!ti_parent || !(ti_parent->flags & TRACEFS_EVENT_INODE))
-		goto out;
-
 	ef = dentry->d_fsdata;
 	if (!ef)
 		goto out;
@@ -873,30 +866,29 @@ static void unhook_dentry(struct dentry
 {
 	if (!dentry)
 		return;
-
-	/* Keep the dentry from being freed yet (see eventfs_workfn()) */
+	/*
+	 * Need to add a reference to the dentry that is expected by
+	 * simple_recursive_removal(), which will include a dput().
+	 */
 	dget(dentry);
 
-	dentry->d_fsdata = NULL;
-	d_invalidate(dentry);
-	mutex_lock(&eventfs_mutex);
-	/* dentry should now have at least a single reference */
-	WARN_ONCE((int)d_count(dentry) < 1,
-		  "dentry %px (%s) less than one reference (%d) after invalidate\n",
-		  dentry, dentry->d_name.name, d_count(dentry));
-	mutex_unlock(&eventfs_mutex);
+	/*
+	 * Also add a reference for the dput() in eventfs_workfn().
+	 * That is required as that dput() will free the ei after
+	 * the SRCU grace period is over.
+	 */
+	dget(dentry);
 }
 
 /**
  * eventfs_remove_rec - remove eventfs dir or file from list
  * @ef: eventfs_file to be removed.
- * @head: to create list of eventfs_file to be deleted
  * @level: to check recursion depth
  *
  * The helper function eventfs_remove_rec() is used to clean up and free the
  * associated data from eventfs for both of the added functions.
  */
-static void eventfs_remove_rec(struct eventfs_file *ef, struct list_head *head, int level)
+static void eventfs_remove_rec(struct eventfs_file *ef, int level)
 {
 	struct eventfs_file *ef_child;
 
@@ -916,14 +908,16 @@ static void eventfs_remove_rec(struct ev
 		/* search for nested folders or files */
 		list_for_each_entry_srcu(ef_child, &ef->ei->e_top_files, list,
 					 lockdep_is_held(&eventfs_mutex)) {
-			eventfs_remove_rec(ef_child, head, level + 1);
+			eventfs_remove_rec(ef_child, level + 1);
 		}
 	}
 
 	ef->is_freed = 1;
 
+	unhook_dentry(ef->dentry);
+
 	list_del_rcu(&ef->list);
-	list_add_tail(&ef->del_list, head);
+	call_srcu(&eventfs_srcu, &ef->rcu, free_rcu_ef);
 }
 
 /**
@@ -934,28 +928,22 @@ static void eventfs_remove_rec(struct ev
  */
 void eventfs_remove(struct eventfs_file *ef)
 {
-	struct eventfs_file *tmp;
-	LIST_HEAD(ef_del_list);
+	struct dentry *dentry;
 
 	if (!ef)
 		return;
 
-	/*
-	 * Move the deleted eventfs_inodes onto the ei_del_list
-	 * which will also set the is_freed value. Note, this has to be
-	 * done under the eventfs_mutex, but the deletions of
-	 * the dentries must be done outside the eventfs_mutex.
-	 * Hence moving them to this temporary list.
-	 */
 	mutex_lock(&eventfs_mutex);
-	eventfs_remove_rec(ef, &ef_del_list, 0);
+	dentry = ef->dentry;
+	eventfs_remove_rec(ef, 0);
 	mutex_unlock(&eventfs_mutex);
 
-	list_for_each_entry_safe(ef, tmp, &ef_del_list, del_list) {
-		unhook_dentry(ef->dentry);
-		list_del(&ef->del_list);
-		call_srcu(&eventfs_srcu, &ef->rcu, free_rcu_ef);
-	}
+	/*
+	 * If any of the ei children has a dentry, then the ei itself
+	 * must have a dentry.
+	 */
+	if (dentry)
+		simple_recursive_removal(dentry, NULL);
 }
 
 /**
@@ -966,6 +954,8 @@ void eventfs_remove(struct eventfs_file
  */
 void eventfs_remove_events_dir(struct dentry *dentry)
 {
+	struct eventfs_file *ef_child;
+	struct eventfs_inode *ei;
 	struct tracefs_inode *ti;
 
 	if (!dentry || !dentry->d_inode)
@@ -975,6 +965,11 @@ void eventfs_remove_events_dir(struct de
 	if (!ti || !(ti->flags & TRACEFS_EVENT_INODE))
 		return;
 
-	d_invalidate(dentry);
-	dput(dentry);
+	mutex_lock(&eventfs_mutex);
+	ei = ti->private;
+	list_for_each_entry_srcu(ef_child, &ei->e_top_files, list,
+				 lockdep_is_held(&eventfs_mutex)) {
+		eventfs_remove_rec(ef_child, 0);
+	}
+	mutex_unlock(&eventfs_mutex);
 }



  parent reply	other threads:[~2023-11-06 13:09 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-06 13:03 [PATCH 6.6 00/30] 6.6.1-rc1 review Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 01/30] drm/amd/display: Dont use fsleep for PSR exit waits Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 02/30] power: supply: core: Use blocking_notifier_call_chain to avoid RCU complaint Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 03/30] perf evlist: Avoid frequency mode for the dummy event Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 04/30] tracing: Have trace_event_file have ref counters Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 05/30] eventfs: Remove "is_freed" union with rcu head Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 06/30] eventfs: Save ownership and mode Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 07/30] eventfs: Delete eventfs_inode when the last dentry is freed Greg Kroah-Hartman
2023-11-06 13:03 ` Greg Kroah-Hartman [this message]
2023-11-06 13:03 ` [PATCH 6.6 09/30] ALSA: usb-audio: add quirk flag to enable native DSD for McIntosh devices Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 10/30] PCI: Prevent xHCI driver from claiming AMD VanGogh USB3 DRD device Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 11/30] usb: storage: set 1.50 as the lower bcdDevice for older "Super Top" compatibility Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 12/30] usb: typec: tcpm: Add additional checks for contaminant Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 13/30] usb: typec: tcpm: Fix NULL pointer dereference in tcpm_pd_svdm() Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 14/30] usb: raw-gadget: properly handle interrupted requests Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 15/30] Bluetooth: hci_bcm4377: Mark bcm4378/bcm4387 as BROKEN_LE_CODED Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 16/30] tty: n_gsm: fix race condition in status line change on dead connections Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 17/30] tty: 8250: Remove UC-257 and UC-431 Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 18/30] tty: 8250: Add support for additional Brainboxes UC cards Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 19/30] tty: 8250: Add support for Brainboxes UP cards Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 20/30] tty: 8250: Add support for Intashield IS-100 Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 21/30] tty: 8250: Fix port count of PX-257 Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 22/30] tty: 8250: Fix up PX-803/PX-857 Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 23/30] tty: 8250: Add support for additional Brainboxes PX cards Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 24/30] tty: 8250: Add support for Intashield IX cards Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 25/30] tty: 8250: Add Brainboxes Oxford Semiconductor-based quirks Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 26/30] dt-bindings: serial: rs485: Add rs485-rts-active-high Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 27/30] misc: pci_endpoint_test: Add deviceID for J721S2 PCIe EP device support Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 28/30] serial: core: Fix runtime PM handling for pending tx Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 29/30] ALSA: hda: intel-dsp-config: Fix JSL Chromebook quirk detection Greg Kroah-Hartman
2023-11-06 13:03 ` [PATCH 6.6 30/30] ASoC: SOF: sof-pci-dev: Fix community key " Greg Kroah-Hartman
2023-11-06 17:25 ` [PATCH 6.6 00/30] 6.6.1-rc1 review SeongJae Park
2023-11-06 18:21 ` Florian Fainelli
2023-11-06 19:01 ` Allen Pais
2023-11-07  2:12 ` Rudi Heitbaum
2023-11-07  5:04 ` Bagas Sanjaya
2023-11-07  8:47 ` Ron Economos
2023-11-07 11:02 ` Takeshi Ogasawara
2023-11-07 15:27 ` Shuah Khan
2023-11-07 17:15 ` Ricardo B. Marliere
2023-11-07 18:55 ` Guenter Roeck
2023-11-07 19:18 ` Naresh Kamboju
2023-11-08  9:50 ` Jon Hunter

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=20231106130258.225254857@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=mark.rutland@arm.com \
    --cc=mhiramat@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=rostedt@goodmis.org \
    --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.