All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ajay Kaher <akaher@vmware.com>
To: rostedt@goodmis.org, shuah@kernel.org, mhiramat@kernel.org
Cc: chinglinyu@google.com, linux-kernel@vger.kernel.org,
	linux-kselftest@vger.kernel.org,
	linux-trace-kernel@vger.kernel.org, lkp@intel.com,
	namit@vmware.com, oe-lkp@lists.linux.dev, akaher@vmware.com,
	amakhalov@vmware.com, er.ajay.kaher@gmail.com,
	srivatsa@csail.mit.edu, tkundu@vmware.com,
	vsirnapalli@vmware.com
Subject: [PATCH v4 07/10] eventfs: Implement eventfs lookup, read, open functions
Date: Thu, 13 Jul 2023 17:03:21 +0530	[thread overview]
Message-ID: <1689248004-8158-8-git-send-email-akaher@vmware.com> (raw)
In-Reply-To: <1689248004-8158-1-git-send-email-akaher@vmware.com>

Adding following inode_operations, file_operations and helper functions to
eventfs:
dcache_dir_open_wrapper()
eventfs_root_lookup()
eventfs_release()
eventfs_set_ef_status_free()
eventfs_post_create_dir()

inode_operations, file_operations will be called from vfs.

Signed-off-by: Ajay Kaher <akaher@vmware.com>
Co-developed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Tested-by: Ching-lin Yu <chinglinyu@google.com>
---
 fs/tracefs/event_inode.c | 194 ++++++++++++++++++++++++++++++++++++++-
 include/linux/tracefs.h  |   2 +
 2 files changed, 194 insertions(+), 2 deletions(-)

diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 34b5d3d8005b..7167340ac29e 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -67,7 +67,7 @@ DEFINE_STATIC_SRCU(eventfs_srcu);
  * If tracefs is not enabled in the kernel, the value -%ENODEV will be
  * returned.
  */
