LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 00/16 v3] tracing: Add new file system tracefs
@ 2015-01-26 15:09 Steven Rostedt
  2015-01-26 15:09 ` [PATCH 01/16 v3] debugfs_{mkdir,create,link}(): get rid of redundant argument Steven Rostedt
                   ` (16 more replies)
  0 siblings, 17 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel; +Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

There has been complaints that tracing is tied too much to debugfs,
as there are systems that would like to perform tracing, but do
not mount debugfs for security reasons. That is because any subsystem
may use debugfs for debugging, and these interfaces are not always
tested for security.

Creating a new tracefs that the tracing directory will now be attached
to allows system admins the ability to access the tracing directory
without the need to mount debugfs.

Another advantage is that debugfs does not support the system calls
for mkdir and rmdir. Tracing uses these system calls to create new
instances for sub buffers. This was done by a hack that hijacked the
dentry ops from the "instances" debugfs dentry, and replacing it with
one that could work.

Instead of using this hack, tracefs can provide a proper interface to
allow the tracing system to have a mkdir and rmdir feature.

To maintain backward compatibility with older tools that expect that
the tracing directory is mounted with debugfs, the tracing directory
is still created under debugfs and tracefs is automatically mounted
there.

Finally, a new directory is created when tracefs is enabled called
/sys/kernel/tracing. This will be the new location that system admins
may mount tracefs if they are not using debugfs.

Changes from v2:

 o Al Viro wrote a series of patches to create "debugfs_create_automount()"
   that gives us a safe way to modify the debugfs dentry to add
   automounting. tracefs now uses this function to automount itself
   on the debugfs/tracing directory.

Changes from v1:

 o Fixed all the posting problems (included files that were missing
   and removed changes that were not suppose to be there).

 o Changed the mkdir/rmdir logic. Instead of trying to keep the inode
   mutexes locked, which caused locking issues with other locks that
   were taken, the locks are still released. But this time, they are
   released by the tracefs system which has a bit more control.
   As the mkdir/rmdir methods for the tracing facility only need the
   new name of the instance, the tracefs mkdir/rmdir copies the name
   from the dentry, releases the locks, and passes in the copy to
   the tracing methods.


Al Viro (11):
      debugfs_{mkdir,create,link}(): get rid of redundant argument
      debugfs: split the beginning and the end of __create_file() off
      debugfs: kill __create_file()
      fold debugfs_link() into caller
      debugfs_mknod(): get rid useless arguments
      fold debugfs_mkdir() into caller
      fold debugfs_create() into caller
      fold debugfs_mknod() into callers
      debugfs: take mode-dependent parts of debugfs_get_inode() into callers
      debugfs: split end_creating() into success and failure cases
      new primitive: debugfs_create_automount()

Steven Rostedt (Red Hat) (5):
      tracefs: Add new tracefs file system
      tracing: Convert the tracing facility over to use tracefs
      tracing: Automatically mount tracefs on debugfs/tracing
      tracefs: Add directory /sys/kernel/tracing
      tracing: Have mkdir and rmdir be part of tracefs

----
 fs/Makefile                          |   1 +
 fs/debugfs/inode.c                   | 251 ++++++-------
 fs/tracefs/Makefile                  |   4 +
 fs/tracefs/inode.c                   | 658 +++++++++++++++++++++++++++++++++++
 include/linux/debugfs.h              |   5 +
 include/linux/tracefs.h              |  48 +++
 include/uapi/linux/magic.h           |   2 +
 kernel/trace/ftrace.c                |  22 +-
 kernel/trace/trace.c                 | 161 ++++-----
 kernel/trace/trace.h                 |   2 +-
 kernel/trace/trace_events.c          |  32 +-
 kernel/trace/trace_functions_graph.c |   7 +-
 kernel/trace/trace_kprobe.c          |  10 +-
 kernel/trace/trace_probe.h           |   2 +-
 kernel/trace/trace_stat.c            |  10 +-
 15 files changed, 962 insertions(+), 253 deletions(-)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 01/16 v3] debugfs_{mkdir,create,link}(): get rid of redundant argument
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 02/16 v3] debugfs: split the beginning and the end of __create_file() off Steven Rostedt
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0001-debugfs_-mkdir-create-link-get-rid-of-redundant-argu.patch --]
[-- Type: text/plain, Size: 2052 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 05f2960ed7c3..adaaa04448b3 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -89,8 +89,9 @@ static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
 	return error;
 }
 
-static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+static int debugfs_mkdir(struct dentry *dentry, umode_t mode)
 {
+	struct inode *dir = dentry->d_parent->d_inode;
 	int res;
 
 	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
@@ -102,16 +103,18 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	return res;
 }
 
