aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/kernfs.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-01-10 08:57:26 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-10 16:51:21 -0500
commit9f010c2ad5194a4b682e747984477850fabd03be (patch)
treee989b667775b3e1bf9b6da90bbaf2815eb103502 /include/linux/kernfs.h
parent895a068a524e134900b9d98b519309b7aae7bbb1 (diff)
kernfs: implement kernfs_{de|re}activate[_self]()
This patch implements four functions to manipulate deactivation state - deactivate, reactivate and the _self suffixed pair. A new fields kernfs_node->deact_depth is added so that concurrent and nested deactivations are handled properly. kernfs_node->hash is moved so that it's paired with the new field so that it doesn't increase the size of kernfs_node. A kernfs user's lock would normally nest inside active ref but during removal the user may want to perform kernfs_remove() while holding the said lock, which would introduce a reverse locking dependency. This function can be used to break such reverse dependency by allowing deactivation step to performed separately outside user's critical section. This will also be used implement kernfs_remove_self(). Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/kernfs.h')
-rw-r--r--include/linux/kernfs.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 9b5a4bb88c64..ac8693027058 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -80,6 +80,8 @@ struct kernfs_elem_attr {
80struct kernfs_node { 80struct kernfs_node {
81 atomic_t count; 81 atomic_t count;
82 atomic_t active; 82 atomic_t active;
83 int deact_depth;
84 unsigned int hash; /* ns + name hash */
83#ifdef CONFIG_DEBUG_LOCK_ALLOC 85#ifdef CONFIG_DEBUG_LOCK_ALLOC
84 struct lockdep_map dep_map; 86 struct lockdep_map dep_map;
85#endif 87#endif
@@ -90,7 +92,6 @@ struct kernfs_node {
90 struct rb_node rb; 92 struct rb_node rb;
91 93
92 const void *ns; /* namespace tag */ 94 const void *ns; /* namespace tag */
93 unsigned int hash; /* ns + name hash */
94 union { 95 union {
95 struct kernfs_elem_dir dir; 96 struct kernfs_elem_dir dir;
96 struct kernfs_elem_symlink symlink; 97 struct kernfs_elem_symlink symlink;
@@ -233,6 +234,10 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
233struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, 234struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
234 const char *name, 235 const char *name,
235 struct kernfs_node *target); 236 struct kernfs_node *target);
237void kernfs_deactivate(struct kernfs_node *kn);
238void kernfs_reactivate(struct kernfs_node *kn);
239void kernfs_deactivate_self(struct kernfs_node *kn);
240void kernfs_reactivate_self(struct kernfs_node *kn);
236void kernfs_remove(struct kernfs_node *kn); 241void kernfs_remove(struct kernfs_node *kn);
237int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name, 242int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
238 const void *ns); 243 const void *ns);