The commit is pushed to "branch-rh10-6.12.0-55.13.1.3.x.vz10-ovz" and will 
appear at [email protected]:openvz/vzkernel.git
after rh10-6.12.0-55.13.1.3.25.vz10
------>
commit a05a668cf1c9f8c7bff5e89a4a6bbcd43271593a
Author: Pavel Tikhomirov <[email protected]>
Date:   Mon Dec 15 19:21:56 2025 +0800

    cgroup-v2: Fix error handling in cgroup_controllers_hidden_write()
    
    Currently if there is a population error, we can end up with partially
    applied mask, which is not what we want, let's do a proper cleanup.
    
    Split cgroup_apply_hidden() into two separate helpers for showing and
    hiding: cgroup_unhide() and cgroup_hide(). As cgroup_hide() never fails
    we can easily use it for both hiding on success path and cleanup on
    error path of cgroup_unhide() with restored old mask.
    
    While on it let's add small comments to those helpers.
    
    https://virtuozzo.atlassian.net/browse/VSTOR-119803
    Fixes: fbc4461a215c ("cgroup-v2: Add a new API to hide cgroup files per 
controller")
    Co-developed-by: Konstantin Khorenko <[email protected]>
    Signed-off-by: Pavel Tikhomirov <[email protected]>
    
    Feature: ve: ve generic structures
---
 kernel/cgroup/cgroup.c | 52 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index eb2b64f7da37b..92abecb000b19 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -3896,7 +3896,11 @@ static ssize_t cgroup_subtree_control_write(struct 
kernfs_open_file *of,
        return ret ?: nbytes;
 }
 
-static int cgroup_apply_hidden(struct cgroup *cgrp)
+/*
+ * cgroup_unhide() - Apply cleared bits in hidden_ss_mask to the cgroup
+ * directory by populating files for visible controllers.
+ */
+static int cgroup_unhide(struct cgroup *cgrp)
 {
        struct cgroup_subsys *ss;
        int ssid;
@@ -3916,14 +3920,36 @@ static int cgroup_apply_hidden(struct cgroup *cgrp)
                        ret = css_populate_dir(css);
                        if (ret)
                                return ret;
-               } else {
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * cgroup_hide() - Apply set bits in hidden_ss_mask to the cgroup
+ * directory by clearing files for hidden controllers.
+ */
+static void cgroup_hide(struct cgroup *cgrp)
+{
+       struct cgroup_subsys *ss;
+       int ssid;
+
+       for_each_subsys(ss, ssid) {
+               struct cgroup_subsys_state *css = cgroup_css(cgrp, ss);
+
+               if (!(cgroup_ss_mask(cgrp) & (1 << ss->id)))
+                       continue;
+
+               if (!css)
+                       continue;
+
+               if (!css_visible(css)) {
                        css_clear_dir(css);
                        if (ss->css_reset)
                                ss->css_reset(css);
                }
        }
-
-       return 0;
 }
 
 /* change the hidden controllers for a cgroup in the default hierarchy */
@@ -3933,6 +3959,7 @@ static ssize_t cgroup_controllers_hidden_write(struct 
kernfs_open_file *of,
 {
        struct cgroup_subsys *ss;
        u16 hide = 0, show = 0;
+       u16 old_hidden_ss_mask;
        struct cgroup *cgrp;
        int ssid, ret;
        char *tok;
@@ -3988,10 +4015,23 @@ static ssize_t cgroup_controllers_hidden_write(struct 
kernfs_open_file *of,
                goto out_unlock;
        }
 
-       cgrp->hidden_ss_mask |= hide;
+       /*
+        * This is similar to cgroup_apply_control_enable(). We first try to
+        * populate dirs for controllers being shown, and on success, hide the
+        * controllers being hidden. On error we restore the old mask and hide
+        * any dirs that might have been populated in cgroup_unhide().
+        */
+       old_hidden_ss_mask = cgroup_hidden_ss_mask(cgrp);
        cgrp->hidden_ss_mask &= ~show;
 
-       ret = cgroup_apply_hidden(cgrp);
+       ret = cgroup_unhide(cgrp);
+       if (ret)
+               /* Restore old mask on failure */
+               cgrp->hidden_ss_mask = old_hidden_ss_mask;
+       else
+               cgrp->hidden_ss_mask |= hide;
+
+       cgroup_hide(cgrp);
        if (ret)
                goto out_unlock;
 
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to