-static int debugfs_link(struct inode *dir, struct dentry *dentry, umode_t mode,
+static int debugfs_link(struct dentry *dentry, umode_t mode,
 			void *data)
 {
+	struct inode *dir = dentry->d_parent->d_inode;
 	mode = (mode & S_IALLUGO) | S_IFLNK;
 	return debugfs_mknod(dir, dentry, mode, 0, data, NULL);
 }
 
-static int debugfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+static int debugfs_create(struct dentry *dentry, umode_t mode,
 			  void *data, const struct file_operations *fops)
 {
+	struct inode *dir = dentry->d_parent->d_inode;
 	int res;
 
 	mode = (mode & S_IALLUGO) | S_IFREG;
@@ -329,16 +332,14 @@ static struct dentry *__create_file(const char *name, umode_t mode,
 	if (!IS_ERR(dentry)) {
 		switch (mode & S_IFMT) {
 		case S_IFDIR:
-			error = debugfs_mkdir(parent->d_inode, dentry, mode);
+			error = debugfs_mkdir(dentry, mode);
 
 			break;
 		case S_IFLNK:
-			error = debugfs_link(parent->d_inode, dentry, mode,
-					     data);
+			error = debugfs_link(dentry, mode, data);
 			break;
 		default:
-			error = debugfs_create(parent->d_inode, dentry, mode,
-					       data, fops);
+			error = debugfs_create(dentry, mode, data, fops);
 			break;
 		}
 		dput(dentry);
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 02/16 v3] debugfs: split the beginning and the end of __create_file() off
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
  2015-01-26 15:09 ` [PATCH 01/16 v3] debugfs_{mkdir,create,link}(): get rid of redundant argument Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 03/16 v3] debugfs: kill __create_file() Steven Rostedt
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0002-debugfs-split-the-beginning-and-the-end-of-__create_.patch --]
[-- Type: text/plain, Size: 2911 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 61 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 22 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index adaaa04448b3..100186c2bf0a 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -305,11 +305,9 @@ static struct file_system_type debug_fs_type = {
 };
 MODULE_ALIAS_FS("debugfs");
 
-static struct dentry *__create_file(const char *name, umode_t mode,
-				    struct dentry *parent, void *data,
-				    const struct file_operations *fops)
+static struct dentry *start_creating(const char *name, struct dentry *parent)
 {
-	struct dentry *dentry = NULL;
+	struct dentry *dentry;
 	int error;
 
 	pr_debug("debugfs: creating file '%s'\n",name);
@@ -317,7 +315,7 @@ static struct dentry *__create_file(const char *name, umode_t mode,
 	error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
 			      &debugfs_mount_count);
 	if (error)
-		goto exit;
+		return ERR_PTR(error);
 
 	/* If the parent is not specified, we create it in the root.
 	 * We need the root dentry to do this, which is in the super
@@ -329,32 +327,51 @@ static struct dentry *__create_file(const char *name, umode_t mode,
 
 	mutex_lock(&parent->d_inode->i_mutex);
 	dentry = lookup_one_len(name, parent, strlen(name));
-	if (!IS_ERR(dentry)) {
-		switch (mode & S_IFMT) {
-		case S_IFDIR:
-			error = debugfs_mkdir(dentry, mode);
-
-			break;
-		case S_IFLNK:
-			error = debugfs_link(dentry, mode, data);
-			break;
-		default:
-			error = debugfs_create(dentry, mode, data, fops);
-			break;
-		}
+	if (!IS_ERR(dentry) && dentry->d_inode) {
 		dput(dentry);
-	} else
-		error = PTR_ERR(dentry);
-	mutex_unlock(&parent->d_inode->i_mutex);
+		dentry = ERR_PTR(-EEXIST);
+	}
+	if (IS_ERR(dentry))
+		mutex_unlock(&parent->d_inode->i_mutex);
+	return dentry;
+}
+
+static struct dentry *end_creating(struct dentry *dentry, int error)
+{
+	mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
+	dput(dentry);
 
 	if (error) {
 		dentry = NULL;
 		simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 	}
-exit:
 	return dentry;
 }
 
+static struct dentry *__create_file(const char *name, umode_t mode,
+				    struct dentry *parent, void *data,
+				    const struct file_operations *fops)
+{
+	struct dentry *dentry = start_creating(name, parent);
+	int error;
+
+	if (IS_ERR(dentry))
+		return NULL;
+
+	switch (mode & S_IFMT) {
+	case S_IFDIR:
+		error = debugfs_mkdir(dentry, mode);
+		break;
+	case S_IFLNK:
+		error = debugfs_link(dentry, mode, data);
+		break;
+	default:
+		error = debugfs_create(dentry, mode, data, fops);
+		break;
+	}
+	return end_creating(dentry, error);
+}
+
 /**
  * debugfs_create_file - create a file in the debugfs filesystem
  * @name: a pointer to a string containing the name of the file to create.
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 03/16 v3] debugfs: kill __create_file()
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
  2015-01-26 15:09 ` [PATCH 01/16 v3] debugfs_{mkdir,create,link}(): get rid of redundant argument Steven Rostedt
  2015-01-26 15:09 ` [PATCH 02/16 v3] debugfs: split the beginning and the end of __create_file() off Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 04/16 v3] fold debugfs_link() into caller Steven Rostedt
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0003-debugfs-kill-__create_file.patch --]
[-- Type: text/plain, Size: 3067 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 71 +++++++++++++++++++++++++-----------------------------
 1 file changed, 33 insertions(+), 38 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 100186c2bf0a..18564b08884c 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -348,30 +348,6 @@ static struct dentry *end_creating(struct dentry *dentry, int error)
 	return dentry;
 }
 
-static struct dentry *__create_file(const char *name, umode_t mode,
-				    struct dentry *parent, void *data,
-				    const struct file_operations *fops)
-{
-	struct dentry *dentry = start_creating(name, parent);
-	int error;
-
-	if (IS_ERR(dentry))
-		return NULL;
-
-	switch (mode & S_IFMT) {
-	case S_IFDIR:
-		error = debugfs_mkdir(dentry, mode);
-		break;
-	case S_IFLNK:
-		error = debugfs_link(dentry, mode, data);
-		break;
-	default:
-		error = debugfs_create(dentry, mode, data, fops);
-		break;
-	}
-	return end_creating(dentry, error);
-}
-
 /**
  * debugfs_create_file - create a file in the debugfs filesystem
  * @name: a pointer to a string containing the name of the file to create.
@@ -402,15 +378,19 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
 				   struct dentry *parent, void *data,
 				   const struct file_operations *fops)
 {
-	switch (mode & S_IFMT) {
-	case S_IFREG:
-	case 0:
-		break;
-	default:
-		BUG();
-	}
+	struct dentry *dentry;
+	int error;
+
+	if (!(mode & S_IFMT))
+		mode |= S_IFREG;
+	BUG_ON(!S_ISREG(mode));
+	dentry = start_creating(name, parent);
+
+	if (IS_ERR(dentry))
+		return NULL;
 
-	return __create_file(name, mode, parent, data, fops);
+	error = debugfs_create(dentry, mode, data, fops);
+	return end_creating(dentry, error);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_file);
 
@@ -434,8 +414,14 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
  */
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 {
-	return __create_file(name, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-				   parent, NULL, NULL);
+	struct dentry *dentry = start_creating(name, parent);
+	int error;
+
+	if (IS_ERR(dentry))
+		return NULL;
+
+	error = debugfs_mkdir(dentry, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+	return end_creating(dentry, error);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
@@ -465,17 +451,26 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
 struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 				      const char *target)
 {
-	struct dentry *result;
+	struct dentry *dentry;
 	char *link;
+	int error;
 
 	link = kstrdup(target, GFP_KERNEL);
 	if (!link)
 		return NULL;
 
-	result = __create_file(name, S_IFLNK | S_IRWXUGO, parent, link, NULL);
-	if (!result)
+	dentry = start_creating(name, parent);
+
+	if (IS_ERR(dentry)) {
 		kfree(link);
-	return result;
+		return NULL;
+	}
+
+	error = debugfs_link(dentry, S_IFLNK | S_IRWXUGO, link);
+	if (error)
+		kfree(link);
+
+	return end_creating(dentry, error);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 04/16 v3] fold debugfs_link() into caller
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (2 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 03/16 v3] debugfs: kill __create_file() Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 05/16 v3] debugfs_mknod(): get rid useless arguments Steven Rostedt
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0004-fold-debugfs_link-into-caller.patch --]
[-- Type: text/plain, Size: 1108 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 18564b08884c..c69e00d69ff1 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -103,14 +103,6 @@ static int debugfs_mkdir(struct dentry *dentry, umode_t mode)
 	return res;
 }
 
-static int debugfs_link(struct dentry *dentry, umode_t mode,
-			void *data)
-{
-	struct inode *dir = dentry->d_parent->d_inode;
-	mode = (mode & S_IALLUGO) | S_IFLNK;
-	return debugfs_mknod(dir, dentry, mode, 0, data, NULL);
-}
-
 static int debugfs_create(struct dentry *dentry, umode_t mode,
 			  void *data, const struct file_operations *fops)
 {
@@ -466,7 +458,8 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 		return NULL;
 	}
 
-	error = debugfs_link(dentry, S_IFLNK | S_IRWXUGO, link);
+	error = debugfs_mknod(dentry->d_parent->d_inode, dentry,
+			      S_IFLNK | S_IRWXUGO, 0, link, NULL);
 	if (error)
 		kfree(link);
 
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 05/16 v3] debugfs_mknod(): get rid useless arguments
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (3 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 04/16 v3] fold debugfs_link() into caller Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 06/16 v3] fold debugfs_mkdir() into caller Steven Rostedt
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0005-debugfs_mknod-get-rid-useless-arguments.patch --]
[-- Type: text/plain, Size: 2233 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

dev is always zero, dir was only used to get its ->i_sb, which is
equal to ->d_sb of dentry...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index c69e00d69ff1..bc02e2096977 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -70,23 +70,18 @@ static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev
 }
 
 /* SMP-safe */
-static int debugfs_mknod(struct inode *dir, struct dentry *dentry,
-			 umode_t mode, dev_t dev, void *data,
+static int debugfs_mknod(struct dentry *dentry,
+			 umode_t mode, void *data,
 			 const struct file_operations *fops)
 {
 	struct inode *inode;
-	int error = -EPERM;
 
-	if (dentry->d_inode)
-		return -EEXIST;
-
-	inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops);
-	if (inode) {
-		d_instantiate(dentry, inode);
-		dget(dentry);
-		error = 0;
-	}
-	return error;
+	inode = debugfs_get_inode(dentry->d_sb, mode, 0, data, fops);
+	if (unlikely(!inode))
+		return -EPERM;
+	d_instantiate(dentry, inode);
+	dget(dentry);
+	return 0;
 }
 
 static int debugfs_mkdir(struct dentry *dentry, umode_t mode)
@@ -95,7 +90,7 @@ static int debugfs_mkdir(struct dentry *dentry, umode_t mode)
 	int res;
 
 	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
-	res = debugfs_mknod(dir, dentry, mode, 0, NULL, NULL);
+	res = debugfs_mknod(dentry, mode, NULL, NULL);
 	if (!res) {
 		inc_nlink(dir);
 		fsnotify_mkdir(dir, dentry);
@@ -110,7 +105,7 @@ static int debugfs_create(struct dentry *dentry, umode_t mode,
 	int res;
 
 	mode = (mode & S_IALLUGO) | S_IFREG;
-	res = debugfs_mknod(dir, dentry, mode, 0, data, fops);
+	res = debugfs_mknod(dentry, mode, data, fops);
 	if (!res)
 		fsnotify_create(dir, dentry);
 	return res;
@@ -458,8 +453,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 		return NULL;
 	}
 
-	error = debugfs_mknod(dentry->d_parent->d_inode, dentry,
-			      S_IFLNK | S_IRWXUGO, 0, link, NULL);
+	error = debugfs_mknod(dentry, S_IFLNK | S_IRWXUGO, link, NULL);
 	if (error)
 		kfree(link);
 
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 06/16 v3] fold debugfs_mkdir() into caller
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (4 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 05/16 v3] debugfs_mknod(): get rid useless arguments Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 07/16 v3] fold debugfs_create() " Steven Rostedt
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0006-fold-debugfs_mkdir-into-caller.patch --]
[-- Type: text/plain, Size: 1366 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index bc02e2096977..8d12935c87f1 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -84,20 +84,6 @@ static int debugfs_mknod(struct dentry *dentry,
 	return 0;
 }
 
-static int debugfs_mkdir(struct dentry *dentry, umode_t mode)
-{
-	struct inode *dir = dentry->d_parent->d_inode;
-	int res;
-
-	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
-	res = debugfs_mknod(dentry, mode, NULL, NULL);
-	if (!res) {
-		inc_nlink(dir);
-		fsnotify_mkdir(dir, dentry);
-	}
-	return res;
-}
-
 static int debugfs_create(struct dentry *dentry, umode_t mode,
 			  void *data, const struct file_operations *fops)
 {
@@ -407,7 +393,12 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 	if (IS_ERR(dentry))
 		return NULL;
 
-	error = debugfs_mkdir(dentry, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+	error = debugfs_mknod(dentry, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+			      NULL, NULL);
+	if (!error) {
+		inc_nlink(dentry->d_parent->d_inode);
+		fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+	}
 	return end_creating(dentry, error);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 07/16 v3] fold debugfs_create() into caller
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (5 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 06/16 v3] fold debugfs_mkdir() into caller Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 08/16 v3] fold debugfs_mknod() into callers Steven Rostedt
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0007-fold-debugfs_create-into-caller.patch --]
[-- Type: text/plain, Size: 1254 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 8d12935c87f1..778c0e32eb51 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -84,19 +84,6 @@ static int debugfs_mknod(struct dentry *dentry,
 	return 0;
 }
 
-static int debugfs_create(struct dentry *dentry, umode_t mode,
-			  void *data, const struct file_operations *fops)
-{
-	struct inode *dir = dentry->d_parent->d_inode;
-	int res;
-
-	mode = (mode & S_IALLUGO) | S_IFREG;
-	res = debugfs_mknod(dentry, mode, data, fops);
-	if (!res)
-		fsnotify_create(dir, dentry);
-	return res;
-}
-
 static inline int debugfs_positive(struct dentry *dentry)
 {
 	return dentry->d_inode && !d_unhashed(dentry);
@@ -362,7 +349,9 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
 	if (IS_ERR(dentry))
 		return NULL;
 
-	error = debugfs_create(dentry, mode, data, fops);
+	error = debugfs_mknod(dentry, mode, data, fops);
+	if (!error)
+		fsnotify_create(dentry->d_parent->d_inode, dentry);
 	return end_creating(dentry, error);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_file);
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 08/16 v3] fold debugfs_mknod() into callers
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (6 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 07/16 v3] fold debugfs_create() " Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 09/16 v3] debugfs: take mode-dependent parts of debugfs_get_inode() " Steven Rostedt
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0008-fold-debugfs_mknod-into-callers.patch --]
[-- Type: text/plain, Size: 3563 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 68 +++++++++++++++++++++++++-----------------------------
 1 file changed, 31 insertions(+), 37 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 778c0e32eb51..b765c04eba20 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -69,21 +69,6 @@ static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev
 	return inode;
 }
 
-/* SMP-safe */
-static int debugfs_mknod(struct dentry *dentry,
-			 umode_t mode, void *data,
-			 const struct file_operations *fops)
-{
-	struct inode *inode;
-
-	inode = debugfs_get_inode(dentry->d_sb, mode, 0, data, fops);
-	if (unlikely(!inode))
-		return -EPERM;
-	d_instantiate(dentry, inode);
-	dget(dentry);
-	return 0;
-}
-
 static inline int debugfs_positive(struct dentry *dentry)
 {
 	return dentry->d_inode && !d_unhashed(dentry);
@@ -339,7 +324,7 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
 				   const struct file_operations *fops)
 {
 	struct dentry *dentry;
-	int error;
+	struct inode *inode;
 
 	if (!(mode & S_IFMT))
 		mode |= S_IFREG;
@@ -349,10 +334,14 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
 	if (IS_ERR(dentry))
 		return NULL;
 
-	error = debugfs_mknod(dentry, mode, data, fops);
-	if (!error)
-		fsnotify_create(dentry->d_parent->d_inode, dentry);
-	return end_creating(dentry, error);
+	inode = debugfs_get_inode(dentry->d_sb, mode, 0, data, fops);
+	if (unlikely(!inode))
+		return end_creating(dentry, -ENOMEM);
+
+	d_instantiate(dentry, inode);
+	dget(dentry);
+	fsnotify_create(dentry->d_parent->d_inode, dentry);
+	return end_creating(dentry, 0);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_file);
 
@@ -377,18 +366,22 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
 struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 {
 	struct dentry *dentry = start_creating(name, parent);
-	int error;
+	struct inode *inode;
 
 	if (IS_ERR(dentry))
 		return NULL;
 
-	error = debugfs_mknod(dentry, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-			      NULL, NULL);
-	if (!error) {
-		inc_nlink(dentry->d_parent->d_inode);
-		fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
-	}
-	return end_creating(dentry, error);
+	inode = debugfs_get_inode(dentry->d_sb,
+				  S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+				  0, NULL, NULL);
+	if (unlikely(!inode))
+		return end_creating(dentry, -ENOMEM);
+
+	d_instantiate(dentry, inode);
+	dget(dentry);
+	inc_nlink(dentry->d_parent->d_inode);
+	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+	return end_creating(dentry, 0);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
@@ -419,25 +412,26 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 				      const char *target)
 {
 	struct dentry *dentry;
-	char *link;
-	int error;
-
-	link = kstrdup(target, GFP_KERNEL);
+	struct inode *inode;
+	char *link = kstrdup(target, GFP_KERNEL);
 	if (!link)
 		return NULL;
 
 	dentry = start_creating(name, parent);
-
 	if (IS_ERR(dentry)) {
 		kfree(link);
 		return NULL;
 	}
 
-	error = debugfs_mknod(dentry, S_IFLNK | S_IRWXUGO, link, NULL);
-	if (error)
+	inode = debugfs_get_inode(dentry->d_sb, S_IFLNK | S_IRWXUGO, 0,
+				  link, NULL);
+	if (unlikely(!inode)) {
 		kfree(link);
-
-	return end_creating(dentry, error);
+		return end_creating(dentry, -ENOMEM);
+	}
+	d_instantiate(dentry, inode);
+	dget(dentry);
+	return end_creating(dentry, 0);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 09/16 v3] debugfs: take mode-dependent parts of debugfs_get_inode() into callers
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (7 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 08/16 v3] fold debugfs_mknod() into callers Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 10/16 v3] debugfs: split end_creating() into success and failure cases Steven Rostedt
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0009-debugfs-take-mode-dependent-parts-of-debugfs_get_ino.patch --]
[-- Type: text/plain, Size: 3218 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

... and trim the arguments list

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 48 ++++++++++++++++--------------------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index b765c04eba20..61e9a6815a19 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -34,37 +34,12 @@ static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
 static bool debugfs_registered;
 
-static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev_t dev,
-				       void *data, const struct file_operations *fops)
-
+static struct inode *debugfs_get_inode(struct super_block *sb)
 {
 	struct inode *inode = new_inode(sb);
-
 	if (inode) {
 		inode->i_ino = get_next_ino();
-		inode->i_mode = mode;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = fops ? fops : &debugfs_file_operations;
-			inode->i_private = data;
-			break;
-		case S_IFLNK:
-			inode->i_op = &debugfs_link_operations;
-			inode->i_private = data;
-			break;
-		case S_IFDIR:
-			inode->i_op = &simple_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2
-			 * (for "." entry) */
-			inc_nlink(inode);
-			break;
-		}
 	}
 	return inode;
 }
@@ -334,10 +309,13 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
 	if (IS_ERR(dentry))
 		return NULL;
 
-	inode = debugfs_get_inode(dentry->d_sb, mode, 0, data, fops);
+	inode = debugfs_get_inode(dentry->d_sb);
 	if (unlikely(!inode))
 		return end_creating(dentry, -ENOMEM);
 
+	inode->i_mode = mode;
+	inode->i_fop = fops ? fops : &debugfs_file_operations;
+	inode->i_private = data;
 	d_instantiate(dentry, inode);
 	dget(dentry);
 	fsnotify_create(dentry->d_parent->d_inode, dentry);
@@ -371,12 +349,16 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 	if (IS_ERR(dentry))
 		return NULL;
 
-	inode = debugfs_get_inode(dentry->d_sb,
-				  S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-				  0, NULL, NULL);
+	inode = debugfs_get_inode(dentry->d_sb);
 	if (unlikely(!inode))
 		return end_creating(dentry, -ENOMEM);
 
+	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+	inode->i_op = &simple_dir_inode_operations;
+	inode->i_fop = &simple_dir_operations;
+
+	/* directory inodes start off with i_nlink == 2 (for "." entry) */
+	inc_nlink(inode);
 	d_instantiate(dentry, inode);
 	dget(dentry);
 	inc_nlink(dentry->d_parent->d_inode);
@@ -423,12 +405,14 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 		return NULL;
 	}
 
-	inode = debugfs_get_inode(dentry->d_sb, S_IFLNK | S_IRWXUGO, 0,
-				  link, NULL);
+	inode = debugfs_get_inode(dentry->d_sb);
 	if (unlikely(!inode)) {
 		kfree(link);
 		return end_creating(dentry, -ENOMEM);
 	}
+	inode->i_mode = S_IFLNK | S_IRWXUGO;
+	inode->i_op = &debugfs_link_operations;
+	inode->i_private = link;
 	d_instantiate(dentry, inode);
 	dget(dentry);
 	return end_creating(dentry, 0);
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 10/16 v3] debugfs: split end_creating() into success and failure cases
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (8 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 09/16 v3] debugfs: take mode-dependent parts of debugfs_get_inode() " Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 11/16 v3] new primitive: debugfs_create_automount() Steven Rostedt
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0010-debugfs-split-end_creating-into-success-and-failure-.patch --]
[-- Type: text/plain, Size: 2968 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

... and don't bother with dput(dentry) in the former and with
dget(dentry) preceding all its calls.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 61e9a6815a19..1219dff8e18f 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -256,15 +256,17 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
 	return dentry;
 }
 
-static struct dentry *end_creating(struct dentry *dentry, int error)
+static struct dentry *failed_creating(struct dentry *dentry)
 {
 	mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
 	dput(dentry);
+	simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+	return NULL;
+}
 
-	if (error) {
-		dentry = NULL;
-		simple_release_fs(&debugfs_mount, &debugfs_mount_count);
-	}
+static struct dentry *end_creating(struct dentry *dentry)
+{
+	mutex_unlock(&dentry->d_parent->d_inode->i_mutex);
 	return dentry;
 }
 
@@ -311,15 +313,14 @@ struct dentry *debugfs_create_file(const char *name, umode_t mode,
 
 	inode = debugfs_get_inode(dentry->d_sb);
 	if (unlikely(!inode))
-		return end_creating(dentry, -ENOMEM);
+		return failed_creating(dentry);
 
 	inode->i_mode = mode;
 	inode->i_fop = fops ? fops : &debugfs_file_operations;
 	inode->i_private = data;
 	d_instantiate(dentry, inode);
-	dget(dentry);
 	fsnotify_create(dentry->d_parent->d_inode, dentry);
-	return end_creating(dentry, 0);
+	return end_creating(dentry);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_file);
 
@@ -351,7 +352,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 
 	inode = debugfs_get_inode(dentry->d_sb);
 	if (unlikely(!inode))
-		return end_creating(dentry, -ENOMEM);
+		return failed_creating(dentry);
 
 	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
 	inode->i_op = &simple_dir_inode_operations;
@@ -360,10 +361,9 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 	/* directory inodes start off with i_nlink == 2 (for "." entry) */
 	inc_nlink(inode);
 	d_instantiate(dentry, inode);
-	dget(dentry);
 	inc_nlink(dentry->d_parent->d_inode);
 	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
-	return end_creating(dentry, 0);
+	return end_creating(dentry);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
@@ -408,14 +408,13 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 	inode = debugfs_get_inode(dentry->d_sb);
 	if (unlikely(!inode)) {
 		kfree(link);
-		return end_creating(dentry, -ENOMEM);
+		return failed_creating(dentry);
 	}
 	inode->i_mode = S_IFLNK | S_IRWXUGO;
 	inode->i_op = &debugfs_link_operations;
 	inode->i_private = link;
 	d_instantiate(dentry, inode);
-	dget(dentry);
-	return end_creating(dentry, 0);
+	return end_creating(dentry);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 11/16 v3] new primitive: debugfs_create_automount()
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (9 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 10/16 v3] debugfs: split end_creating() into success and failure cases Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 12/16 v3] tracefs: Add new tracefs file system Steven Rostedt
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0011-new-primitive-debugfs_create_automount.patch --]
[-- Type: text/plain, Size: 3347 bytes --]

From: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/debugfs/inode.c      | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/debugfs.h |  5 +++++
 2 files changed, 53 insertions(+)

diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 1219dff8e18f..957c40ce09f6 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -175,6 +175,18 @@ static const struct super_operations debugfs_super_operations = {
 	.show_options	= debugfs_show_options,
 };
 
+static struct vfsmount *debugfs_automount(struct path *path)
+{
+	struct vfsmount *(*f)(void *);
+	f = (struct vfsmount *(*)(void *))path->dentry->d_fsdata;
+	return f(path->dentry->d_inode->i_private);
+}
+
+static const struct dentry_operations debugfs_dops = {
+	.d_delete = always_delete_dentry,
+	.d_automount = debugfs_automount,
+};
+
 static int debug_fill_super(struct super_block *sb, void *data, int silent)
 {
 	static struct tree_descr debug_files[] = {{""}};
@@ -199,6 +211,7 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
 		goto fail;
 
 	sb->s_op = &debugfs_super_operations;
+	sb->s_d_op = &debugfs_dops;
 
 	debugfs_apply_options(sb);
 
@@ -368,6 +381,41 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
 EXPORT_SYMBOL_GPL(debugfs_create_dir);
 
 /**
+ * debugfs_create_automount - create automount point in the debugfs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this parameter is NULL, then the
+ *          file will be created in the root of the debugfs filesystem.
+ * @f: function to be called when pathname resolution steps on that one.
+ * @data: opaque argument to pass to f().
+ *
+ * @f should return what ->d_automount() would.
+ */
+struct dentry *debugfs_create_automount(const char *name,
+					struct dentry *parent,
+					struct vfsmount *(*f)(void *),
+					void *data)
+{
+	struct dentry *dentry = start_creating(name, parent);
+	struct inode *inode;
+
+	if (IS_ERR(dentry))
+		return NULL;
+
+	inode = debugfs_get_inode(dentry->d_sb);
+	if (unlikely(!inode))
+		return failed_creating(dentry);
+
+	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+	inode->i_flags |= S_AUTOMOUNT;
+	inode->i_private = data;
+	dentry->d_fsdata = (void *)f;
+	d_instantiate(dentry, inode);
+	return end_creating(dentry);
+}
+EXPORT_SYMBOL(debugfs_create_automount);
+
+/**
  * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
  * @name: a pointer to a string containing the name of the symbolic link to
  *        create.
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index da4c4983adbe..ea149a24a1f2 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -56,6 +56,11 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
 struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 				      const char *dest);
 
+struct dentry *debugfs_create_automount(const char *name,
+					struct dentry *parent,
+					struct vfsmount *(*f)(void *),
+					void *data);
+
 void debugfs_remove(struct dentry *dentry);
 void debugfs_remove_recursive(struct dentry *dentry);
 
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 12/16 v3] tracefs: Add new tracefs file system
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (10 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 11/16 v3] new primitive: debugfs_create_automount() Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 13/16 v3] tracing: Convert the tracing facility over to use tracefs Steven Rostedt
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel; +Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

[-- Attachment #1: 0012-tracefs-Add-new-tracefs-file-system.patch --]
[-- Type: text/plain, Size: 18320 bytes --]

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

Add a separate file system to handle the tracing directory. Currently it
is part of debugfs, but that is starting to show its limits.

One thing is that in order to access the tracing infrastructure, you need
to mount debugfs. As that includes debugging from all sorts of sub systems
in the kernel, it is not considered advisable to mount such an all
encompassing debugging system.

Having the tracing system in its own file systems gives access to the
tracing sub system without needing to include all other systems.

Another problem with tracing using the debugfs system is that the
instances use mkdir to create sub buffers. debugfs does not support mkdir
from userspace so to implement it, special hacks were used. By controlling
the file system that the tracing infrastructure uses, this can be properly
done without hacks.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 fs/Makefile                |   1 +
 fs/tracefs/Makefile        |   4 +
 fs/tracefs/inode.c         | 560 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/tracefs.h    |  41 ++++
 include/uapi/linux/magic.h |   2 +
 5 files changed, 608 insertions(+)
 create mode 100644 fs/tracefs/Makefile
 create mode 100644 fs/tracefs/inode.c
 create mode 100644 include/linux/tracefs.h

diff --git a/fs/Makefile b/fs/Makefile
index bedff48e8fdc..d244b8d973ac 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_HOSTFS)		+= hostfs/
 obj-$(CONFIG_HPPFS)		+= hppfs/
 obj-$(CONFIG_CACHEFILES)	+= cachefiles/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
+obj-$(CONFIG_TRACING)		+= tracefs/
 obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
 obj-$(CONFIG_BTRFS_FS)		+= btrfs/
 obj-$(CONFIG_GFS2_FS)           += gfs2/
diff --git a/fs/tracefs/Makefile b/fs/tracefs/Makefile
new file mode 100644
index 000000000000..82fa35b656c4
--- /dev/null
+++ b/fs/tracefs/Makefile
@@ -0,0 +1,4 @@
+tracefs-objs	:= inode.o
+
+obj-$(CONFIG_TRACING)	+= tracefs.o
+
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
new file mode 100644
index 000000000000..c31997a303c7
--- /dev/null
+++ b/fs/tracefs/inode.c
@@ -0,0 +1,560 @@
+/*
+ *  inode.c - part of tracefs, a pseudo file system for activating tracing
+ *
+ * Based on debugfs by: Greg Kroah-Hartman <greg@kroah.com>
+ *
+ *  Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt <srostedt@redhat.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License version
+ *	2 as published by the Free Software Foundation.
+ *
+ * tracefs is the file system that is used by the tracing infrastructure.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/tracefs.h>
+#include <linux/fsnotify.h>
+#include <linux/seq_file.h>
+#include <linux/parser.h>
+#include <linux/magic.h>
+#include <linux/slab.h>
+
+#define TRACEFS_DEFAULT_MODE	0700
+
+static struct vfsmount *tracefs_mount;
+static int tracefs_mount_count;
+static bool tracefs_registered;
+
+static ssize_t default_read_file(struct file *file, char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	return 0;
+}
+
+static ssize_t default_write_file(struct file *file, const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static const struct file_operations tracefs_file_operations = {
+	.read =		default_read_file,
+	.write =	default_write_file,
+	.open =		simple_open,
+	.llseek =	noop_llseek,
+};
+
+static struct inode *tracefs_get_inode(struct super_block *sb, umode_t mode, dev_t dev,
+				      void *data, const struct file_operations *fops)
+
+{
+	struct inode *inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_ino = get_next_ino();
+		inode->i_mode = mode;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = fops ? fops : &tracefs_file_operations;
+			inode->i_private = data;
+			break;
+		case S_IFDIR:
+			inode->i_op = &simple_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+
+			/* directory inodes start off with i_nlink == 2
+			 * (for "." entry) */
+			inc_nlink(inode);
+			break;
+		}
+	}
+	return inode;
+}
+
+static int tracefs_mknod(struct inode *dir, struct dentry *dentry,
+			 umode_t mode, dev_t dev, void *data,
+			 const struct file_operations *fops)
+{
+	struct inode *inode;
+	int error = -EPERM;
+
+	if (dentry->d_inode)
+		return -EEXIST;
+
+	inode = tracefs_get_inode(dir->i_sb, mode, dev, data, fops);
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);
+		error = 0;
+	}
+	return error;
+}
+
+static int tracefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+	int res;
+
+	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+	res = tracefs_mknod(dir, dentry, mode, 0, NULL, NULL);
+	if (!res) {
+		inc_nlink(dir);
+		fsnotify_mkdir(dir, dentry);
+	}
+	return res;
+}
+
+static int tracefs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+			  void *data, const struct file_operations *fops)
+{
+	int res;
+
+	mode = (mode & S_IALLUGO) | S_IFREG;
+	res = tracefs_mknod(dir, dentry, mode, 0, data, fops);
+	if (!res)
+		fsnotify_create(dir, dentry);
+	return res;
+}
+
+struct tracefs_mount_opts {
+	kuid_t uid;
+	kgid_t gid;
+	umode_t mode;
+};
+
+enum {
+	Opt_uid,
+	Opt_gid,
+	Opt_mode,
+	Opt_err
+};
+
+static const match_table_t tokens = {
+	{Opt_uid, "uid=%u"},
+	{Opt_gid, "gid=%u"},
+	{Opt_mode, "mode=%o"},
+	{Opt_err, NULL}
+};
+
+struct tracefs_fs_info {
+	struct tracefs_mount_opts mount_opts;
+};
+
+static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
+{
+	substring_t args[MAX_OPT_ARGS];
+	int option;
+	int token;
+	kuid_t uid;
+	kgid_t gid;
+	char *p;
+
+	opts->mode = TRACEFS_DEFAULT_MODE;
+
+	while ((p = strsep(&data, ",")) != NULL) {
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_uid:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			uid = make_kuid(current_user_ns(), option);
+			if (!uid_valid(uid))
+				return -EINVAL;
+			opts->uid = uid;
+			break;
+		case Opt_gid:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			gid = make_kgid(current_user_ns(), option);
+			if (!gid_valid(gid))
+				return -EINVAL;
+			opts->gid = gid;
+			break;
+		case Opt_mode:
+			if (match_octal(&args[0], &option))
+				return -EINVAL;
+			opts->mode = option & S_IALLUGO;
+			break;
+		/*
+		 * We might like to report bad mount options here;
+		 * but traditionally tracefs has ignored all mount options
+		 */
+		}
+	}
+
+	return 0;
+}
+
+static int tracefs_apply_options(struct super_block *sb)
+{
+	struct tracefs_fs_info *fsi = sb->s_fs_info;
+	struct inode *inode = sb->s_root->d_inode;
+	struct tracefs_mount_opts *opts = &fsi->mount_opts;
+
+	inode->i_mode &= ~S_IALLUGO;
+	inode->i_mode |= opts->mode;
+
+	inode->i_uid = opts->uid;
+	inode->i_gid = opts->gid;
+
+	return 0;
+}
+
+static int tracefs_remount(struct super_block *sb, int *flags, char *data)
+{
+	int err;
+	struct tracefs_fs_info *fsi = sb->s_fs_info;
+
+	sync_filesystem(sb);
+	err = tracefs_parse_options(data, &fsi->mount_opts);
+	if (err)
+		goto fail;
+
+	tracefs_apply_options(sb);
+
+fail:
+	return err;
+}
+
+static int tracefs_show_options(struct seq_file *m, struct dentry *root)
+{
+	struct tracefs_fs_info *fsi = root->d_sb->s_fs_info;
+	struct tracefs_mount_opts *opts = &fsi->mount_opts;
+
+	if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
+		seq_printf(m, ",uid=%u",
+			   from_kuid_munged(&init_user_ns, opts->uid));
+	if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
+		seq_printf(m, ",gid=%u",
+			   from_kgid_munged(&init_user_ns, opts->gid));
+	if (opts->mode != TRACEFS_DEFAULT_MODE)
+		seq_printf(m, ",mode=%o", opts->mode);
+
+	return 0;
+}
+
+static const struct super_operations tracefs_super_operations = {
+	.statfs		= simple_statfs,
+	.remount_fs	= tracefs_remount,
+	.show_options	= tracefs_show_options,
+};
+
+static int trace_fill_super(struct super_block *sb, void *data, int silent)
+{
+	static struct tree_descr trace_files[] = {{""}};
+	struct tracefs_fs_info *fsi;
+	int err;
+
+	save_mount_options(sb, data);
+
+	fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL);
+	sb->s_fs_info = fsi;
+	if (!fsi) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	err = tracefs_parse_options(data, &fsi->mount_opts);
+	if (err)
+		goto fail;
+
+	err  =  simple_fill_super(sb, TRACEFS_MAGIC, trace_files);
+	if (err)
+		goto fail;
+
+	sb->s_op = &tracefs_super_operations;
+
+	tracefs_apply_options(sb);
+
+	return 0;
+
+fail:
+	kfree(fsi);
+	sb->s_fs_info = NULL;
+	return err;
+}
+
+static struct dentry *trace_mount(struct file_system_type *fs_type,
+			int flags, const char *dev_name,
+			void *data)
+{
+	return mount_single(fs_type, flags, data, trace_fill_super);
+}
+
+static struct file_system_type trace_fs_type = {
+	.owner =	THIS_MODULE,
+	.name =		"tracefs",
+	.mount =	trace_mount,
+	.kill_sb =	kill_litter_super,
+};
+MODULE_ALIAS_FS("tracefs");
+
+static struct dentry *__create_file(const char *name, umode_t mode,
+				    struct dentry *parent, void *data,
+				    const struct file_operations *fops)
+{
+	struct dentry *dentry = NULL;
+	int error;
+
+	pr_debug("tracefs: creating file '%s'\n",name);
+
+	error = simple_pin_fs(&trace_fs_type, &tracefs_mount,
+			      &tracefs_mount_count);
+	if (error)
+		goto exit;
+
+	/* If the parent is not specified, we create it in the root.
+	 * We need the root dentry to do this, which is in the super
+	 * block. A pointer to that is in the struct vfsmount that we
+	 * have around.
+	 */
+	if (!parent)
+		parent = tracefs_mount->mnt_root;
+
+	mutex_lock(&parent->d_inode->i_mutex);
+	dentry = lookup_one_len(name, parent, strlen(name));
+	if (!IS_ERR(dentry)) {
+		switch (mode & S_IFMT) {
+		case S_IFDIR:
+			error = tracefs_mkdir(parent->d_inode, dentry, mode);
+
+			break;
+		default:
+			error = tracefs_create(parent->d_inode, dentry, mode,
+					       data, fops);
+			break;
+		}
+		dput(dentry);
+	} else
+		error = PTR_ERR(dentry);
+	mutex_unlock(&parent->d_inode->i_mutex);
+
+	if (error) {
+		dentry = NULL;
+		simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+	}
+exit:
+	return dentry;
+}
+
+/**
+ * tracefs_create_file - create a file in the tracefs filesystem
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have.
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this parameter is NULL, then the
+ *          file will be created in the root of the tracefs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ *        on.  The inode.i_private pointer will point to this value on
+ *        the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ *        this file.
+ *
+ * This is the basic "create a file" function for tracefs.  It allows for a
+ * wide range of flexibility in creating a file, or a directory (if you want
+ * to create a directory, the tracefs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the tracefs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, %NULL will be returned.
+ *
+ * If tracefs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *tracefs_create_file(const char *name, umode_t mode,
+				   struct dentry *parent, void *data,
+				   const struct file_operations *fops)
+{
+	switch (mode & S_IFMT) {
+	case S_IFREG:
+	case 0:
+		break;
+	default:
+		BUG();
+	}
+
+	return __create_file(name, mode, parent, data, fops);
+}
+
+/**
+ * tracefs_create_dir - create a directory in the tracefs filesystem
+ * @name: a pointer to a string containing the name of the directory to
+ *        create.
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this parameter is NULL, then the
+ *          directory will be created in the root of the tracefs filesystem.
+ *
+ * This function creates a directory in tracefs with the given name.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the tracefs_remove() function when the file is
+ * to be removed. If an error occurs, %NULL will be returned.
+ *
+ * If tracing is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
+{
+	return __create_file(name, S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+				   parent, NULL, NULL);
+}
+
+static inline int tracefs_positive(struct dentry *dentry)
+{
+	return dentry->d_inode && !d_unhashed(dentry);
+}
+
+static int __tracefs_remove(struct dentry *dentry, struct dentry *parent)
+{
+	int ret = 0;
+
+	if (tracefs_positive(dentry)) {
+		if (dentry->d_inode) {
+			dget(dentry);
+			switch (dentry->d_inode->i_mode & S_IFMT) {
+			case S_IFDIR:
+				ret = simple_rmdir(parent->d_inode, dentry);
+				break;
+			default:
+				simple_unlink(parent->d_inode, dentry);
+				break;
+			}
+			if (!ret)
+				d_delete(dentry);
+			dput(dentry);
+		}
+	}
+	return ret;
+}
+
+/**
+ * tracefs_remove - removes a file or directory from the tracefs filesystem
+ * @dentry: a pointer to a the dentry of the file or directory to be
+ *          removed.
+ *
+ * This function removes a file or directory in tracefs that was previously
+ * created with a call to another tracefs function (like
+ * tracefs_create_file() or variants thereof.)
+ */
+void tracefs_remove(struct dentry *dentry)
+{
+	struct dentry *parent;
+	int ret;
+
+	if (IS_ERR_OR_NULL(dentry))
+		return;
+
+	parent = dentry->d_parent;
+	if (!parent || !parent->d_inode)
+		return;
+
+	mutex_lock(&parent->d_inode->i_mutex);
+	ret = __tracefs_remove(dentry, parent);
+	mutex_unlock(&parent->d_inode->i_mutex);
+	if (!ret)
+		simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+}
+
+/**
+ * tracefs_remove_recursive - recursively removes a directory
+ * @dentry: a pointer to a the dentry of the directory to be removed.
+ *
+ * This function recursively removes a directory tree in tracefs that
+ * was previously created with a call to another tracefs function
+ * (like tracefs_create_file() or variants thereof.)
+ */
+void tracefs_remove_recursive(struct dentry *dentry)
+{
+	struct dentry *child, *parent;
+
+	if (IS_ERR_OR_NULL(dentry))
+		return;
+
+	parent = dentry->d_parent;
+	if (!parent || !parent->d_inode)
+		return;
+
+	parent = dentry;
+ down:
+	mutex_lock(&parent->d_inode->i_mutex);
+ loop:
+	/*
+	 * The parent->d_subdirs is protected by the d_lock. Outside that
+	 * lock, the child can be unlinked and set to be freed which can
+	 * use the d_u.d_child as the rcu head and corrupt this list.
+	 */
+	spin_lock(&parent->d_lock);
+	list_for_each_entry(child, &parent->d_subdirs, d_child) {
+		if (!tracefs_positive(child))
+			continue;
+
+		/* perhaps simple_empty(child) makes more sense */
+		if (!list_empty(&child->d_subdirs)) {
+			spin_unlock(&parent->d_lock);
+			mutex_unlock(&parent->d_inode->i_mutex);
+			parent = child;
+			goto down;
+		}
+
+		spin_unlock(&parent->d_lock);
+
+		if (!__tracefs_remove(child, parent))
+			simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+
+		/*
+		 * The parent->d_lock protects agaist child from unlinking
+		 * from d_subdirs. When releasing the parent->d_lock we can
+		 * no longer trust that the next pointer is valid.
+		 * Restart the loop. We'll skip this one with the
+		 * tracefs_positive() check.
+		 */
+		goto loop;
+	}
+	spin_unlock(&parent->d_lock);
+
+	mutex_unlock(&parent->d_inode->i_mutex);
+	child = parent;
+	parent = parent->d_parent;
+	mutex_lock(&parent->d_inode->i_mutex);
+
+	if (child != dentry)
+		/* go up */
+		goto loop;
+
+	if (!__tracefs_remove(child, parent))
+		simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+	mutex_unlock(&parent->d_inode->i_mutex);
+}
+
+/**
+ * tracefs_initialized - Tells whether tracefs has been registered
+ */
+bool tracefs_initialized(void)
+{
+	return tracefs_registered;
+}
+
+static int __init tracefs_init(void)
+{
+	int retval;
+
+	retval = register_filesystem(&trace_fs_type);
+	if (!retval)
+		tracefs_registered = true;
+
+	return retval;
+}
+core_initcall(tracefs_init);
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
new file mode 100644
index 000000000000..23e04ce21749
--- /dev/null
+++ b/include/linux/tracefs.h
@@ -0,0 +1,41 @@
+/*
+ *  tracefs.h - a pseudo file system for activating tracing
+ *
+ * Based on debugfs by: 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *
+ *  Copyright (C) 2014 Red Hat Inc, author: Steven Rostedt <srostedt@redhat.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License version
+ *	2 as published by the Free Software Foundation.
+ *
+ * tracefs is the file system that is used by the tracing infrastructure.
+ *
+ */
+
+#ifndef _TRACEFS_H_
+#define _TRACEFS_H_
+
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+
+#include <linux/types.h>
+
+struct file_operations;
+
+#ifdef CONFIG_TRACING
+
+struct dentry *tracefs_create_file(const char *name, umode_t mode,
+				   struct dentry *parent, void *data,
+				   const struct file_operations *fops);
+
+struct dentry *tracefs_create_dir(const char *name, struct dentry *parent);
+
+void tracefs_remove(struct dentry *dentry);
+void tracefs_remove_recursive(struct dentry *dentry);
+
+bool tracefs_initialized(void);
+
+#endif /* CONFIG_TRACING */
+
+#endif
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index 7d664ea85ebd..7b1425a6b370 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -58,6 +58,8 @@
 
 #define STACK_END_MAGIC		0x57AC6E9D
 
+#define TRACEFS_MAGIC          0x74726163
+
 #define V9FS_MAGIC		0x01021997
 
 #define BDEVFS_MAGIC            0x62646576
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 13/16 v3] tracing: Convert the tracing facility over to use tracefs
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (11 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 12/16 v3] tracefs: Add new tracefs file system Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 14/16 v3] tracing: Automatically mount tracefs on debugfs/tracing Steven Rostedt
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel; +Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

[-- Attachment #1: 0013-tracing-Convert-the-tracing-facility-over-to-use-tra.patch --]
[-- Type: text/plain, Size: 20220 bytes --]

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

debugfs was fine for the tracing facility as a quick way to get
an interface. Now that tracing has matured, it should separate itself
from debugfs such that it can be mounted separately without needing
to mount all of debugfs with it. That is, users resist using tracing
because it requires mounting debugfs. Having tracing have its own file
system lets users get the features of tracing without needing to bring
in the rest of the kernel's debug infrastructure.

Another reason for tracefs is that debubfs does not support mkdir.
Currently, to create instances, one does a mkdir in the tracing/instance
directory. This is implemented via a hack that forces debugfs to do
something it is not intended on doing. By converting over to tracefs, this
hack can be removed and mkdir can be properly implemented. This patch does
not address this yet, but it lays the ground work for that to be done.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/ftrace.c                | 22 ++++++-------
 kernel/trace/trace.c                 | 61 ++++++++++++++++++++++--------------
 kernel/trace/trace.h                 |  2 +-
 kernel/trace/trace_events.c          | 32 +++++++++----------
 kernel/trace/trace_functions_graph.c |  7 ++---
 kernel/trace/trace_kprobe.c          | 10 +++---
 kernel/trace/trace_probe.h           |  2 +-
 kernel/trace/trace_stat.c            | 10 +++---
 8 files changed, 79 insertions(+), 67 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 80c9d34540dd..e3596de88fc1 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -18,7 +18,7 @@
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
 #include <linux/suspend.h>
-#include <linux/debugfs.h>
+#include <linux/tracefs.h>
 #include <linux/hardirq.h>
 #include <linux/kthread.h>
 #include <linux/uaccess.h>
@@ -1008,7 +1008,7 @@ static struct tracer_stat function_stats __initdata = {
 	.stat_show	= function_stat_show
 };
 
-static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
+static __init void ftrace_profile_tracefs(struct dentry *d_tracer)
 {
 	struct ftrace_profile_stat *stat;
 	struct dentry *entry;
@@ -1044,15 +1044,15 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
 		}
 	}
 
-	entry = debugfs_create_file("function_profile_enabled", 0644,
+	entry = tracefs_create_file("function_profile_enabled", 0644,
 				    d_tracer, NULL, &ftrace_profile_fops);
 	if (!entry)
-		pr_warning("Could not create debugfs "
+		pr_warning("Could not create tracefs "
 			   "'function_profile_enabled' entry\n");
 }
 
 #else /* CONFIG_FUNCTION_PROFILER */
-static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
+static __init void ftrace_profile_tracefs(struct dentry *d_tracer)
 {
 }
 #endif /* CONFIG_FUNCTION_PROFILER */
@@ -4653,7 +4653,7 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops)
 	mutex_unlock(&ftrace_lock);
 }
 
-static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
+static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer)
 {
 
 	trace_create_file("available_filter_functions", 0444,
@@ -4961,7 +4961,7 @@ static int __init ftrace_nodyn_init(void)
 }
 core_initcall(ftrace_nodyn_init);
 
-static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
+static inline int ftrace_init_dyn_tracefs(struct dentry *d_tracer) { return 0; }
 static inline void ftrace_startup_enable(int command) { }
 static inline void ftrace_startup_all(int command) { }
 /* Keep as macros so we do not need to define the commands */
@@ -5414,7 +5414,7 @@ static const struct file_operations ftrace_pid_fops = {
 	.release	= ftrace_pid_release,
 };
 
-static __init int ftrace_init_debugfs(void)
+static __init int ftrace_init_tracefs(void)
 {
 	struct dentry *d_tracer;
 
@@ -5422,16 +5422,16 @@ static __init int ftrace_init_debugfs(void)
 	if (IS_ERR(d_tracer))
 		return 0;
 
-	ftrace_init_dyn_debugfs(d_tracer);
+	ftrace_init_dyn_tracefs(d_tracer);
 
 	trace_create_file("set_ftrace_pid", 0644, d_tracer,
 			    NULL, &ftrace_pid_fops);
 
-	ftrace_profile_debugfs(d_tracer);
+	ftrace_profile_tracefs(d_tracer);
 
 	return 0;
 }
-fs_initcall(ftrace_init_debugfs);
+fs_initcall(ftrace_init_tracefs);
 
 /**
  * ftrace_kill - kill ftrace
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index acd27555dc5b..fb577a2a60ea 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -20,6 +20,7 @@
 #include <linux/notifier.h>
 #include <linux/irqflags.h>
 #include <linux/debugfs.h>
+#include <linux/tracefs.h>
 #include <linux/pagemap.h>
 #include <linux/hardirq.h>
 #include <linux/linkage.h>
@@ -5814,19 +5815,31 @@ static __init int register_snapshot_cmd(void)
 static inline __init int register_snapshot_cmd(void) { return 0; }
 #endif /* defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) */
 
+#define TRACE_TOP_DIR_ENTRY		((struct dentry *)1)
+
 struct dentry *tracing_init_dentry_tr(struct trace_array *tr)
 {
+	/* Top entry does not have a descriptor */
+	if (tr->dir == TRACE_TOP_DIR_ENTRY)
+		return NULL;
+
+	/* All sub buffers do */
 	if (tr->dir)
 		return tr->dir;
 
 	if (!debugfs_initialized())
 		return ERR_PTR(-ENODEV);
 
-	if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
+	if (tr->flags & TRACE_ARRAY_FL_GLOBAL) {
 		tr->dir = debugfs_create_dir("tracing", NULL);
+		tr->dir = TRACE_TOP_DIR_ENTRY;
+		return NULL;
+	}
 
-	if (!tr->dir)
+	if (!tr->dir) {
 		pr_warn_once("Could not create debugfs directory 'tracing'\n");
+		return ERR_PTR(-ENOMEM);
+	}
 
 	return tr->dir;
 }
@@ -5847,10 +5860,10 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu)
 	if (IS_ERR(d_tracer))
 		return NULL;
 
-	tr->percpu_dir = debugfs_create_dir("per_cpu", d_tracer);
+	tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer);
 
 	WARN_ONCE(!tr->percpu_dir,
-		  "Could not create debugfs directory 'per_cpu/%d'\n", cpu);
+		  "Could not create tracefs directory 'per_cpu/%d'\n", cpu);
 
 	return tr->percpu_dir;
 }
@@ -5867,7 +5880,7 @@ trace_create_cpu_file(const char *name, umode_t mode, struct dentry *parent,
 }
 
 static void
-tracing_init_debugfs_percpu(struct trace_array *tr, long cpu)
+tracing_init_tracefs_percpu(struct trace_array *tr, long cpu)
 {
 	struct dentry *d_percpu = tracing_dentry_percpu(tr, cpu);
 	struct dentry *d_cpu;
@@ -5877,9 +5890,9 @@ tracing_init_debugfs_percpu(struct trace_array *tr, long cpu)
 		return;
 
 	snprintf(cpu_dir, 30, "cpu%ld", cpu);
-	d_cpu = debugfs_create_dir(cpu_dir, d_percpu);
+	d_cpu = tracefs_create_dir(cpu_dir, d_percpu);
 	if (!d_cpu) {
-		pr_warning("Could not create debugfs '%s' entry\n", cpu_dir);
+		pr_warning("Could not create tracefs '%s' entry\n", cpu_dir);
 		return;
 	}
 
@@ -6031,9 +6044,9 @@ struct dentry *trace_create_file(const char *name,
 {
 	struct dentry *ret;
 
-	ret = debugfs_create_file(name, mode, parent, data, fops);
+	ret = tracefs_create_file(name, mode, parent, data, fops);
 	if (!ret)
-		pr_warning("Could not create debugfs '%s' entry\n", name);
+		pr_warning("Could not create tracefs '%s' entry\n", name);
 
 	return ret;
 }
@@ -6050,9 +6063,9 @@ static struct dentry *trace_options_init_dentry(struct trace_array *tr)
 	if (IS_ERR(d_tracer))
 		return NULL;
 
-	tr->options = debugfs_create_dir("options", d_tracer);
+	tr->options = tracefs_create_dir("options", d_tracer);
 	if (!tr->options) {
-		pr_warning("Could not create debugfs directory 'options'\n");
+		pr_warning("Could not create tracefs directory 'options'\n");
 		return NULL;
 	}
 
@@ -6121,7 +6134,7 @@ destroy_trace_option_files(struct trace_option_dentry *topts)
 		return;
 
 	for (cnt = 0; topts[cnt].opt; cnt++)
-		debugfs_remove(topts[cnt].entry);
+		tracefs_remove(topts[cnt].entry);
 
 	kfree(topts);
 }
@@ -6210,7 +6223,7 @@ static const struct file_operations rb_simple_fops = {
 struct dentry *trace_instance_dir;
 
 static void
-init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer);
+init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer);
 
 static int
 allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size)
@@ -6326,17 +6339,17 @@ static int new_instance_create(const char *name)
 	if (allocate_trace_buffers(tr, trace_buf_size) < 0)
 		goto out_free_tr;
 
-	tr->dir = debugfs_create_dir(name, trace_instance_dir);
+	tr->dir = tracefs_create_dir(name, trace_instance_dir);
 	if (!tr->dir)
 		goto out_free_tr;
 
 	ret = event_trace_add_tracer(tr->dir, tr);
 	if (ret) {
-		debugfs_remove_recursive(tr->dir);
+		tracefs_remove_recursive(tr->dir);
 		goto out_free_tr;
 	}
 
-	init_tracer_debugfs(tr, tr->dir);
+	init_tracer_tracefs(tr, tr->dir);
 
 	list_add(&tr->list, &ftrace_trace_arrays);
 
@@ -6409,7 +6422,7 @@ static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t m
 		return -ENOENT;
 
 	/*
-	 * The inode mutex is locked, but debugfs_create_dir() will also
+	 * The inode mutex is locked, but tracefs_create_dir() will also
 	 * take the mutex. As the instances directory can not be destroyed
 	 * or changed in any other way, it is safe to unlock it, and
 	 * let the dentry try. If two users try to make the same dir at
@@ -6439,7 +6452,7 @@ static int instance_rmdir(struct inode *inode, struct dentry *dentry)
 	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	/*
-	 * The inode mutex is locked, but debugfs_create_dir() will also
+	 * The inode mutex is locked, but tracefs_create_dir() will also
 	 * take the mutex. As the instances directory can not be destroyed
 	 * or changed in any other way, it is safe to unlock it, and
 	 * let the dentry try. If two users try to make the same dir at
@@ -6464,7 +6477,7 @@ static const struct inode_operations instance_dir_inode_operations = {
 
 static __init void create_trace_instances(struct dentry *d_tracer)
 {
-	trace_instance_dir = debugfs_create_dir("instances", d_tracer);
+	trace_instance_dir = tracefs_create_dir("instances", d_tracer);
 	if (WARN_ON(!trace_instance_dir))
 		return;
 
@@ -6473,7 +6486,7 @@ static __init void create_trace_instances(struct dentry *d_tracer)
 }
 
 static void
-init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer)
+init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
 {
 	int cpu;
 
@@ -6527,11 +6540,11 @@ init_tracer_debugfs(struct trace_array *tr, struct dentry *d_tracer)
 #endif
 
 	for_each_tracing_cpu(cpu)
-		tracing_init_debugfs_percpu(tr, cpu);
+		tracing_init_tracefs_percpu(tr, cpu);
 
 }
 
-static __init int tracer_init_debugfs(void)
+static __init int tracer_init_tracefs(void)
 {
 	struct dentry *d_tracer;
 
@@ -6541,7 +6554,7 @@ static __init int tracer_init_debugfs(void)
 	if (IS_ERR(d_tracer))
 		return 0;
 
-	init_tracer_debugfs(&global_trace, d_tracer);
+	init_tracer_tracefs(&global_trace, d_tracer);
 
 	trace_create_file("tracing_thresh", 0644, d_tracer,
 			&global_trace, &tracing_thresh_fops);
@@ -6901,5 +6914,5 @@ __init static int clear_boot_tracer(void)
 	return 0;
 }
 
-fs_initcall(tracer_init_debugfs);
+fs_initcall(tracer_init_tracefs);
 late_initcall(clear_boot_tracer);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 0eddfeb05fee..ba1170cb4880 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -334,7 +334,7 @@ struct tracer_flags {
 
 
 /**
- * struct tracer - a specific tracer and its callbacks to interact with debugfs
+ * struct tracer - a specific tracer and its callbacks to interact with tracefs
  * @name: the name chosen to select it on the available_tracers file
  * @init: called when one switches to this tracer (echo name > current_tracer)
  * @reset: called when one switches to another tracer
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 4ff8c1394017..e3b7782f904f 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -13,7 +13,7 @@
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
 #include <linux/kthread.h>
-#include <linux/debugfs.h>
+#include <linux/tracefs.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
 #include <linux/ctype.h>
@@ -480,7 +480,7 @@ static void remove_subsystem(struct ftrace_subsystem_dir *dir)
 		return;
 
 	if (!--dir->nr_events) {
-		debugfs_remove_recursive(dir->entry);
+		tracefs_remove_recursive(dir->entry);
 		list_del(&dir->list);
 		__put_system_dir(dir);
 	}
@@ -499,7 +499,7 @@ static void remove_event_file_dir(struct ftrace_event_file *file)
 		}
 		spin_unlock(&dir->d_lock);
 
-		debugfs_remove_recursive(dir);
+		tracefs_remove_recursive(dir);
 	}
 
 	list_del(&file->list);
@@ -1526,7 +1526,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
 	} else
 		__get_system(system);
 
-	dir->entry = debugfs_create_dir(name, parent);
+	dir->entry = tracefs_create_dir(name, parent);
 	if (!dir->entry) {
 		pr_warn("Failed to create system directory %s\n", name);
 		__put_system(system);
@@ -1539,12 +1539,12 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
 	dir->subsystem = system;
 	file->system = dir;
 
-	entry = debugfs_create_file("filter", 0644, dir->entry, dir,
+	entry = tracefs_create_file("filter", 0644, dir->entry, dir,
 				    &ftrace_subsystem_filter_fops);
 	if (!entry) {
 		kfree(system->filter);
 		system->filter = NULL;
-		pr_warn("Could not create debugfs '%s/filter' entry\n", name);
+		pr_warn("Could not create tracefs '%s/filter' entry\n", name);
 	}
 
 	trace_create_file("enable", 0644, dir->entry, dir,
@@ -1585,9 +1585,9 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file)
 		d_events = parent;
 
 	name = ftrace_event_name(call);
-	file->dir = debugfs_create_dir(name, d_events);
+	file->dir = tracefs_create_dir(name, d_events);
 	if (!file->dir) {
-		pr_warn("Could not create debugfs '%s' directory\n", name);
+		pr_warn("Could not create tracefs '%s' directory\n", name);
 		return -1;
 	}
 
@@ -2228,7 +2228,7 @@ static inline int register_event_cmds(void) { return 0; }
 /*
  * The top level array has already had its ftrace_event_file
  * descriptors created in order to allow for early events to
- * be recorded. This function is called after the debugfs has been
+ * be recorded. This function is called after the tracefs has been
  * initialized, and we now have to create the files associated
  * to the events.
  */
@@ -2311,16 +2311,16 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
 	struct dentry *d_events;
 	struct dentry *entry;
 
-	entry = debugfs_create_file("set_event", 0644, parent,
+	entry = tracefs_create_file("set_event", 0644, parent,
 				    tr, &ftrace_set_event_fops);
 	if (!entry) {
-		pr_warn("Could not create debugfs 'set_event' entry\n");
+		pr_warn("Could not create tracefs 'set_event' entry\n");
 		return -ENOMEM;
 	}
 
-	d_events = debugfs_create_dir("events", parent);
+	d_events = tracefs_create_dir("events", parent);
 	if (!d_events) {
-		pr_warn("Could not create debugfs 'events' directory\n");
+		pr_warn("Could not create tracefs 'events' directory\n");
 		return -ENOMEM;
 	}
 
@@ -2412,7 +2412,7 @@ int event_trace_del_tracer(struct trace_array *tr)
 
 	down_write(&trace_event_sem);
 	__trace_remove_event_dirs(tr);
-	debugfs_remove_recursive(tr->event_dir);
+	tracefs_remove_recursive(tr->event_dir);
 	up_write(&trace_event_sem);
 
 	tr->event_dir = NULL;
@@ -2493,10 +2493,10 @@ static __init int event_trace_init(void)
 	if (IS_ERR(d_tracer))
 		return 0;
 
-	entry = debugfs_create_file("available_events", 0444, d_tracer,
+	entry = tracefs_create_file("available_events", 0444, d_tracer,
 				    tr, &ftrace_avail_fops);
 	if (!entry)
-		pr_warn("Could not create debugfs 'available_events' entry\n");
+		pr_warn("Could not create tracefs 'available_events' entry\n");
 
 	if (trace_define_common_fields())
 		pr_warn("tracing: Failed to allocate common fields");
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 2d25ad1526bb..9cfea4c6d314 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -6,7 +6,6 @@
  * is Copyright (c) Steven Rostedt <srostedt@redhat.com>
  *
  */
-#include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/ftrace.h>
 #include <linux/slab.h>
@@ -151,7 +150,7 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
 	 * The curr_ret_stack is initialized to -1 and get increased
 	 * in this function.  So it can be less than -1 only if it was
 	 * filtered out via ftrace_graph_notrace_addr() which can be
-	 * set from set_graph_notrace file in debugfs by user.
+	 * set from set_graph_notrace file in tracefs by user.
 	 */
 	if (current->curr_ret_stack < -1)
 		return -EBUSY;
@@ -1432,7 +1431,7 @@ static const struct file_operations graph_depth_fops = {
 	.llseek		= generic_file_llseek,
 };
 
-static __init int init_graph_debugfs(void)
+static __init int init_graph_tracefs(void)
 {
 	struct dentry *d_tracer;
 
@@ -1445,7 +1444,7 @@ static __init int init_graph_debugfs(void)
 
 	return 0;
 }
-fs_initcall(init_graph_debugfs);
+fs_initcall(init_graph_tracefs);
 
 static __init int init_graph_trace(void)
 {
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index b4a00def88f5..c1c6655847c8 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1310,7 +1310,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk)
 	return ret;
 }
 
-/* Make a debugfs interface for controlling probe points */
+/* Make a tracefs interface for controlling probe points */
 static __init int init_kprobe_trace(void)
 {
 	struct dentry *d_tracer;
@@ -1323,20 +1323,20 @@ static __init int init_kprobe_trace(void)
 	if (IS_ERR(d_tracer))
 		return 0;
 
-	entry = debugfs_create_file("kprobe_events", 0644, d_tracer,
+	entry = tracefs_create_file("kprobe_events", 0644, d_tracer,
 				    NULL, &kprobe_events_ops);
 
 	/* Event list interface */
 	if (!entry)
-		pr_warning("Could not create debugfs "
+		pr_warning("Could not create tracefs "
 			   "'kprobe_events' entry\n");
 
 	/* Profile interface */
-	entry = debugfs_create_file("kprobe_profile", 0444, d_tracer,
+	entry = tracefs_create_file("kprobe_profile", 0444, d_tracer,
 				    NULL, &kprobe_profile_ops);
 
 	if (!entry)
-		pr_warning("Could not create debugfs "
+		pr_warning("Could not create tracefs "
 			   "'kprobe_profile' entry\n");
 	return 0;
 }
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index 4f815fbce16d..19aff635841a 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -25,7 +25,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
-#include <linux/debugfs.h>
+#include <linux/tracefs.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index 75e19e86c954..6cf935316769 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -12,7 +12,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/rbtree.h>
-#include <linux/debugfs.h>
+#include <linux/tracefs.h>
 #include "trace_stat.h"
 #include "trace.h"
 
@@ -65,7 +65,7 @@ static void reset_stat_session(struct stat_session *session)
 
 static void destroy_session(struct stat_session *session)
 {
-	debugfs_remove(session->file);
+	tracefs_remove(session->file);
 	__reset_stat_session(session);
 	mutex_destroy(&session->stat_mutex);
 	kfree(session);
@@ -279,9 +279,9 @@ static int tracing_stat_init(void)
 	if (IS_ERR(d_tracing))
 		return 0;
 
-	stat_dir = debugfs_create_dir("trace_stat", d_tracing);
+	stat_dir = tracefs_create_dir("trace_stat", d_tracing);
 	if (!stat_dir)
-		pr_warning("Could not create debugfs "
+		pr_warning("Could not create tracefs "
 			   "'trace_stat' entry\n");
 	return 0;
 }
@@ -291,7 +291,7 @@ static int init_stat_file(struct stat_session *session)
 	if (!stat_dir && tracing_stat_init())
 		return -ENODEV;
 
-	session->file = debugfs_create_file(session->ts->name, 0644,
+	session->file = tracefs_create_file(session->ts->name, 0644,
 					    stat_dir,
 					    session, &tracing_stat_fops);
 	if (!session->file)
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 14/16 v3] tracing: Automatically mount tracefs on debugfs/tracing
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (12 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 13/16 v3] tracing: Convert the tracing facility over to use tracefs Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 15/16 v3] tracefs: Add directory /sys/kernel/tracing Steven Rostedt
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0014-tracing-Automatically-mount-tracefs-on-debugfs-traci.patch --]
[-- Type: text/plain, Size: 2840 bytes --]

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

As tools currently rely on the tracing directory in debugfs, we can not
just created a tracefs infrastructure and expect sysadmins to mount
the new tracefs to have their old tools work.

Instead, the debugfs tracing directory is still created and the tracefs
file system is mounted there when the debugfs filesystem is mounted.

No longer does the tracing infrastructure update the debugfs file system,
but instead interacts with the tracefs file system. But now, it still
appears to the user like nothing changed, except you also have the feature
of mounting just the tracing system without needing all of debugfs!

Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index fb577a2a60ea..623791e15966 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -32,6 +32,7 @@
 #include <linux/splice.h>
 #include <linux/kdebug.h>
 #include <linux/string.h>
+#include <linux/mount.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
@@ -5815,10 +5816,34 @@ static __init int register_snapshot_cmd(void)
 static inline __init int register_snapshot_cmd(void) { return 0; }
 #endif /* defined(CONFIG_TRACER_SNAPSHOT) && defined(CONFIG_DYNAMIC_FTRACE) */
 
+static struct vfsmount *trace_automount(void *ingore)
+{
+	struct vfsmount *mnt;
+	struct file_system_type *type;
+
+	/*
+	 * To maintain backward compatibility for tools that mount
+	 * debugfs to get to the tracing facility, tracefs is automatically
+	 * mounted to the debugfs/tracing directory.
+	 */
+	type = get_fs_type("tracefs");
+	if (!type)
+		return NULL;
+	mnt = vfs_kern_mount(type, 0, "tracefs", NULL);
+	put_filesystem(type);
+	if (IS_ERR(mnt))
+		return NULL;
+	mntget(mnt);
+
+	return mnt;
+}
+
 #define TRACE_TOP_DIR_ENTRY		((struct dentry *)1)
 
 struct dentry *tracing_init_dentry_tr(struct trace_array *tr)
 {
+	struct dentry *traced;
+
 	/* Top entry does not have a descriptor */
 	if (tr->dir == TRACE_TOP_DIR_ENTRY)
 		return NULL;
@@ -5831,7 +5856,16 @@ struct dentry *tracing_init_dentry_tr(struct trace_array *tr)
 		return ERR_PTR(-ENODEV);
 
 	if (tr->flags & TRACE_ARRAY_FL_GLOBAL) {
-		tr->dir = debugfs_create_dir("tracing", NULL);
+		/*
+		 * As there may still be users that expect the tracing
+		 * files to exist in debugfs/tracing, we must automount
+		 * the tracefs file system there, so older tools still
+		 * work with the newer kerenl.
+		 */
+		traced = debugfs_create_automount("tracing", NULL,
+						  trace_automount, NULL);
+		if (!traced)
+			return ERR_PTR(-ENOMEM);
 		tr->dir = TRACE_TOP_DIR_ENTRY;
 		return NULL;
 	}
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 15/16 v3] tracefs: Add directory /sys/kernel/tracing
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (13 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 14/16 v3] tracing: Automatically mount tracefs on debugfs/tracing Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 15:09 ` [PATCH 16/16 v3] tracing: Have mkdir and rmdir be part of tracefs Steven Rostedt
  2015-01-26 19:30 ` [PATCH 00/16 v3] tracing: Add new file system tracefs Al Viro
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel; +Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

[-- Attachment #1: 0015-tracefs-Add-directory-sys-kernel-tracing.patch --]
[-- Type: text/plain, Size: 1184 bytes --]

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

When tracefs is configured, have the directory /sys/kernel/tracing appear
just like /sys/kernel/debug appears when debugfs is configured.

This will give a consistent place for system admins to mount tracefs.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 fs/tracefs/inode.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index c31997a303c7..cdbaa42b44a1 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
+#include <linux/kobject.h>
 #include <linux/namei.h>
 #include <linux/tracefs.h>
 #include <linux/fsnotify.h>
@@ -547,10 +548,16 @@ bool tracefs_initialized(void)
 	return tracefs_registered;
 }
 
+static struct kobject *trace_kobj;
+
 static int __init tracefs_init(void)
 {
 	int retval;
 
+	trace_kobj = kobject_create_and_add("tracing", kernel_kobj);
+	if (!trace_kobj)
+		return -EINVAL;
+
 	retval = register_filesystem(&trace_fs_type);
 	if (!retval)
 		tracefs_registered = true;
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 16/16 v3] tracing: Have mkdir and rmdir be part of tracefs
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (14 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 15/16 v3] tracefs: Add directory /sys/kernel/tracing Steven Rostedt
@ 2015-01-26 15:09 ` Steven Rostedt
  2015-01-26 19:30 ` [PATCH 00/16 v3] tracing: Add new file system tracefs Al Viro
  16 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 15:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Al Viro, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton, Al Viro

[-- Attachment #1: 0016-tracing-Have-mkdir-and-rmdir-be-part-of-tracefs.patch --]
[-- Type: text/plain, Size: 8387 bytes --]

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

The tracing "instances" directory can create sub tracing buffers
with mkdir, and remove them with rmdir. As a mkdir will also create
all the files and directories that control the sub buffer the inode
mutexes need to be released before this is done, to avoid deadlocks.
It is better to let the tracing system unlock the inode mutexes before
calling the functions that create the files within the new directory
(or deletes the files from the one being destroyed).

Now that tracing has been converted over to tracefs, the tracefs file
system can be modified to accommodate this feature. It still releases
the locks, but the filesystem itself can take care of the ugly
business and let the user just do what it needs.

The tracing system now attaches a descriptor to the directory dentry
that can have userspace create or remove sub directories. If this
descriptor does not exist for a dentry, then that dentry can not be
used to create other directories. This descriptor holds a mkdir and
rmdir method that only takes a character string as an argument.

The tracefs file system will first make a copy of the dentry name
before releasing the locks. Then it will pass the copied name to the
methods. It is up to the tracing system that supplied the methods to
handle races with duplicate names and such as all the inode mutexes
would be released when the functions are called.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 fs/tracefs/inode.c      | 93 ++++++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/tracefs.h |  7 ++++
 kernel/trace/trace.c    | 68 +++---------------------------------
 3 files changed, 103 insertions(+), 65 deletions(-)

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index cdbaa42b44a1..a005b951fd85 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -50,6 +50,87 @@ static const struct file_operations tracefs_file_operations = {
 	.llseek =	noop_llseek,
 };
 
+static char *get_dname(struct dentry *dentry)
+{
+	const char *dname;
+	char *name;
+	int len = dentry->d_name.len;
+
+	dname = dentry->d_name.name;
+	name = kmalloc(len + 1, GFP_KERNEL);
+	if (!name)
+		return NULL;
+	memcpy(name, dname, len);
+	name[len] = 0;
+	return name;
+}
+
+static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode)
+{
+	const struct tracefs_dir_ops *ops = inode ? inode->i_private : NULL;
+	char *name;
+	int ret;
+
+	if (!ops)
+		return -EPERM;
+
+	name = get_dname(dentry);
+	if (!name)
+		return -ENOMEM;
+
+	/*
+	 * The mkdir call can call the generic functions that create
+	 * the files within the tracefs system. It is up to the individual
+	 * mkdir routine to handle races.
+	 */
+	mutex_unlock(&inode->i_mutex);
+	ret = ops->mkdir(name);
+	mutex_lock(&inode->i_mutex);
+
+	kfree(name);
+
+	return ret;
+}
+
+static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
+{
+	const struct tracefs_dir_ops *ops = inode->i_private;
+	char *name;
+	int ret;
+
+	if (!ops)
+		return -EPERM;
+
+	name = get_dname(dentry);
+	if (!name)
+		return -ENOMEM;
+
+	/*
+	 * The rmdir call can call the generic functions that create
+	 * the files within the tracefs system. It is up to the individual
+	 * rmdir routine to handle races.
+	 * This time we need to unlock not only the parent (inode) but
+	 * also the directory that is being deleted.
+	 */
+	mutex_unlock(&inode->i_mutex);
+	mutex_unlock(&dentry->d_inode->i_mutex);
+
+	ret = ops->rmdir(name);
+
+	mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+	mutex_lock(&dentry->d_inode->i_mutex);
+
+	kfree(name);
+
+	return ret;
+}
+
+const struct inode_operations tracefs_dir_inode_operations = {
+	.lookup		= simple_lookup,
+	.mkdir		= tracefs_syscall_mkdir,
+	.rmdir		= tracefs_syscall_rmdir,
+};
+
 static struct inode *tracefs_get_inode(struct super_block *sb, umode_t mode, dev_t dev,
 				      void *data, const struct file_operations *fops)
 
@@ -69,7 +150,7 @@ static struct inode *tracefs_get_inode(struct super_block *sb, umode_t mode, dev
 			inode->i_private = data;
 			break;
 		case S_IFDIR:
-			inode->i_op = &simple_dir_inode_operations;
+			inode->i_op = &tracefs_dir_inode_operations;
 			inode->i_fop = &simple_dir_operations;
 
 			/* directory inodes start off with i_nlink == 2
@@ -125,6 +206,16 @@ static int tracefs_create(struct inode *dir, struct dentry *dentry, umode_t mode
 	return res;
 }
 
+void tracefs_add_dir_ops(struct dentry *dentry, const struct tracefs_dir_ops *ops)
+{
+	struct inode *inode = dentry->d_inode;
+
+	if (!inode)
+		return;
+
+	inode->i_private = (void *)ops;
+}
+
 struct tracefs_mount_opts {
 	kuid_t uid;
 	kgid_t gid;
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 23e04ce21749..d142b1f9d453 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -34,6 +34,13 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent);
 void tracefs_remove(struct dentry *dentry);
 void tracefs_remove_recursive(struct dentry *dentry);
 
+struct tracefs_dir_ops {
+	int (*mkdir)(const char *name);
+	int (*rmdir)(const char *name);
+};
+
+void tracefs_add_dir_ops(struct dentry *dentry, const struct tracefs_dir_ops *ops);
+
 bool tracefs_initialized(void);
 
 #endif /* CONFIG_TRACING */
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 623791e15966..c555027c8aaf 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6334,7 +6334,7 @@ static void free_trace_buffers(struct trace_array *tr)
 #endif
 }
 
-static int new_instance_create(const char *name)
+static int instance_mkdir(const char *name)
 {
 	struct trace_array *tr;
 	int ret;
@@ -6404,7 +6404,7 @@ static int new_instance_create(const char *name)
 
 }
 
-static int instance_delete(const char *name)
+static int instance_rmdir(const char *name)
 {
 	struct trace_array *tr;
 	int found = 0;
@@ -6445,66 +6445,7 @@ static int instance_delete(const char *name)
 	return ret;
 }
 
-static int instance_mkdir (struct inode *inode, struct dentry *dentry, umode_t mode)
-{
-	struct dentry *parent;
-	int ret;
-
-	/* Paranoid: Make sure the parent is the "instances" directory */
-	parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
-	if (WARN_ON_ONCE(parent != trace_instance_dir))
-		return -ENOENT;
-
-	/*
-	 * The inode mutex is locked, but tracefs_create_dir() will also
-	 * take the mutex. As the instances directory can not be destroyed
-	 * or changed in any other way, it is safe to unlock it, and
-	 * let the dentry try. If two users try to make the same dir at
-	 * the same time, then the new_instance_create() will determine the
-	 * winner.
-	 */
-	mutex_unlock(&inode->i_mutex);
-
-	ret = new_instance_create(dentry->d_iname);
-
-	mutex_lock(&inode->i_mutex);
-
-	return ret;
-}
-
-static int instance_rmdir(struct inode *inode, struct dentry *dentry)
-{
-	struct dentry *parent;
-	int ret;
-
-	/* Paranoid: Make sure the parent is the "instances" directory */
-	parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
-	if (WARN_ON_ONCE(parent != trace_instance_dir))
-		return -ENOENT;
-
-	/* The caller did a dget() on dentry */
-	mutex_unlock(&dentry->d_inode->i_mutex);
-
-	/*
-	 * The inode mutex is locked, but tracefs_create_dir() will also
-	 * take the mutex. As the instances directory can not be destroyed
-	 * or changed in any other way, it is safe to unlock it, and
-	 * let the dentry try. If two users try to make the same dir at
-	 * the same time, then the instance_delete() will determine the
-	 * winner.
-	 */
-	mutex_unlock(&inode->i_mutex);
-
-	ret = instance_delete(dentry->d_iname);
-
-	mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
-	mutex_lock(&dentry->d_inode->i_mutex);
-
-	return ret;
-}
-
-static const struct inode_operations instance_dir_inode_operations = {
-	.lookup		= simple_lookup,
+static const struct tracefs_dir_ops instance_dir_ops = {
 	.mkdir		= instance_mkdir,
 	.rmdir		= instance_rmdir,
 };
@@ -6515,8 +6456,7 @@ static __init void create_trace_instances(struct dentry *d_tracer)
 	if (WARN_ON(!trace_instance_dir))
 		return;
 
-	/* Hijack the dir inode operations, to allow mkdir */
-	trace_instance_dir->d_inode->i_op = &instance_dir_inode_operations;
+	tracefs_add_dir_ops(trace_instance_dir, &instance_dir_ops);
 }
 
 static void
-- 
2.1.4



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
                   ` (15 preceding siblings ...)
  2015-01-26 15:09 ` [PATCH 16/16 v3] tracing: Have mkdir and rmdir be part of tracefs Steven Rostedt
@ 2015-01-26 19:30 ` Al Viro
  2015-01-26 20:42   ` Steven Rostedt
  2015-01-26 21:40   ` Al Viro
  16 siblings, 2 replies; 40+ messages in thread
From: Al Viro @ 2015-01-26 19:30 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 10:09:13AM -0500, Steven Rostedt wrote:
> There has been complaints that tracing is tied too much to debugfs,
> as there are systems that would like to perform tracing, but do
> not mount debugfs for security reasons. That is because any subsystem
> may use debugfs for debugging, and these interfaces are not always
> tested for security.
> 
> Creating a new tracefs that the tracing directory will now be attached
> to allows system admins the ability to access the tracing directory
> without the need to mount debugfs.
> 
> Another advantage is that debugfs does not support the system calls
> for mkdir and rmdir. Tracing uses these system calls to create new
> instances for sub buffers. This was done by a hack that hijacked the
> dentry ops from the "instances" debugfs dentry, and replacing it with
> one that could work.
> 
> Instead of using this hack, tracefs can provide a proper interface to
> allow the tracing system to have a mkdir and rmdir feature.
> 
> To maintain backward compatibility with older tools that expect that
> the tracing directory is mounted with debugfs, the tracing directory
> is still created under debugfs and tracefs is automatically mounted
> there.
> 
> Finally, a new directory is created when tracefs is enabled called
> /sys/kernel/tracing. This will be the new location that system admins
> may mount tracefs if they are not using debugfs.

You are still fighting an inconvenient API, but now it's not debugfs one -
it's your copy thereof.  Why not give your instances/ an inode_operations
of its own?  One with ->mkdir() and ->rmdir(), leaving all other directories
as-is.  That way you don't need the secondary methods at all.  And sure,
debugfs_create_dir() grabs ->i_mutex on parent, making you drop that in
your ->mkdir() if you want to call it.  But now you are not talking to it -
just to your own code, where you are free to change the calling conventions,
making it caller's responsibility to get that ->i_mutex.  The same goes for
the rmdir side...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 19:30 ` [PATCH 00/16 v3] tracing: Add new file system tracefs Al Viro
@ 2015-01-26 20:42   ` Steven Rostedt
  2015-01-26 20:44     ` Steven Rostedt
  2015-01-26 21:46     ` Al Viro
  2015-01-26 21:40   ` Al Viro
  1 sibling, 2 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 20:42 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 19:30:49 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> You are still fighting an inconvenient API, but now it's not debugfs one -
> it's your copy thereof.  Why not give your instances/ an inode_operations
> of its own?  One with ->mkdir() and ->rmdir(), leaving all other directories
> as-is.  That way you don't need the secondary methods at all.  And sure,
> debugfs_create_dir() grabs ->i_mutex on parent, making you drop that in
> your ->mkdir() if you want to call it.  But now you are not talking to it -
> just to your own code, where you are free to change the calling conventions,
> making it caller's responsibility to get that ->i_mutex.  The same goes for
> the rmdir side...

The vfs layer grabs the i_mutex, which needs to be dropped. I was
hoping to keep the dropping of the i_mutex within the tracefs code and
not have the tracing code worry about it. I still will need to add
i_private to hold this info.

But that said, I could clean it up a little be having a
tracefs_create_instance_dir(), which does all the work within the
tracefs code. The caller would pass in the functions to be called by
that.

Like this patch applied on top of my current series:

-- Steve

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index c7eb4c58579e..13e17bf677f4 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -50,6 +50,11 @@ static const struct file_operations tracefs_file_operations = {
 	.llseek =	noop_llseek,
 };
 
+struct tracefs_dir_ops {
+	int (*mkdir)(const char *name);
+	int (*rmdir)(const char *name);
+};
+
 static char *get_dname(struct dentry *dentry)
 {
 	const char *dname;
@@ -67,13 +72,10 @@ static char *get_dname(struct dentry *dentry)
 
 static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode)
 {
-	const struct tracefs_dir_ops *ops = inode ? inode->i_private : NULL;
+	const struct tracefs_dir_ops *ops = inode->i_private;
 	char *name;
 	int ret;
 
-	if (!ops)
-		return -EPERM;
-
 	name = get_dname(dentry);
 	if (!name)
 		return -ENOMEM;
@@ -98,9 +100,6 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
 	char *name;
 	int ret;
 
-	if (!ops)
-		return -EPERM;
-
 	name = get_dname(dentry);
 	if (!name)
 		return -ENOMEM;
@@ -317,16 +316,6 @@ static struct file_system_type trace_fs_type = {
 };
 MODULE_ALIAS_FS("tracefs");
 
-void tracefs_add_dir_ops(struct dentry *dentry, const struct tracefs_dir_ops *ops)
-{
-	struct inode *inode = dentry->d_inode;
-
-	if (!inode)
-		return;
-
-	inode->i_private = (void *)ops;
-}
-
 static struct dentry *start_creating(const char *name, struct dentry *parent)
 {
 	struct dentry *dentry;
@@ -425,6 +414,31 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
 	return end_creating(dentry);
 }
 
+static struct dentry *__create_dir(const char *name, struct dentry *parent,
+				   const struct inode_operations *ops)
+{
+	struct dentry *dentry = start_creating(name, parent);
+	struct inode *inode;
+
+	if (IS_ERR(dentry))
+		return NULL;
+
+	inode = tracefs_get_inode(dentry->d_sb);
+	if (unlikely(!inode))
+		return failed_creating(dentry);
+
+	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+	inode->i_op = ops;
+	inode->i_fop = &simple_dir_operations;
+
+	/* directory inodes start off with i_nlink == 2 (for "." entry) */
+	inc_nlink(inode);
+	d_instantiate(dentry, inode);
+	inc_nlink(dentry->d_parent->d_inode);
+	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+	return end_creating(dentry);
+}
+
 /**
  * tracefs_create_dir - create a directory in the tracefs filesystem
  * @name: a pointer to a string containing the name of the directory to
@@ -444,26 +458,30 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
  */
 struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
 {
-	struct dentry *dentry = start_creating(name, parent);
-	struct inode *inode;
+	return __create_dir(name, parent, &simple_dir_inode_operations);
+}
 
-	if (IS_ERR(dentry))
+struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
+					  int (*mkdir)(const char *name),
+					  int (*rmdir)(const char *name))
+{
+	struct tracefs_dir_ops *dir_ops;
+	struct dentry *dentry;
+
+	dir_ops = kmalloc(sizeof(*dir_ops), GFP_KERNEL);
+	if (!dir_ops)
 		return NULL;
 
-	inode = tracefs_get_inode(dentry->d_sb);
-	if (unlikely(!inode))
-		return failed_creating(dentry);
+	dir_ops->mkdir = mkdir;
+	dir_ops->rmdir = mkdir;
 
-	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
-	inode->i_op = &tracefs_dir_inode_operations;
-	inode->i_fop = &simple_dir_operations;
+	dentry = __create_dir(name, parent, &tracefs_dir_inode_operations);
+	if (!dentry)
+		return NULL;
 
-	/* directory inodes start off with i_nlink == 2 (for "." entry) */
-	inc_nlink(inode);
-	d_instantiate(dentry, inode);
-	inc_nlink(dentry->d_parent->d_inode);
-	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
-	return end_creating(dentry);
+	dentry->d_inode->i_private = (void *)dir_ops;
+
+	return dentry;
 }
 
 static inline int tracefs_positive(struct dentry *dentry)
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index d142b1f9d453..5b727a17beee 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -34,12 +34,9 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent);
 void tracefs_remove(struct dentry *dentry);
 void tracefs_remove_recursive(struct dentry *dentry);
 
-struct tracefs_dir_ops {
-	int (*mkdir)(const char *name);
-	int (*rmdir)(const char *name);
-};
-
-void tracefs_add_dir_ops(struct dentry *dentry, const struct tracefs_dir_ops *ops);
+struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
+					   int (*mkdir)(const char *name),
+					   int (*rmdir)(const char *name));
 
 bool tracefs_initialized(void);
 
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c555027c8aaf..2047501dcd16 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6445,18 +6445,13 @@ static int instance_rmdir(const char *name)
 	return ret;
 }
 
-static const struct tracefs_dir_ops instance_dir_ops = {
-	.mkdir		= instance_mkdir,
-	.rmdir		= instance_rmdir,
-};
-
 static __init void create_trace_instances(struct dentry *d_tracer)
 {
-	trace_instance_dir = tracefs_create_dir("instances", d_tracer);
+	trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer,
+							 instance_mkdir,
+							 instance_rmdir);
 	if (WARN_ON(!trace_instance_dir))
 		return;
-
-	tracefs_add_dir_ops(trace_instance_dir, &instance_dir_ops);
 }
 
 static void

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 20:42   ` Steven Rostedt
@ 2015-01-26 20:44     ` Steven Rostedt
  2015-01-26 20:58       ` Steven Rostedt
  2015-01-26 21:46     ` Al Viro
  1 sibling, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 20:44 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 15:42:59 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:

  
> -	if (IS_ERR(dentry))
> +struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
> +					  int (*mkdir)(const char *name),
> +					  int (*rmdir)(const char *name))

Now what I could also do is to only allow this to be called once. And
in that case, we can hard code what mkdir and rmdir are. This could
work as currently there only exists a single instance of the instances
directory.

I might just do that too.

-- Steve


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 20:44     ` Steven Rostedt
@ 2015-01-26 20:58       ` Steven Rostedt
  2015-01-26 21:44         ` Al Viro
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 20:58 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 15:44:19 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:

> Now what I could also do is to only allow this to be called once. And
> in that case, we can hard code what mkdir and rmdir are. This could
> work as currently there only exists a single instance of the instances
> directory.
> 
> I might just do that too.

And just did:

diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index c7eb4c58579e..13e17bf677f4 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -50,6 +50,11 @@ static const struct file_operations tracefs_file_operations = {
 	.llseek =	noop_llseek,
 };
 
+struct tracefs_dir_ops {
+	int (*mkdir)(const char *name);
+	int (*rmdir)(const char *name);
+};
+
 static char *get_dname(struct dentry *dentry)
 {
 	const char *dname;
@@ -67,13 +72,10 @@ static char *get_dname(struct dentry *dentry)
 
 static int tracefs_syscall_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode)
 {
-	const struct tracefs_dir_ops *ops = inode ? inode->i_private : NULL;
+	const struct tracefs_dir_ops *ops = inode->i_private;
 	char *name;
 	int ret;
 
-	if (!ops)
-		return -EPERM;
-
 	name = get_dname(dentry);
 	if (!name)
 		return -ENOMEM;
@@ -98,9 +100,6 @@ static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
 	char *name;
 	int ret;
 
-	if (!ops)
-		return -EPERM;
-
 	name = get_dname(dentry);
 	if (!name)
 		return -ENOMEM;
@@ -317,16 +316,6 @@ static struct file_system_type trace_fs_type = {
 };
 MODULE_ALIAS_FS("tracefs");
 
-void tracefs_add_dir_ops(struct dentry *dentry, const struct tracefs_dir_ops *ops)
-{
-	struct inode *inode = dentry->d_inode;
-
-	if (!inode)
-		return;
-
-	inode->i_private = (void *)ops;
-}
-
 static struct dentry *start_creating(const char *name, struct dentry *parent)
 {
 	struct dentry *dentry;
@@ -425,6 +414,31 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
 	return end_creating(dentry);
 }
 
+static struct dentry *__create_dir(const char *name, struct dentry *parent,
+				   const struct inode_operations *ops)
+{
+	struct dentry *dentry = start_creating(name, parent);
+	struct inode *inode;
+
+	if (IS_ERR(dentry))
+		return NULL;
+
+	inode = tracefs_get_inode(dentry->d_sb);
+	if (unlikely(!inode))
+		return failed_creating(dentry);
+
+	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+	inode->i_op = ops;
+	inode->i_fop = &simple_dir_operations;
+
+	/* directory inodes start off with i_nlink == 2 (for "." entry) */
+	inc_nlink(inode);
+	d_instantiate(dentry, inode);
+	inc_nlink(dentry->d_parent->d_inode);
+	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
+	return end_creating(dentry);
+}
+
 /**
  * tracefs_create_dir - create a directory in the tracefs filesystem
  * @name: a pointer to a string containing the name of the directory to
@@ -444,26 +458,30 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
  */
 struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
 {
-	struct dentry *dentry = start_creating(name, parent);
-	struct inode *inode;
+	return __create_dir(name, parent, &simple_dir_inode_operations);
+}
 
-	if (IS_ERR(dentry))
+struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
+					  int (*mkdir)(const char *name),
+					  int (*rmdir)(const char *name))
+{
+	struct tracefs_dir_ops *dir_ops;
+	struct dentry *dentry;
+
+	dir_ops = kmalloc(sizeof(*dir_ops), GFP_KERNEL);
+	if (!dir_ops)
 		return NULL;
 
-	inode = tracefs_get_inode(dentry->d_sb);
-	if (unlikely(!inode))
-		return failed_creating(dentry);
+	dir_ops->mkdir = mkdir;
+	dir_ops->rmdir = mkdir;
 
-	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
-	inode->i_op = &tracefs_dir_inode_operations;
-	inode->i_fop = &simple_dir_operations;
+	dentry = __create_dir(name, parent, &tracefs_dir_inode_operations);
+	if (!dentry)
+		return NULL;
 
-	/* directory inodes start off with i_nlink == 2 (for "." entry) */
-	inc_nlink(inode);
-	d_instantiate(dentry, inode);
-	inc_nlink(dentry->d_parent->d_inode);
-	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);
-	return end_creating(dentry);
+	dentry->d_inode->i_private = (void *)dir_ops;
+
+	return dentry;
 }
 
 static inline int tracefs_positive(struct dentry *dentry)
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index d142b1f9d453..5b727a17beee 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -34,12 +34,9 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent);
 void tracefs_remove(struct dentry *dentry);
 void tracefs_remove_recursive(struct dentry *dentry);
 
-struct tracefs_dir_ops {
-	int (*mkdir)(const char *name);
-	int (*rmdir)(const char *name);
-};
-
-void tracefs_add_dir_ops(struct dentry *dentry, const struct tracefs_dir_ops *ops);
+struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
+					   int (*mkdir)(const char *name),
+					   int (*rmdir)(const char *name));
 
 bool tracefs_initialized(void);
 
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c555027c8aaf..2047501dcd16 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6445,18 +6445,13 @@ static int instance_rmdir(const char *name)
 	return ret;
 }
 
