summaryrefslogtreecommitdiff
path: root/include
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 13:51:21 -0800
commit9f010c2ad5194a4b682e747984477850fabd03be (patch)
treee989b667775b3e1bf9b6da90bbaf2815eb103502 /include
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')
-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 {
struct kernfs_node {
atomic_t count;
atomic_t active;
+ int deact_depth;
+ unsigned int hash; /* ns + name hash */
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
@@ -90,7 +92,6 @@ struct kernfs_node {
struct rb_node rb;
const void *ns; /* namespace tag */
- unsigned int hash; /* ns + name hash */
union {
struct kernfs_elem_dir dir;
struct kernfs_elem_symlink symlink;
@@ -233,6 +234,10 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
const char *name,
struct kernfs_node *target);
+void kernfs_deactivate(struct kernfs_node *kn);
+void kernfs_reactivate(struct kernfs_node *kn);
+void kernfs_deactivate_self(struct kernfs_node *kn);
+void kernfs_reactivate_self(struct kernfs_node *kn);
void kernfs_remove(struct kernfs_node *kn);
int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
const void *ns);