summaryrefslogtreecommitdiff
path: root/fs/tracefs/internal.h
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2024-01-22 23:27:48 +0300
committerSteven Rostedt (Google) <rostedt@goodmis.org>2024-01-23 17:17:11 +0300
commit834bf76add3e6168038150f162cbccf1fd492a67 (patch)
tree9bc775ceb228d5e8e59b2c750e59e540d76001b0 /fs/tracefs/internal.h
parent2b44760609e9eaafc9d234a6883d042fc21132a7 (diff)
downloadlinux-834bf76add3e6168038150f162cbccf1fd492a67.tar.xz
eventfs: Save directory inodes in the eventfs_inode structure
The eventfs inodes and directories are allocated when referenced. But this leaves the issue of keeping consistent inode numbers and the number is only saved in the inode structure itself. When the inode is no longer referenced, it can be freed. When the file that the inode was representing is referenced again, the inode is once again created, but the inode number needs to be the same as it was before. Just making the inode numbers the same for all files is fine, but that does not work with directories. The find command will check for loops via the inode number and having the same inode number for directories triggers: # find /sys/kernel/tracing find: File system loop detected; '/sys/kernel/debug/tracing/events/initcall/initcall_finish' is part of the same file system loop as '/sys/kernel/debug/tracing/events/initcall'. [..] Linus pointed out that the eventfs_inode structure ends with a single 32bit int, and on 64 bit machines, there's likely a 4 byte hole due to alignment. We can use this hole to store the inode number for the eventfs_inode. All directories in eventfs are represented by an eventfs_inode and that data structure can hold its inode number. That last int was also purposely placed at the end of the structure to prevent holes from within. Now that there's a 4 byte number to hold the inode, both the inode number and the last integer can be moved up in the structure for better cache locality, where the llist and rcu fields can be moved to the end as they are only used when the eventfs_inode is being deleted. Link: https://lore.kernel.org/all/CAMuHMdXKiorg-jiuKoZpfZyDJ3Ynrfb8=X+c7x0Eewxn-YRdCA@mail.gmail.com/ Link: https://lore.kernel.org/linux-trace-kernel/20240122152748.46897388@gandalf.local.home Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Fixes: 53c41052ba31 ("eventfs: Have the inodes all for files and directories all be the same") Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> Reviewed-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'fs/tracefs/internal.h')
-rw-r--r--fs/tracefs/internal.h7
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
index 12b7d0150ae9..45397df9bb65 100644
--- a/fs/tracefs/internal.h
+++ b/fs/tracefs/internal.h
@@ -55,6 +55,10 @@ struct eventfs_inode {
struct eventfs_attr *entry_attrs;
struct eventfs_attr attr;
void *data;
+ unsigned int is_freed:1;
+ unsigned int is_events:1;
+ unsigned int nr_entries:30;
+ unsigned int ino;
/*
* Union - used for deletion
* @llist: for calling dput() if needed after RCU
@@ -64,9 +68,6 @@ struct eventfs_inode {
struct llist_node llist;
struct rcu_head rcu;
};
- unsigned int is_freed:1;
- unsigned int is_events:1;
- unsigned int nr_entries:30;
};
static inline struct tracefs_inode *get_tracefs(const struct inode *inode)