-static const struct tracefs_dir_ops instance_dir_ops = {
-	.mkdir		= instance_mkdir,
-	.rmdir		= instance_rmdir,
-};
-
 static __init void create_trace_instances(struct dentry *d_tracer)
 {
-	trace_instance_dir = tracefs_create_dir("instances", d_tracer);
+	trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer,
+							 instance_mkdir,
+							 instance_rmdir);
 	if (WARN_ON(!trace_instance_dir))
 		return;
-
-	tracefs_add_dir_ops(trace_instance_dir, &instance_dir_ops);
 }
 
 static void

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 19:30 ` [PATCH 00/16 v3] tracing: Add new file system tracefs Al Viro
  2015-01-26 20:42   ` Steven Rostedt
@ 2015-01-26 21:40   ` Al Viro
  2015-01-26 23:37     ` Steven Rostedt
  1 sibling, 1 reply; 40+ messages in thread
From: Al Viro @ 2015-01-26 21:40 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 07:30:49PM +0000, Al Viro wrote:
> On Mon, Jan 26, 2015 at 10:09:13AM -0500, Steven Rostedt wrote:
> > There has been complaints that tracing is tied too much to debugfs,
> > as there are systems that would like to perform tracing, but do
> > not mount debugfs for security reasons. That is because any subsystem
> > may use debugfs for debugging, and these interfaces are not always
> > tested for security.
> > 
> > Creating a new tracefs that the tracing directory will now be attached
> > to allows system admins the ability to access the tracing directory
> > without the need to mount debugfs.
> > 
> > Another advantage is that debugfs does not support the system calls
> > for mkdir and rmdir. Tracing uses these system calls to create new
> > instances for sub buffers. This was done by a hack that hijacked the
> > dentry ops from the "instances" debugfs dentry, and replacing it with
> > one that could work.
> > 
> > Instead of using this hack, tracefs can provide a proper interface to
> > allow the tracing system to have a mkdir and rmdir feature.
> > 
> > To maintain backward compatibility with older tools that expect that
> > the tracing directory is mounted with debugfs, the tracing directory
> > is still created under debugfs and tracefs is automatically mounted
> > there.
> > 
> > Finally, a new directory is created when tracefs is enabled called
> > /sys/kernel/tracing. This will be the new location that system admins
> > may mount tracefs if they are not using debugfs.
> 
> You are still fighting an inconvenient API, but now it's not debugfs one -
> it's your copy thereof.  Why not give your instances/ an inode_operations
> of its own?  One with ->mkdir() and ->rmdir(), leaving all other directories
> as-is.  That way you don't need the secondary methods at all.  And sure,
> debugfs_create_dir() grabs ->i_mutex on parent, making you drop that in
> your ->mkdir() if you want to call it.  But now you are not talking to it -
> just to your own code, where you are free to change the calling conventions,
> making it caller's responsibility to get that ->i_mutex.  The same goes for
> the rmdir side...

