Messages in this thread Patch in this message |  | | From | Imran Khan <> | Subject | [PATCH v8 04/10] kernfs: Introduce interface to access global kernfs_open_file_mutex. | Date | Sun, 10 Apr 2022 12:37:13 +1000 |
| |
This allows to change underlying mutex locking, without needing to change the users of the lock. For example next patch modifies this interface to use hashed mutexes in place of a single global kernfs_open_file_mutex.
Signed-off-by: Imran Khan <imran.f.khan@oracle.com> --- fs/kernfs/file.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-)
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index c89220dcfdc1..214b48d59148 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -47,6 +47,22 @@ struct kernfs_open_node { #define attribute_to_node(ptr, type, member) \ container_of(ptr, type, member) +static inline struct mutex *kernfs_open_file_mutex_ptr(struct kernfs_node *kn) +{ + return &kernfs_open_file_mutex; +} + +static inline struct mutex *kernfs_open_file_mutex_lock(struct kernfs_node *kn) +{ + struct mutex *lock; + + lock = kernfs_open_file_mutex_ptr(kn); + + mutex_lock(lock); + + return lock; +} + static DEFINE_SPINLOCK(kernfs_notify_lock); static LLIST_HEAD(kernfs_notify_list); @@ -520,8 +536,9 @@ static int kernfs_get_open_node(struct kernfs_node *kn, struct kernfs_open_file *of) { struct kernfs_open_node *on, *new_on = NULL; + struct mutex *mutex = NULL; - mutex_lock(&kernfs_open_file_mutex); + mutex = kernfs_open_file_mutex_lock(kn); /** * ->attr.open changes under kernfs_open_file_mutex so we don't @@ -531,13 +548,13 @@ static int kernfs_get_open_node(struct kernfs_node *kn, lockdep_is_held(&kernfs_open_file_mutex)); if (on) { list_add_tail(&of->list, &on->files); - mutex_unlock(&kernfs_open_file_mutex); + mutex_unlock(mutex); return 0; } else { /* not there, initialize a new one and retry */ new_on = kmalloc(sizeof(*new_on), GFP_KERNEL); if (!new_on) { - mutex_unlock(&kernfs_open_file_mutex); + mutex_unlock(mutex); return -ENOMEM; } atomic_set(&new_on->event, 1); @@ -546,7 +563,7 @@ static int kernfs_get_open_node(struct kernfs_node *kn, list_add_tail(&of->list, &new_on->files); rcu_assign_pointer(kn->attr.open, new_on); } - mutex_unlock(&kernfs_open_file_mutex); + mutex_unlock(mutex); return 0; } @@ -567,12 +584,13 @@ static void kernfs_put_open_node(struct kernfs_node *kn, struct kernfs_open_file *of) { struct kernfs_open_node *on; + struct mutex *mutex = NULL; /* ->attr.open NULL means there are no more open files */ if (rcu_dereference_raw(kn->attr.open) == NULL) return; - mutex_lock(&kernfs_open_file_mutex); + mutex = kernfs_open_file_mutex_lock(kn); on = rcu_dereference_protected(kn->attr.open, lockdep_is_held(&kernfs_open_file_mutex)); @@ -589,7 +607,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn, rcu_assign_pointer(kn->attr.open, NULL); kfree_rcu(on, rcu_head); } - mutex_unlock(&kernfs_open_file_mutex); + mutex_unlock(mutex); } static int kernfs_fop_open(struct inode *inode, struct file *file) @@ -731,7 +749,7 @@ static void kernfs_release_file(struct kernfs_node *kn, * here because drain path may be called from places which can * cause circular dependency. */ - lockdep_assert_held(&kernfs_open_file_mutex); + lockdep_assert_held(kernfs_open_file_mutex_ptr(kn)); if (!of->released) { /* @@ -748,11 +766,12 @@ static int kernfs_fop_release(struct inode *inode, struct file *filp) { struct kernfs_node *kn = inode->i_private; struct kernfs_open_file *of = kernfs_of(filp); + struct mutex *mutex = NULL; if (kn->flags & KERNFS_HAS_RELEASE) { - mutex_lock(&kernfs_open_file_mutex); + mutex = kernfs_open_file_mutex_lock(kn); kernfs_release_file(kn, of); - mutex_unlock(&kernfs_open_file_mutex); + mutex_unlock(mutex); } kernfs_put_open_node(kn, of); @@ -767,6 +786,7 @@ void kernfs_drain_open_files(struct kernfs_node *kn) { struct kernfs_open_node *on; struct kernfs_open_file *of; + struct mutex *mutex = NULL; if (!(kn->flags & (KERNFS_HAS_MMAP | KERNFS_HAS_RELEASE))) return; @@ -774,7 +794,7 @@ void kernfs_drain_open_files(struct kernfs_node *kn) if (rcu_dereference_raw(kn->attr.open) == NULL) return; - mutex_lock(&kernfs_open_file_mutex); + mutex = kernfs_open_file_mutex_lock(kn); on = rcu_dereference_check(kn->attr.open, lockdep_is_held(&kernfs_open_file_mutex)); if (!on) { @@ -792,7 +812,7 @@ void kernfs_drain_open_files(struct kernfs_node *kn) kernfs_release_file(kn, of); } - mutex_unlock(&kernfs_open_file_mutex); + mutex_unlock(mutex); } /* -- 2.30.2
|  |