Skip to content

Commit 783bd07

Browse files
htejungregkh
authored andcommitted
kernfs: Implement kernfs_show()
Currently, kernfs nodes can be created hidden and activated later by calling kernfs_activate() to allow creation of multiple nodes to succeed or fail as a unit. This is an one-way one-time-only transition. This patch introduces kernfs_show() which can toggle visibility dynamically. As the currently proposed use - toggling the cgroup pressure files - only requires operating on leaf nodes, for the sake of simplicity, restrict it as such for now. Hiding uses the same mechanism as deactivation and likewise guarantees that there are no in-flight operations on completion. KERNFS_ACTIVATED and KERNFS_HIDDEN are used to manage the interactions between activations and show/hide operations. A node is visible iff both activated & !hidden. Cc: Chengming Zhou <[email protected]> Cc: Johannes Weiner <[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 f8eb145 commit 783bd07

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

fs/kernfs/dir.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,7 @@ static void kernfs_activate_one(struct kernfs_node *kn)
13111311

13121312
kn->flags |= KERNFS_ACTIVATED;
13131313

1314-
if (kernfs_active(kn) || (kn->flags & KERNFS_REMOVING))
1314+
if (kernfs_active(kn) || (kn->flags & (KERNFS_HIDDEN | KERNFS_REMOVING)))
13151315
return;
13161316

13171317
WARN_ON_ONCE(kn->parent && RB_EMPTY_NODE(&kn->rb));
@@ -1347,6 +1347,41 @@ void kernfs_activate(struct kernfs_node *kn)
13471347
up_write(&root->kernfs_rwsem);
13481348
}
13491349

1350+
/**
1351+
* kernfs_show - show or hide a node
1352+
* @kn: kernfs_node to show or hide
1353+
* @show: whether to show or hide
1354+
*
1355+
* If @show is %false, @kn is marked hidden and deactivated. A hidden node is
1356+
* ignored in future activaitons. If %true, the mark is removed and activation
1357+
* state is restored. This function won't implicitly activate a new node in a
1358+
* %KERNFS_ROOT_CREATE_DEACTIVATED root which hasn't been activated yet.
1359+
*
1360+
* To avoid recursion complexities, directories aren't supported for now.
1361+
*/
1362+
void kernfs_show(struct kernfs_node *kn, bool show)
1363+
{
1364+
struct kernfs_root *root = kernfs_root(kn);
1365+
1366+
if (WARN_ON_ONCE(kernfs_type(kn) == KERNFS_DIR))
1367+
return;
1368+
1369+
down_write(&root->kernfs_rwsem);
1370+
1371+
if (show) {
1372+
kn->flags &= ~KERNFS_HIDDEN;
1373+
if (kn->flags & KERNFS_ACTIVATED)
1374+
kernfs_activate_one(kn);
1375+
} else {
1376+
kn->flags |= KERNFS_HIDDEN;
1377+
if (kernfs_active(kn))
1378+
atomic_add(KN_DEACTIVATED_BIAS, &kn->active);
1379+
kernfs_drain(kn);
1380+
}
1381+
1382+
up_write(&root->kernfs_rwsem);
1383+
}
1384+
13501385
static void __kernfs_remove(struct kernfs_node *kn)
13511386
{
13521387
struct kernfs_node *pos;

include/linux/kernfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ enum kernfs_node_flag {
108108
KERNFS_HAS_SEQ_SHOW = 0x0040,
109109
KERNFS_HAS_MMAP = 0x0080,
110110
KERNFS_LOCKDEP = 0x0100,
111+
KERNFS_HIDDEN = 0x0200,
111112
KERNFS_SUICIDAL = 0x0400,
112113
KERNFS_SUICIDED = 0x0800,
113114
KERNFS_EMPTY_DIR = 0x1000,
@@ -430,6 +431,7 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
430431
const char *name,
431432
struct kernfs_node *target);
432433
void kernfs_activate(struct kernfs_node *kn);
434+
void kernfs_show(struct kernfs_node *kn, bool show);
433435
void kernfs_remove(struct kernfs_node *kn);
434436
void kernfs_break_active_protection(struct kernfs_node *kn);
435437
void kernfs_unbreak_active_protection(struct kernfs_node *kn);

0 commit comments

Comments
 (0)