Is the following correct?
	* only one directory in the entire tree (/instances) allows mkdir/rmdir.
	* ftrace_trace_arrays always starts with global_trace and the rest
is in 1-to-1 correspondence with subdirectories of /instances.
	* tr->name is NULL for global_trace and non-NULL for everything
else.
	* all modifications of that list are happening from mkdir/rmdir
	* in the end of ->mkdir tr->dir set to the dentry of our subdirectory,
and it's non-NULL (or trace_array creation simply fails)
	* global_array.dir is set to magical value ((struct dentry *)1) upon
the first call of tracing_init_dentry().  Prior to that it's NULL.  BTW, may
I politely inquire what the fuck are those contortions in
tracing_init_dentry_tr() about?  Looks like a stunningly convoluted way
to trigger that automount point creation early in tracer_init_tracefs().
Why not do that right there explicitly?

What are mount options doing?  I mean, sure, you set the mode/uid/gid
of root.  Which is not modifiable anyway...  And AFAICS that's all those
options are affecting.

AFAICS, nothing ever removes files in debugfs root.  Right?  If so, you don't
need the games with simple_pin_fs() - they are pointless in such situation
anyway.  Just do tracefs_mount = kern_mount(&trace_fs_type); in tracefs_init()
and be done with that; lose the tracefs_mount_count and all calls of
simple_{pin,release}_fs().

