Skip to content

Commit c254917

Browse files
htejungregkh
authored andcommitted
kernfs: Add KERNFS_REMOVING flags
KERNFS_ACTIVATED tracks whether a given node has ever been activated. As a node was only deactivated on removal, this was used for 1. Drain optimization (removed by the previous patch). 2. To hide !activated nodes 3. To avoid double activations 4. Reject adding children to a node being removed 5. Skip activaing a node which is being removed. We want to decouple deactivation from removal so that nodes can be deactivated and hidden dynamically, which makes KERNFS_ACTIVATED useless for all of the above purposes. #1 is already gone. #2 and #3 can instead test whether the node is currently active. A new flag KERNFS_REMOVING is added to explicitly mark nodes which are being removed for #4 and #5. While this leaves KERNFS_ACTIVATED with no users, leave it be as it will be used in a following patch. Cc: Chengming Zhou <[email protected]> Tested-by: Chengming Zhou <[email protected]> Reviewed-by: Chengming Zhou <[email protected]> Signed-off-by: Tejun Heo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 2d7f9f8 commit c254917

File tree

2 files changed

+8
-14
lines changed

2 files changed

+8
-14
lines changed

fs/kernfs/dir.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -705,13 +705,7 @@ struct kernfs_node *kernfs_find_and_get_node_by_id(struct kernfs_root *root,
705705
goto err_unlock;
706706
}
707707

708-
/*
709-
* ACTIVATED is protected with kernfs_mutex but it was clear when
710-
* @kn was added to idr and we just wanna see it set. No need to
711-
* grab kernfs_mutex.
712-
*/
713-
if (unlikely(!(kn->flags & KERNFS_ACTIVATED) ||
714-
!atomic_inc_not_zero(&kn->count)))
708+
if (unlikely(!kernfs_active(kn) || !atomic_inc_not_zero(&kn->count)))
715709
goto err_unlock;
716710

717711
spin_unlock(&kernfs_idr_lock);
@@ -753,10 +747,7 @@ int kernfs_add_one(struct kernfs_node *kn)
753747
goto out_unlock;
754748

755749
ret = -ENOENT;
756-
if (parent->flags & KERNFS_EMPTY_DIR)
757-
goto out_unlock;
758-
759-
if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent))
750+
if (parent->flags & (KERNFS_REMOVING | KERNFS_EMPTY_DIR))
760751
goto out_unlock;
761752

762753
kn->hash = kernfs_name_hash(kn->name, kn->ns);
@@ -1336,7 +1327,7 @@ void kernfs_activate(struct kernfs_node *kn)
13361327

13371328
pos = NULL;
13381329
while ((pos = kernfs_next_descendant_post(pos, kn))) {
1339-
if (pos->flags & KERNFS_ACTIVATED)
1330+
if (kernfs_active(pos) || (pos->flags & KERNFS_REMOVING))
13401331
continue;
13411332

13421333
WARN_ON_ONCE(pos->parent && RB_EMPTY_NODE(&pos->rb));
@@ -1368,11 +1359,13 @@ static void __kernfs_remove(struct kernfs_node *kn)
13681359

13691360
pr_debug("kernfs %s: removing\n", kn->name);
13701361

1371-
/* prevent any new usage under @kn by deactivating all nodes */
1362+
/* prevent new usage by marking all nodes removing and deactivating */
13721363
pos = NULL;
1373-
while ((pos = kernfs_next_descendant_post(pos, kn)))
1364+
while ((pos = kernfs_next_descendant_post(pos, kn))) {
1365+
pos->flags |= KERNFS_REMOVING;
13741366
if (kernfs_active(pos))
13751367
atomic_add(KN_DEACTIVATED_BIAS, &pos->active);
1368+
}
13761369

13771370
/* deactivate and unlink the subtree node-by-node */
13781371
do {

include/linux/kernfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ enum kernfs_node_flag {
112112
KERNFS_SUICIDED = 0x0800,
113113
KERNFS_EMPTY_DIR = 0x1000,
114114
KERNFS_HAS_RELEASE = 0x2000,
115+
KERNFS_REMOVING = 0x4000,
115116
};
116117

117118
/* @flags for kernfs_create_root() */

0 commit comments

Comments
 (0)