eventfs: Some more minor fixes
Steven Rostedt
maintainercover eventfs: Some more minor fixes
Mark Rutland reported some crashes from the latest eventfs updates. This fixes most of them.
He still has one splat that he can trigger but I can not. Still looking into that.
Steven Rostedt (Google) (4):
eventfs: Use GFP_NOFS for allocation when eventfs_mutex is held
eventfs: Move taking of inode_lock into dcache_dir_open_wrapper()
eventfs: Do not allow NULL parent to eventfs_start_creating()
eventfs: Make sure that parent->d_inode is locked in creating files/dirs
----
fs/tracefs/event_inode.c | 24 ++++++++---------------- fs/tracefs/inode.c | 13 ++++--------- 2 files changed, 12 insertions(+), 25 deletions(-)
Steven Rostedt
maintainerPATCH 1/4 eventfs: Use GFP_NOFS for allocation when eventfs_mutex is held
From: "Steven Rostedt (Google)" <[email protected]>
If memory reclaim happens, it can reclaim file system pages. The file system pages from eventfs may take the eventfs_mutex on reclaim. This means that allocation while holding the eventfs_mutex must not call into filesystem reclaim. A lockdep splat uncovered this.
--- fs/tracefs/event_inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/tracefs/event_inode.c +2 -2
@@ -95,7 +95,7 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,if (!(dentry->d_inode->i_mode &S_IFDIR )) {if (!ei->entry_attrs) { ei->entry_attrs =kzalloc (sizeof (*ei->entry_attrs) * ei->nr_entries, -GFP_KERNEL ); +GFP_NOFS );if (!ei->entry_attrs) { ret = -ENOMEM ; goto out;
@@ -627,7 +627,7 @@ static int add_dentries(struct dentry ***dentries, struct dentry *d, int cnt) {struct dentry **tmp; - tmp =krealloc (*dentries,sizeof (d) * (cnt +2 ),GFP_KERNEL ); + tmp =krealloc (*dentries,sizeof (d) * (cnt +2 ),GFP_NOFS );if (!tmp)return -1 ; tmp[cnt] = d;
Signature · 1 line
2.42.0
Steven Rostedt
maintainerPATCH 2/4 eventfs: Move taking of inode_lock into dcache_dir_open_wrapper()
In reply to Steven RostedtFrom: "Steven Rostedt (Google)" <[email protected]>
The both create_file_dentry() and create_dir_dentry() takes a boolean parameter "lookup", as on lookup the inode_lock should already be taken, but for dcache_dir_open_wrapper() it is not taken.
There's no reason that the dcache_dir_open_wrapper() can't take the inode_lock before calling these functions. In fact, it's better if it does, as the lock can be held throughout both directory and file creations.
This also simplifies the code, and possibly prevents unexpected race conditions when the lock is released.
--- fs/tracefs/event_inode.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-)
fs/tracefs/event_inode.c +2 -14
@@ -347,15 +347,8 @@ create_file_dentry(struct eventfs_inode *ei, int idx,mutex_unlock (&eventfs_mutex); -/* The lookup already has the parent->d_inode locked */ -if (!lookup) -inode_lock (parent->d_inode); - dentry =create_file (name, mode, attr, parent, data, fops); -if (!lookup) -inode_unlock (parent->d_inode); -mutex_lock (&eventfs_mutex);if (IS_ERR_OR_NULL (dentry)) {
@@ -453,15 +446,8 @@ create_dir_dentry(struct eventfs_inode *pei, struct eventfs_inode *ei, }mutex_unlock (&eventfs_mutex); -/* The lookup already has the parent->d_inode locked */ -if (!lookup) -inode_lock (parent->d_inode); - dentry =create_dir (ei, parent); -if (!lookup) -inode_unlock (parent->d_inode); -mutex_lock (&eventfs_mutex);if (IS_ERR_OR_NULL (dentry) && !ei->is_freed) {
@@ -693,6 +679,7 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file)return -ENOMEM ; } +inode_lock (parent->d_inode);list_for_each_entry_srcu (ei_child, &ei->children, list,srcu_read_lock_held (&eventfs_srcu)) { d =create_dir_dentry (ei, ei_child, parent, false);
@@ -725,6 +712,7 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file) cnt++; } } +inode_unlock (parent->d_inode);srcu_read_unlock (&eventfs_srcu, idx); ret =dcache_dir_open (inode, file);
Signature · 1 line
2.42.0
Steven Rostedt
maintainerPATCH 3/4 eventfs: Do not allow NULL parent to eventfs_start_creating()
In reply to Steven RostedtFrom: "Steven Rostedt (Google)" <[email protected]>
The eventfs directory is dynamically created via the meta data supplied by the existing trace events. All files and directories in eventfs has a parent. Do not allow NULL to be passed into eventfs_start_creating() as the parent because that should never happen. Warn if it does.
--- fs/tracefs/inode.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
fs/tracefs/inode.c +4 -9
@@ -509,20 +509,15 @@ struct dentry *eventfs_start_creating(const char *name, struct dentry *parent)struct dentry *dentry;int error; +/* Must always have a parent. */ +if (WARN_ON_ONCE (!parent)) +return ERR_PTR (-EINVAL ); + error =simple_pin_fs (&trace_fs_type, &tracefs_mount, &tracefs_mount_count);if (error)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 -* block. A pointer to that is in the struct vfsmount that we -* have around. -*/ -if (!parent) - parent = tracefs_mount->mnt_root; -if (unlikely (IS_DEADDIR (parent->d_inode))) dentry =ERR_PTR (-ENOENT );else
Signature · 1 line
2.42.0
Steven Rostedt
maintainerPATCH 4/4 eventfs: Make sure that parent->d_inode is locked in creating files/dirs
In reply to Steven RostedtFrom: "Steven Rostedt (Google)" <[email protected]>
Since the locking of the parent->d_inode has been moved outside the creation of the files and directories (as it use to be locked via a conditional), add a WARN_ON_ONCE() to the case that it's not locked.
--- fs/tracefs/event_inode.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/tracefs/event_inode.c +4 -0
@@ -327,6 +327,8 @@ create_file_dentry(struct eventfs_inode *ei, int idx,struct dentry **e_dentry = &ei->d_children[idx];struct dentry *dentry; +WARN_ON_ONCE (!inode_is_locked (parent->d_inode)); +mutex_lock (&eventfs_mutex);if (ei->is_freed) {mutex_unlock (&eventfs_mutex);
@@ -430,6 +432,8 @@ create_dir_dentry(struct eventfs_inode *pei, struct eventfs_inode *ei, {struct dentry *dentry =NULL ; +WARN_ON_ONCE (!inode_is_locked (parent->d_inode)); +mutex_lock (&eventfs_mutex);if (pei->is_freed || ei->is_freed) {mutex_unlock (&eventfs_mutex);
Signature · 1 line
2.42.0
Quoted 5 lines · Steven Rostedt
Mark Rutland reported some crashes from the latest eventfs updates. This fixes most of them.
He still has one splat that he can trigger but I can not. Still looking into that.
Thanks,
Josef
Steven Rostedt
maintainerQuoted 8 lines · On Wed, 22 Nov 2023 09:19:25 -0500 Josef Bacik <[email protected]> wrote:
Quoted 5 lines · Steven Rostedt
Mark Rutland reported some crashes from the latest eventfs updates. This fixes most of them.
He still has one splat that he can trigger but I can not. Still looking into that.
Reviewed-by Josef Bacik <[email protected]>
Thanks Josef!
-- Steve