While we are at it, what the hell is tracefs_file_operations about?  Looks
like some bastard offspring of /dev/null, but I don't see anything that would
use it...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 20:58       ` Steven Rostedt
@ 2015-01-26 21:44         ` Al Viro
  0 siblings, 0 replies; 40+ messages in thread
From: Al Viro @ 2015-01-26 21:44 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 03:58:22PM -0500, Steven Rostedt wrote:
> On Mon, 26 Jan 2015 15:44:19 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> > Now what I could also do is to only allow this to be called once. And
> > in that case, we can hard code what mkdir and rmdir are. This could
> > work as currently there only exists a single instance of the instances
> > directory.
> > 
> > I might just do that too.
> 
> And just did:
> 
> diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
> index c7eb4c58579e..13e17bf677f4 100644
> --- a/fs/tracefs/inode.c
> +++ b/fs/tracefs/inode.c
> @@ -50,6 +50,11 @@ static const struct file_operations tracefs_file_operations = {
>  	.llseek =	noop_llseek,
>  };
>  
> +struct tracefs_dir_ops {
> +	int (*mkdir)(const char *name);
> +	int (*rmdir)(const char *name);
> +};

Why go through that indirection at all...

> +struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
> +					   int (*mkdir)(const char *name),
> +					   int (*rmdir)(const char *name));