-struct dentry *create_file(const char *name, umode_t mode,
+static struct dentry *create_file(const char *name, umode_t mode,
 				  struct dentry *parent, void *data,
 				  const struct file_operations *fop)
 {
@@ -123,7 +123,7 @@ struct dentry *create_file(const char *name, umode_t mode,
  * If tracefs is not enabled in the kernel, the value -%ENODEV will be
  * returned.
  */
-struct dentry *create_dir(const char *name, umode_t mode,
+static struct dentry *create_dir(const char *name, umode_t mode,
 				 struct dentry *parent, void *data,
 				 const struct file_operations *fop,
 				 const struct inode_operations *iop)
@@ -157,10 +157,200 @@ struct dentry *create_dir(const char *name, umode_t mode,
 	return eventfs_end_creating(dentry);
 }
 
+/**
+ * eventfs_set_ef_status_free - set the ef->status to free
+ * @dentry: dentry who's status to be freed
+ *
+ * eventfs_set_ef_status_free will be called if no more
+ * reference remains
+ */
+void eventfs_set_ef_status_free(struct dentry *dentry)
+{
+	struct tracefs_inode *ti_parent;
+	struct eventfs_file *ef;
+
+	ti_parent = get_tracefs(dentry->d_parent->d_inode);
+	if (!ti_parent || !(ti_parent->flags & TRACEFS_EVENT_INODE))
+		return;
+
+	ef = dentry->d_fsdata;
+	if (!ef)
+		return;
+	ef->created = false;
+	ef->dentry = NULL;
+}
+
+/**
+ * eventfs_post_create_dir - post create dir routine
+ * @ef: eventfs_file of recently created dir
+ *
+ * Files with-in eventfs dir should know dentry of parent dir
+ */
+static void eventfs_post_create_dir(struct eventfs_file *ef)
+{
+	struct eventfs_file *ef_child;
+	struct tracefs_inode *ti;
+
+	/* srcu lock already held */
+	/* fill parent-child relation */
+	list_for_each_entry_srcu(ef_child, &ef->ei->e_top_files, list,
+				 srcu_read_lock_held(&eventfs_srcu)) {
+		ef_child->d_parent = ef->dentry;
+	}
+
+	ti = get_tracefs(ef->dentry->d_inode);
+	ti->private = ef->ei;
+}
+
+/**
+ * eventfs_root_lookup - lookup routine to create file/dir
+ * @dir: directory in which lookup to be done
+ * @dentry: file/dir dentry
+ * @flags:
+ *
+ * Used to create dynamic file/dir with-in @dir, search with-in ei
+ * list, if @dentry found go ahead and create the file/dir
+ */
+
+static struct dentry *eventfs_root_lookup(struct inode *dir,
+					  struct dentry *dentry,
+					  unsigned int flags)
+{
+	struct tracefs_inode *ti;
+	struct eventfs_inode *ei;
+	struct eventfs_file *ef;
+	struct dentry *ret = NULL;
+	int idx;
+
+	ti = get_tracefs(dir);
+	if (!(ti->flags & TRACEFS_EVENT_INODE))
+		return NULL;
+
+	ei = ti->private;
+	idx = srcu_read_lock(&eventfs_srcu);
+	list_for_each_entry_srcu(ef, &ei->e_top_files, list,
+				 srcu_read_lock_held(&eventfs_srcu)) {
+		if (strcmp(ef->name, dentry->d_name.name))
+			continue;
+		ret = simple_lookup(dir, dentry, flags);
+		if (ef->created)
+			continue;
+		mutex_lock(&eventfs_mutex);
+		ef->created = true;
+		if (ef->ei)
+			ef->dentry = create_dir(ef->name, ef->mode, ef->d_parent,
+						ef->data, ef->fop, ef->iop);
+		else
+			ef->dentry = create_file(ef->name, ef->mode, ef->d_parent,
+						 ef->data, ef->fop);
+
+		if (IS_ERR_OR_NULL(ef->dentry)) {
+			ef->created = false;
+			mutex_unlock(&eventfs_mutex);
+		} else {
+			if (ef->ei)
+				eventfs_post_create_dir(ef);
+			ef->dentry->d_fsdata = ef;
+			mutex_unlock(&eventfs_mutex);
+			dput(ef->dentry);
+		}
+		break;
+	}
+	srcu_read_unlock(&eventfs_srcu, idx);
+	return ret;
+}
+
+/**
+ * eventfs_release - called to release eventfs file/dir
+ * @inode: inode to be released
+ * @file: file to be released (not used)
+ */
+static int eventfs_release(struct inode *inode, struct file *file)
+{
+	struct tracefs_inode *ti;
+	struct eventfs_inode *ei;
+	struct eventfs_file *ef;
+	int idx;
+
+	ti = get_tracefs(inode);
+	if (!(ti->flags & TRACEFS_EVENT_INODE))
+		return -EINVAL;
+
+	ei = ti->private;
+	idx = srcu_read_lock(&eventfs_srcu);
+	list_for_each_entry_srcu(ef, &ei->e_top_files, list,
+				 srcu_read_lock_held(&eventfs_srcu)) {
+		if (ef->created)
+			dput(ef->dentry);
+	}
+	srcu_read_unlock(&eventfs_srcu, idx);
+	return dcache_dir_close(inode, file);
+}
+
+/**
+ * dcache_dir_open_wrapper - eventfs open wrapper
+ * @inode: not used
+ * @file: dir to be opened (to create it's child)
+ *
+ * Used to dynamic create file/dir with-in @file, all the
+ * file/dir will be created. If already created then reference
+ * will be increased
+ */
+static int dcache_dir_open_wrapper(struct inode *inode, struct file *file)
+{
+	struct tracefs_inode *ti;
+	struct eventfs_inode *ei;
+	struct eventfs_file *ef;
+	struct dentry *dentry = file_dentry(file);
+	struct inode *f_inode = file_inode(file);
+	int idx;
+
+	ti = get_tracefs(f_inode);
+	if (!(ti->flags & TRACEFS_EVENT_INODE))
+		return -EINVAL;
+
+	ei = ti->private;
+	idx = srcu_read_lock(&eventfs_srcu);
+	list_for_each_entry_rcu(ef, &ei->e_top_files, list) {
+		if (ef->created) {
+			dget(ef->dentry);
+			continue;
+		}
+		mutex_lock(&eventfs_mutex);
+		ef->created = true;
+
+		inode_lock(dentry->d_inode);
+		if (ef->ei)
+			ef->dentry = create_dir(ef->name, ef->mode, dentry,
+						ef->data, ef->fop, ef->iop);
+		else
+			ef->dentry = create_file(ef->name, ef->mode, dentry,
+						 ef->data, ef->fop);
+		inode_unlock(dentry->d_inode);
+
+		if (IS_ERR_OR_NULL(ef->dentry)) {
+			ef->created = false;
+		} else {
+			if (ef->ei)
+				eventfs_post_create_dir(ef);
+			ef->dentry->d_fsdata = ef;
+		}
+		mutex_unlock(&eventfs_mutex);
+	}
+	srcu_read_unlock(&eventfs_srcu, idx);
+	return dcache_dir_open(inode, file);
+}
+
 static const struct file_operations eventfs_file_operations = {
+	.open           = dcache_dir_open_wrapper,
+	.read		= generic_read_dir,
+	.iterate_shared	= dcache_readdir,
+	.llseek		= generic_file_llseek,
+	.release        = eventfs_release,
 };
 
 static const struct inode_operations eventfs_root_dir_inode_operations = {
+	.lookup		= eventfs_root_lookup,
 };
 
 /**
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 47c1b4d21735..4d30b0cafc5f 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -51,6 +51,8 @@ void eventfs_remove(struct eventfs_file *ef);
 
 void eventfs_remove_events_dir(struct dentry *dentry);
 
+void eventfs_set_ef_status_free(struct dentry *dentry);
+
 struct dentry *tracefs_create_file(const char *name, umode_t mode,
 				   struct dentry *parent, void *data,
 				   const struct file_operations *fops);
-- 
2.39.0


  parent reply	other threads:[~2023-07-13 11:34 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-13 11:33 [PATCH v4 00/10] tracing: introducing eventfs Ajay Kaher
2023-07-13 11:33 ` [PATCH v4 01/10] tracing: Require all trace events to have a TRACE_SYSTEM Ajay Kaher
2023-07-13 11:33 ` [PATCH v4 02/10] tracefs: Rename some tracefs function Ajay Kaher
2023-07-14 15:11   ` Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 03/10] eventfs: Implement eventfs dir creation functions Ajay Kaher
2023-07-14 15:44   ` Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 04/10] eventfs: Implement eventfs file add functions Ajay Kaher
2023-07-14 16:23   ` Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 05/10] eventfs: Implement eventfs file, directory remove function Ajay Kaher
2023-07-14 16:35   ` Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 06/10] eventfs: Implement functions to create eventfs files and directories Ajay Kaher
2023-07-14 16:47   ` Steven Rostedt
2023-07-13 11:33 ` Ajay Kaher [this message]
2023-07-14 20:17   ` [PATCH v4 07/10] eventfs: Implement eventfs lookup, read, open functions Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 08/10] eventfs: Implement tracefs_inode_cache Ajay Kaher
2023-07-14 20:27   ` Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 09/10] eventfs: Move tracing/events to eventfs Ajay Kaher
2023-07-14 21:06   ` Steven Rostedt
2023-07-19 11:08     ` Ajay Kaher
2023-07-19 11:08     ` Ajay Kaher
2023-09-08 12:14   ` Sven Schnelle
2023-09-08 12:31     ` Steven Rostedt
2023-07-13 11:33 ` [PATCH v4 10/10] test: ftrace: Fix kprobe test for eventfs Ajay Kaher
2023-07-14  2:37   ` Steven Rostedt
2023-07-14 13:27     ` Masami Hiramatsu
2023-07-17  5:24       ` Ajay Kaher
2023-07-17 12:24         ` Steven Rostedt
2023-07-14 22:58 ` [PATCH v4 00/10] tracing: introducing eventfs Steven Rostedt
2023-07-16 17:32   ` Ajay Kaher
2023-07-18 13:40     ` Steven Rostedt
2023-07-19 10:25       ` Ajay Kaher
2023-07-19 14:23         ` Steven Rostedt
2023-07-19 18:37           ` Ajay Kaher
2023-07-19 18:40             ` Steven Rostedt
2023-07-21 12:48               ` Steven Rostedt
2023-07-21 13:16                 ` Steven Rostedt
2023-07-21 13:19                 ` Steven Rostedt
2023-07-21 17:17                   ` Nadav Amit
2023-07-21 17:24                     ` Steven Rostedt
2023-07-21 17:30                     ` Steven Rostedt
2023-07-21 20:40                   ` Steven Rostedt
2023-07-26 18:54                     ` Ajay Kaher
2023-07-21 13:18               ` Steven Rostedt
2023-07-21 19:14                 ` Steven Rostedt

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=1689248004-8158-8-git-send-email-akaher@vmware.com \
    --to=akaher@vmware.com \
    --cc=amakhalov@vmware.com \
    --cc=chinglinyu@google.com \
    --cc=er.ajay.kaher@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=mhiramat@kernel.org \
    --cc=namit@vmware.com \
    --cc=oe-lkp@lists.linux.dev \
    --cc=rostedt@goodmis.org \
    --cc=shuah@kernel.org \
    --cc=srivatsa@csail.mit.edu \
    --cc=tkundu@vmware.com \
    --cc=vsirnapalli@vmware.com \
    /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.