--- x/fs/kernfs/dir.c +++ d/fs/kernfs/dir.c @@ -711,6 +711,7 @@ err_unlock: return NULL; } +static void __kernfs_activate(struct kernfs_node *); /** * kernfs_add_one - add kernfs_node to parent without warning * @kn: kernfs_node to be added @@ -762,8 +763,6 @@ int kernfs_add_one(struct kernfs_node *k ps_iattr->ia_mtime = ps_iattr->ia_ctime; } - up_write(&root->kernfs_rwsem); - /* * Activate the new node unless CREATE_DEACTIVATED is requested. * If not activated here, the kernfs user is responsible for @@ -772,7 +771,9 @@ int kernfs_add_one(struct kernfs_node *k * trigger deactivation. */ if (!(kernfs_root(kn)->flags & KERNFS_ROOT_CREATE_DEACTIVATED)) - kernfs_activate(kn); + __kernfs_activate(kn); + + up_write(&root->kernfs_rwsem); return 0; out_unlock: @@ -1304,6 +1305,24 @@ static struct kernfs_node *kernfs_next_d return pos->parent; } +static void __kernfs_activate(struct kernfs_node *kn) +{ + struct kernfs_node *pos; + struct kernfs_root *root = kernfs_root(kn); + + pos = NULL; + while ((pos = kernfs_next_descendant_post(pos, kn))) { + if (pos->flags & KERNFS_ACTIVATED) + continue; + + WARN_ON_ONCE(pos->parent && RB_EMPTY_NODE(&pos->rb)); + WARN_ON_ONCE(atomic_read(&pos->active) != KN_DEACTIVATED_BIAS); + + atomic_sub(KN_DEACTIVATED_BIAS, &pos->active); + pos->flags |= KERNFS_ACTIVATED; + } +} + /** * kernfs_activate - activate a node which started deactivated * @kn: kernfs_node whose subtree is to be activated @@ -1319,23 +1338,10 @@ static struct kernfs_node *kernfs_next_d */ void kernfs_activate(struct kernfs_node *kn) { - struct kernfs_node *pos; struct kernfs_root *root = kernfs_root(kn); down_write(&root->kernfs_rwsem); - - pos = NULL; - while ((pos = kernfs_next_descendant_post(pos, kn))) { - if (pos->flags & KERNFS_ACTIVATED) - continue; - - WARN_ON_ONCE(pos->parent && RB_EMPTY_NODE(&pos->rb)); - WARN_ON_ONCE(atomic_read(&pos->active) != KN_DEACTIVATED_BIAS); - - atomic_sub(KN_DEACTIVATED_BIAS, &pos->active); - pos->flags |= KERNFS_ACTIVATED; - } - + __kernfs_activate(kn); up_write(&root->kernfs_rwsem); }