... when there's exactly one caller of that thing, and the values of
mkdir and rmdir callbacks are the same on each call?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 20:42   ` Steven Rostedt
  2015-01-26 20:44     ` Steven Rostedt
@ 2015-01-26 21:46     ` Al Viro
  2015-01-26 23:02       ` Al Viro
  2015-01-26 23:43       ` Steven Rostedt
  1 sibling, 2 replies; 40+ messages in thread
From: Al Viro @ 2015-01-26 21:46 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 03:42:59PM -0500, Steven Rostedt wrote:
> On Mon, 26 Jan 2015 19:30:49 +0000
> Al Viro <viro@ZenIV.linux.org.uk> wrote:
> 
> > You are still fighting an inconvenient API, but now it's not debugfs one -
> > it's your copy thereof.  Why not give your instances/ an inode_operations
> > of its own?  One with ->mkdir() and ->rmdir(), leaving all other directories
> > as-is.  That way you don't need the secondary methods at all.  And sure,
> > debugfs_create_dir() grabs ->i_mutex on parent, making you drop that in
> > your ->mkdir() if you want to call it.  But now you are not talking to it -
> > just to your own code, where you are free to change the calling conventions,
> > making it caller's responsibility to get that ->i_mutex.  The same goes for
> > the rmdir side...
> 
> The vfs layer grabs the i_mutex, which needs to be dropped.

What for?  Just keep it through your instance_mkdir/instance_rmdir and be
done with that.  Sure, it means that you need variants of file/directory
creation/removal primitives that would assume that parent is already locked
by caller (and would leave unlocking to the caller as well).  So add them...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 21:46     ` Al Viro
@ 2015-01-26 23:02       ` Al Viro
  2015-01-26 23:39         ` Steven Rostedt
  2015-01-26 23:43       ` Steven Rostedt
  1 sibling, 1 reply; 40+ messages in thread
From: Al Viro @ 2015-01-26 23:02 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 09:46:58PM +0000, Al Viro wrote:
> On Mon, Jan 26, 2015 at 03:42:59PM -0500, Steven Rostedt wrote:
> > On Mon, 26 Jan 2015 19:30:49 +0000
> > Al Viro <viro@ZenIV.linux.org.uk> wrote:
> > 
> > > You are still fighting an inconvenient API, but now it's not debugfs one -
> > > it's your copy thereof.  Why not give your instances/ an inode_operations
> > > of its own?  One with ->mkdir() and ->rmdir(), leaving all other directories
> > > as-is.  That way you don't need the secondary methods at all.  And sure,
> > > debugfs_create_dir() grabs ->i_mutex on parent, making you drop that in
> > > your ->mkdir() if you want to call it.  But now you are not talking to it -
> > > just to your own code, where you are free to change the calling conventions,
> > > making it caller's responsibility to get that ->i_mutex.  The same goes for
> > > the rmdir side...
> > 
> > The vfs layer grabs the i_mutex, which needs to be dropped.
> 
> What for?  Just keep it through your instance_mkdir/instance_rmdir and be
> done with that.  Sure, it means that you need variants of file/directory
> creation/removal primitives that would assume that parent is already locked
> by caller (and would leave unlocking to the caller as well).  So add them...

BTW, could you merge vfs.git#debugfs_automount, rather than copy the commits
into your branch?  Bloody inconvenient as it is...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 21:40   ` Al Viro
@ 2015-01-26 23:37     ` Steven Rostedt
  2015-01-27  2:34       ` Steven Rostedt
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 23:37 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 21:40:20 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:


