aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/kernfs/dir.c25
1 files changed, 4 insertions, 21 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 37dd6408f5f6..770d687ee9f3 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -149,25 +149,12 @@ struct kernfs_node *kernfs_get_active(struct kernfs_node *kn)
149 if (unlikely(!kn)) 149 if (unlikely(!kn))
150 return NULL; 150 return NULL;
151 151
152 if (kernfs_lockdep(kn)) 152 if (!atomic_inc_unless_negative(&kn->active))
153 rwsem_acquire_read(&kn->dep_map, 0, 1, _RET_IP_); 153 return NULL;
154
155 /*
156 * Try to obtain an active ref. If @kn is deactivated, we block
157 * till either it's reactivated or killed.
158 */
159 do {
160 if (atomic_inc_unless_negative(&kn->active))
161 return kn;
162
163 wait_event(kernfs_root(kn)->deactivate_waitq,
164 atomic_read(&kn->active) >= 0 ||
165 RB_EMPTY_NODE(&kn->rb));
166 } while (!RB_EMPTY_NODE(&kn->rb));
167 154
168 if (kernfs_lockdep(kn)) 155 if (kernfs_lockdep(kn))
169 rwsem_release(&kn->dep_map, 1, _RET_IP_); 156 rwsem_acquire_read(&kn->dep_map, 0, 1, _RET_IP_);
170 return NULL; 157 return kn;
171} 158}
172 159
173/** 160/**
@@ -799,7 +786,6 @@ static void __kernfs_deactivate(struct kernfs_node *kn)
799 786
800static void __kernfs_remove(struct kernfs_node *kn) 787static void __kernfs_remove(struct kernfs_node *kn)
801{ 788{
802 struct kernfs_root *root = kernfs_root(kn);
803 struct kernfs_node *pos; 789 struct kernfs_node *pos;
804 790
805 lockdep_assert_held(&kernfs_mutex); 791 lockdep_assert_held(&kernfs_mutex);
@@ -851,9 +837,6 @@ static void __kernfs_remove(struct kernfs_node *kn)
851 837
852 kernfs_put(pos); 838 kernfs_put(pos);
853 } while (pos != kn); 839 } while (pos != kn);
854
855 /* some nodes killed, kick get_active waiters */
856 wake_up_all(&root->deactivate_waitq);
857} 840}
858 841
859/** 842/**