> Is the following correct?
> 	* only one directory in the entire tree (/instances) allows mkdir/rmdir.

yes

> 	* ftrace_trace_arrays always starts with global_trace and the rest
> is in 1-to-1 correspondence with subdirectories of /instances.

pretty much.

> 	* tr->name is NULL for global_trace and non-NULL for everything
> else.

yes.

> 	* all modifications of that list are happening from mkdir/rmdir

yes.

> 	* in the end of ->mkdir tr->dir set to the dentry of our subdirectory,
> and it's non-NULL (or trace_array creation simply fails)

yes.

> 	* global_array.dir is set to magical value ((struct dentry *)1) upon

This is new for this patch series. Currently, global_array.dir points
to the dentry of /sys/kernel/debug/tracing. 

> the first call of tracing_init_dentry().  Prior to that it's NULL.  BTW, may
> I politely inquire what the fuck are those contortions in
> tracing_init_dentry_tr() about?  Looks like a stunningly convoluted way
> to trigger that automount point creation early in tracer_init_tracefs().
> Why not do that right there explicitly?

Yeah, that could be cleaned up. Before the tracefs code, it made much
more sense to keep that as a single function. Now that global_array.dir
is treated differently as the subdirs, it does make sense to have
global_arry.dir initialized in a separate function.

I'll update my patch series to do this.


> 
> What are mount options doing?  I mean, sure, you set the mode/uid/gid
> of root.  Which is not modifiable anyway...  And AFAICS that's all those
> options are affecting.

You mean in tracefs.c/inode.c? I have no idea, they are there from
debugfs cut and paste ;-)

> 
> AFAICS, nothing ever removes files in debugfs root.  Right?  If so, you don't

I'm not sure about that. Well, not from tracing or from userspace. But
I believe things can be removed from debugfs root with module unload.
But are you talking about tracefs root?

> need the games with simple_pin_fs() - they are pointless in such situation
> anyway.  Just do tracefs_mount = kern_mount(&trace_fs_type); in tracefs_init()
> and be done with that; lose the tracefs_mount_count and all calls of
> simple_{pin,release}_fs().

OK, cool. Because I had no idea what hey were used for anyway. ;-)

> 
> While we are at it, what the hell is tracefs_file_operations about?  Looks
> like some bastard offspring of /dev/null, but I don't see anything that would
> use it...

Hehe, again, this is what debugfs did and I just brought it over
thinking I needed it.

Thanks,

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 23:02       ` Al Viro
@ 2015-01-26 23:39         ` Steven Rostedt
  0 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 23:39 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 23:02:03 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> BTW, could you merge vfs.git#debugfs_automount, rather than copy the commits
> into your branch?  Bloody inconvenient as it is...

Ah, you're pushing it. Sorry, I thought this was more of a temp branch
for me to play with.

OK, I can merge it.

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 21:46     ` Al Viro
  2015-01-26 23:02       ` Al Viro
@ 2015-01-26 23:43       ` Steven Rostedt
  2015-01-26 23:49         ` Steven Rostedt
  2015-01-27  0:37         ` Al Viro
  1 sibling, 2 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 23:43 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 21:46:58 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> On Mon, Jan 26, 2015 at 03:42:59PM -0500, Steven Rostedt wrote:
> > On Mon, 26 Jan 2015 19:30:49 +0000
> > Al Viro <viro@ZenIV.linux.org.uk> wrote:
> > 
> > > You are still fighting an inconvenient API, but now it's not debugfs one -
> > > it's your copy thereof.  Why not give your instances/ an inode_operations
> > > of its own?  One with ->mkdir() and ->rmdir(), leaving all other directories
> > > as-is.  That way you don't need the secondary methods at all.  And sure,
> > > debugfs_create_dir() grabs ->i_mutex on parent, making you drop that in
> > > your ->mkdir() if you want to call it.  But now you are not talking to it -
> > > just to your own code, where you are free to change the calling conventions,
> > > making it caller's responsibility to get that ->i_mutex.  The same goes for
> > > the rmdir side...
> > 
> > The vfs layer grabs the i_mutex, which needs to be dropped.
> 
> What for?  Just keep it through your instance_mkdir/instance_rmdir and be
> done with that.  Sure, it means that you need variants of file/directory
> creation/removal primitives that would assume that parent is already locked
> by caller (and would leave unlocking to the caller as well).  So add them...

I originally had this, but the issue isn't with i_mutex only. The
instance_mkdir and instance_rmdir need to grab trace_types_lock. This
is also held when calling into tracefs.

That is, we can not hold i_mutex and take trace_types_lock.

trace_types_lock needs to be held with the creation or destruction of
events, which is what mkdir an rmdir do.


-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 23:43       ` Steven Rostedt
@ 2015-01-26 23:49         ` Steven Rostedt
  2015-01-27  0:39           ` Steven Rostedt
  2015-01-27  0:37         ` Al Viro
  1 sibling, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-26 23:49 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 18:43:14 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
 
> That is, we can not hold i_mutex and take trace_types_lock.
> 
> trace_types_lock needs to be held with the creation or destruction of
> events, which is what mkdir an rmdir do.

Although, I can not remember how this happened, but lockdep blew up on
me with this. I'll look again.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 23:43       ` Steven Rostedt
  2015-01-26 23:49         ` Steven Rostedt
@ 2015-01-27  0:37         ` Al Viro
  2015-01-27  1:02           ` Steven Rostedt
  1 sibling, 1 reply; 40+ messages in thread
From: Al Viro @ 2015-01-27  0:37 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 06:43:14PM -0500, Steven Rostedt wrote:

> I originally had this, but the issue isn't with i_mutex only. The
> instance_mkdir and instance_rmdir need to grab trace_types_lock. This
> is also held when calling into tracefs.
> 
> That is, we can not hold i_mutex and take trace_types_lock.
> 
> trace_types_lock needs to be held with the creation or destruction of
> events, which is what mkdir an rmdir do.

Yecchhh...

Looks like something that fell out of BKL removal - AFAICS, you are using
it to protect all kinds of things ;-/

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 23:49         ` Steven Rostedt
@ 2015-01-27  0:39           ` Steven Rostedt
  2015-01-27  4:34             ` Al Viro
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27  0:39 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 18:49:16 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:

> On Mon, 26 Jan 2015 18:43:14 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
>  
> > That is, we can not hold i_mutex and take trace_types_lock.
> > 
> > trace_types_lock needs to be held with the creation or destruction
> > of events, which is what mkdir an rmdir do.
> 
> Although, I can not remember how this happened, but lockdep blew up on
> me with this. I'll look again.

OK, found it. When events are created (module is loaded), the
trace_types_lock is taken, and the event directories are created (these
are in /sys/kernel/debug/tracing/events). We need to grab the i_mutex
in order to create these files.

This means that we can not take the trace_types_lock within the mkdir
or rmdir calls.

The directories are not static even outside the mkdir and rmdir calls.
As events can be created from several sources, which will create new
files and directories.

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  0:37         ` Al Viro
@ 2015-01-27  1:02           ` Steven Rostedt
  2015-01-27  1:03             ` Steven Rostedt
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27  1:02 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Tue, 27 Jan 2015 00:37:42 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> On Mon, Jan 26, 2015 at 06:43:14PM -0500, Steven Rostedt wrote:
> 
> > I originally had this, but the issue isn't with i_mutex only. The
> > instance_mkdir and instance_rmdir need to grab trace_types_lock.
> > This is also held when calling into tracefs.
> > 
> > That is, we can not hold i_mutex and take trace_types_lock.
> > 
> > trace_types_lock needs to be held with the creation or destruction
> > of events, which is what mkdir an rmdir do.
> 
> Yecchhh...
> 
> Looks like something that fell out of BKL removal - AFAICS, you are
> using it to protect all kinds of things ;-/

It's only used to protect slow paths. Yes, it grew more than what it
should protect. I had patches to add a few more mutexes, to narrow
things down. But that still did not solve this issue. The broken out
mutex still needed to be held when events are created.

The main issue is that mkdir() and rmdir() will create events that
require holding a mutex to make sure access to the events are
serialized.

But creating events requires grabbing the i_mutex. We can create events
either with mkdir() or when a module is loaded that has its own events.

Same goes with the mutex that protects adding and removing of
trace_arrays. When a module is loaded, we need to add events to each
trace array that exists (requiring that we grab the mutex that protects
that list). And hold it while we add our events.

Now you see why I found just dropping the parent mutex easier.

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  1:02           ` Steven Rostedt
@ 2015-01-27  1:03             ` Steven Rostedt
  2015-01-27  4:38               ` Al Viro
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27  1:03 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 20:02:18 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:


> Now you see why I found just dropping the parent mutex easier.

And this is probably why kernfs does things the way it does. I can
imagine it having the same locking issues.

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-26 23:37     ` Steven Rostedt
@ 2015-01-27  2:34       ` Steven Rostedt
  2015-01-27  4:46         ` Al Viro
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27  2:34 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, 26 Jan 2015 18:37:39 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:


> > the first call of tracing_init_dentry().  Prior to that it's NULL.
> > BTW, may I politely inquire what the fuck are those contortions in
> > tracing_init_dentry_tr() about?  Looks like a stunningly convoluted
> > way to trigger that automount point creation early in
> > tracer_init_tracefs(). Why not do that right there explicitly?
> 
> Yeah, that could be cleaned up. Before the tracefs code, it made much
> more sense to keep that as a single function. Now that
> global_array.dir is treated differently as the subdirs, it does make
> sense to have global_arry.dir initialized in a separate function.
> 
> I'll update my patch series to do this.

Now I remember why I did this (as I changed the code and everything
blew up). The files in the tracing directory can be created by several
users (do a grep for fs_initcall() in kernel/trace/*.c). The first
caller to add a file initializes the tracing directory.

I guess I can have all the other callers use fs_initcall_sync(). I'm
assuming those come after fs_initcall().

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  0:39           ` Steven Rostedt
@ 2015-01-27  4:34             ` Al Viro
  2015-01-27 15:15               ` Steven Rostedt
  0 siblings, 1 reply; 40+ messages in thread
From: Al Viro @ 2015-01-27  4:34 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 07:39:09PM -0500, Steven Rostedt wrote:
> On Mon, 26 Jan 2015 18:49:16 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> > On Mon, 26 Jan 2015 18:43:14 -0500
> > Steven Rostedt <rostedt@goodmis.org> wrote:
> >  
> > > That is, we can not hold i_mutex and take trace_types_lock.
> > > 
> > > trace_types_lock needs to be held with the creation or destruction
> > > of events, which is what mkdir an rmdir do.
> > 
> > Although, I can not remember how this happened, but lockdep blew up on
> > me with this. I'll look again.
> 
> OK, found it. When events are created (module is loaded), the
> trace_types_lock is taken, and the event directories are created (these
> are in /sys/kernel/debug/tracing/events). We need to grab the i_mutex
> in order to create these files.
> 
> This means that we can not take the trace_types_lock within the mkdir
> or rmdir calls.
> 
> The directories are not static even outside the mkdir and rmdir calls.
> As events can be created from several sources, which will create new
> files and directories.

Frankly, the first impression is that you have trace_types_lock way too
high in the hierarchy - you are taking it well outside of the level where
you start walking through ftrace_trace_arrays...

What else is it used for?  You seem to use it protect trace_array refcounts,
but you use them in a very odd way...  What happens if lookup for a file
in that tree loses CPU just as it enters trace_array_get() (e.g. on the
same trace_types_lock), at which point rm .../instances/<whatever> comes,
sees that tr->ref is still zero, kicks the sucker out of the list and
frees it, immediately followed by mkdir creating a new instace?  If the
allocation of the new trace_array happens to reuse the just-freed one,
your trace_array_get() will actually succeed, won't it?

It's not fatal (after all, everything will work as if you opened the similar
file in new instance in the first place), but it looks rather bogus...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  1:03             ` Steven Rostedt
@ 2015-01-27  4:38               ` Al Viro
  2015-01-27 15:19                 ` Steven Rostedt
  0 siblings, 1 reply; 40+ messages in thread
From: Al Viro @ 2015-01-27  4:38 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 08:03:50PM -0500, Steven Rostedt wrote:
> On Mon, 26 Jan 2015 20:02:18 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> 
> > Now you see why I found just dropping the parent mutex easier.
> 
> And this is probably why kernfs does things the way it does. I can
> imagine it having the same locking issues.

The least said about kernfs locking, the better...

As for the use of trace_types_lock to serialize rmdir vs. event
addition/removal, I wonder what's wrong with actually using the
->i_mutex of /instances - you have a reference to its dentry,
after all...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  2:34       ` Steven Rostedt
@ 2015-01-27  4:46         ` Al Viro
  0 siblings, 0 replies; 40+ messages in thread
From: Al Viro @ 2015-01-27  4:46 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Mon, Jan 26, 2015 at 09:34:19PM -0500, Steven Rostedt wrote:
> On Mon, 26 Jan 2015 18:37:39 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> 
> > > the first call of tracing_init_dentry().  Prior to that it's NULL.
> > > BTW, may I politely inquire what the fuck are those contortions in
> > > tracing_init_dentry_tr() about?  Looks like a stunningly convoluted
> > > way to trigger that automount point creation early in
> > > tracer_init_tracefs(). Why not do that right there explicitly?
> > 
> > Yeah, that could be cleaned up. Before the tracefs code, it made much
> > more sense to keep that as a single function. Now that
> > global_array.dir is treated differently as the subdirs, it does make
> > sense to have global_arry.dir initialized in a separate function.
> > 
> > I'll update my patch series to do this.
> 
> Now I remember why I did this (as I changed the code and everything
> blew up). The files in the tracing directory can be created by several
> users (do a grep for fs_initcall() in kernel/trace/*.c). The first
> caller to add a file initializes the tracing directory.
> 
> I guess I can have all the other callers use fs_initcall_sync(). I'm
> assuming those come after fs_initcall().

Ah...  That explains some of the oddities of that kind (not all of them,
though - your trace_options_init_dentry() is called by
create_trace_option_dirs() and create_trace_option_core_file(), which is
called only by create_trace_option_dirs(), and that - quite a few times,
each time calling trace_options_init_dentry()).

Strange style, IMO.  Frankly, I'd rather have the ordering as explicit as it
gets...

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  4:34             ` Al Viro
@ 2015-01-27 15:15               ` Steven Rostedt
  0 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27 15:15 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Tue, 27 Jan 2015 04:34:21 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:


> Frankly, the first impression is that you have trace_types_lock way too
> high in the hierarchy - you are taking it well outside of the level where
> you start walking through ftrace_trace_arrays...

Actually, it is originally used for modifying of tr->current_trace

This was before having multiple buffers. I just used the same lock to
protect the trace arrays. Note, I have patches to make a separate mutex
for that, but it just seems to make things a little more complex, so I
haven't pushed it too much. Yeah, that trace_types_lock is basically
tracing's BKL.

> 
> What else is it used for?  You seem to use it protect trace_array refcounts,
> but you use them in a very odd way...  What happens if lookup for a file
> in that tree loses CPU just as it enters trace_array_get() (e.g. on the
> same trace_types_lock), at which point rm .../instances/<whatever> comes,
> sees that tr->ref is still zero, kicks the sucker out of the list and
> frees it, immediately followed by mkdir creating a new instace?  If the
> allocation of the new trace_array happens to reuse the just-freed one,
> your trace_array_get() will actually succeed, won't it?
> 
> It's not fatal (after all, everything will work as if you opened the similar
> file in new instance in the first place), but it looks rather bogus...

I'm actually aware of this possibility. But as you said, it's not
fatal, and very unlikely to happen.

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27  4:38               ` Al Viro
@ 2015-01-27 15:19                 ` Steven Rostedt
  2015-01-27 15:44                   ` Steven Rostedt
  0 siblings, 1 reply; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27 15:19 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Tue, 27 Jan 2015 04:38:39 +0000
Al Viro <viro@ZenIV.linux.org.uk> wrote:

> On Mon, Jan 26, 2015 at 08:03:50PM -0500, Steven Rostedt wrote:
> > On Mon, 26 Jan 2015 20:02:18 -0500
> > Steven Rostedt <rostedt@goodmis.org> wrote:
> > 
> > 
> > > Now you see why I found just dropping the parent mutex easier.
> > 
> > And this is probably why kernfs does things the way it does. I can
> > imagine it having the same locking issues.
> 
> The least said about kernfs locking, the better...
> 
> As for the use of trace_types_lock to serialize rmdir vs. event
> addition/removal, I wonder what's wrong with actually using the
> ->i_mutex of /instances - you have a reference to its dentry,
> after all...

You mean, instead of grabbing trace_types_lock for modifying of events
and trace arrays, we should grab the dentry->d_inode->i_mutex?

BTW, what exactly can go wrong with the current method I have that
releases the i_mutex, calls the mkdir() method, and then regrabs the
i_mutex?

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 00/16 v3] tracing: Add new file system tracefs
  2015-01-27 15:19                 ` Steven Rostedt
@ 2015-01-27 15:44                   ` Steven Rostedt
  0 siblings, 0 replies; 40+ messages in thread
From: Steven Rostedt @ 2015-01-27 15:44 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel, Greg Kroah-Hartman, Ingo Molnar, Andrew Morton

On Tue, 27 Jan 2015 10:19:53 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> You mean, instead of grabbing trace_types_lock for modifying of events
> and trace arrays, we should grab the dentry->d_inode->i_mutex?
> 

OK, trace_arrays_lock protects against the tr->current_trace and the
list of arrays, and accessing it.

The creation of events is protected by the event_mutex. Which would
suffer the same issue, as it is grabbed when creating and removing
event directories.

-- Steve

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2015-01-27 15:44 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-26 15:09 [PATCH 00/16 v3] tracing: Add new file system tracefs Steven Rostedt
2015-01-26 15:09 ` [PATCH 01/16 v3] debugfs_{mkdir,create,link}(): get rid of redundant argument Steven Rostedt
2015-01-26 15:09 ` [PATCH 02/16 v3] debugfs: split the beginning and the end of __create_file() off Steven Rostedt
2015-01-26 15:09 ` [PATCH 03/16 v3] debugfs: kill __create_file() Steven Rostedt
2015-01-26 15:09 ` [PATCH 04/16 v3] fold debugfs_link() into caller Steven Rostedt
2015-01-26 15:09 ` [PATCH 05/16 v3] debugfs_mknod(): get rid useless arguments Steven Rostedt
2015-01-26 15:09 ` [PATCH 06/16 v3] fold debugfs_mkdir() into caller Steven Rostedt
2015-01-26 15:09 ` [PATCH 07/16 v3] fold debugfs_create() " Steven Rostedt
2015-01-26 15:09 ` [PATCH 08/16 v3] fold debugfs_mknod() into callers Steven Rostedt
2015-01-26 15:09 ` [PATCH 09/16 v3] debugfs: take mode-dependent parts of debugfs_get_inode() " Steven Rostedt
2015-01-26 15:09 ` [PATCH 10/16 v3] debugfs: split end_creating() into success and failure cases Steven Rostedt
2015-01-26 15:09 ` [PATCH 11/16 v3] new primitive: debugfs_create_automount() Steven Rostedt
2015-01-26 15:09 ` [PATCH 12/16 v3] tracefs: Add new tracefs file system Steven Rostedt
2015-01-26 15:09 ` [PATCH 13/16 v3] tracing: Convert the tracing facility over to use tracefs Steven Rostedt
2015-01-26 15:09 ` [PATCH 14/16 v3] tracing: Automatically mount tracefs on debugfs/tracing Steven Rostedt
2015-01-26 15:09 ` [PATCH 15/16 v3] tracefs: Add directory /sys/kernel/tracing Steven Rostedt
2015-01-26 15:09 ` [PATCH 16/16 v3] tracing: Have mkdir and rmdir be part of tracefs Steven Rostedt
2015-01-26 19:30 ` [PATCH 00/16 v3] tracing: Add new file system tracefs Al Viro
2015-01-26 20:42   ` Steven Rostedt
2015-01-26 20:44     ` Steven Rostedt
2015-01-26 20:58       ` Steven Rostedt
2015-01-26 21:44         ` Al Viro
2015-01-26 21:46     ` Al Viro
2015-01-26 23:02       ` Al Viro
2015-01-26 23:39         ` Steven Rostedt
2015-01-26 23:43       ` Steven Rostedt
2015-01-26 23:49         ` Steven Rostedt
2015-01-27  0:39           ` Steven Rostedt
2015-01-27  4:34             ` Al Viro
2015-01-27 15:15               ` Steven Rostedt
2015-01-27  0:37         ` Al Viro
2015-01-27  1:02           ` Steven Rostedt
2015-01-27  1:03             ` Steven Rostedt
2015-01-27  4:38               ` Al Viro
2015-01-27 15:19                 ` Steven Rostedt
2015-01-27 15:44                   ` Steven Rostedt
2015-01-26 21:40   ` Al Viro
2015-01-26 23:37     ` Steven Rostedt
2015-01-27  2:34       ` Steven Rostedt
2015-01-27  4:46         ` Al Viro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).