Re: [PATCH v2 2/4] device_cgroup: keep track of local group settings
On Thu, Jan 24, 2013 at 02:49:59PM -0500, a...@redhat.com wrote: > In preparation for better hierarchy support, it's needed to retain the local > settings in order to try to reapply them after a propagated change if they're > still valid. > > Cc: Tejun Heo > Cc: Serge Hallyn > Signed-off-by: Aristeu Rozanski Looks okay to me but it would be better if you separate out moving dev_exception_rm() above dev_exception_add() into a separate patch. It currently mixes functional and non-functional changes which isn't very nice. Thanks. -- tejun -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/4] device_cgroup: keep track of local group settings
In preparation for better hierarchy support, it's needed to retain the local settings in order to try to reapply them after a propagated change if they're still valid. Cc: Tejun Heo Cc: Serge Hallyn Signed-off-by: Aristeu Rozanski --- security/device_cgroup.c | 115 +-- 1 file changed, 83 insertions(+), 32 deletions(-) --- github.orig/security/device_cgroup.c2013-01-24 10:40:33.913068234 -0500 +++ github/security/device_cgroup.c 2013-01-24 10:40:46.384253615 -0500 @@ -39,13 +39,27 @@ struct dev_exception_item { struct rcu_head rcu; }; +enum devcg_behavior { + DEVCG_DEFAULT_NONE, + DEVCG_DEFAULT_ALLOW, + DEVCG_DEFAULT_DENY, +}; + struct dev_cgroup { struct cgroup_subsys_state css; + + /* result of merging the parent's rules with local ones */ struct list_head exceptions; - enum { - DEVCG_DEFAULT_ALLOW, - DEVCG_DEFAULT_DENY, - } behavior; + enum devcg_behavior behavior; + + /* +* local set rules, saved so when a parent propagates new rules, the +* local preferences can be preserved +*/ + struct { + struct list_head exceptions; + enum devcg_behavior behavior; + } local; }; static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) @@ -104,8 +118,41 @@ free_and_exit: /* * called under devcgroup_mutex */ -static int dev_exception_add(struct list_head *exceptions, -struct dev_exception_item *ex) +static void __dev_exception_rm(struct list_head *exceptions, + struct dev_exception_item *ex) +{ + struct dev_exception_item *walk, *tmp; + + lockdep_assert_held(_mutex); + + list_for_each_entry_safe(walk, tmp, exceptions, list) { + if (walk->type != ex->type) + continue; + if (walk->major != ex->major) + continue; + if (walk->minor != ex->minor) + continue; + + walk->access &= ~ex->access; + if (!walk->access) { + list_del_rcu(>list); + kfree_rcu(walk, rcu); + } + } +} + +static void dev_exception_rm(struct dev_cgroup *devcgroup, + struct dev_exception_item *ex) +{ + __dev_exception_rm(>local.exceptions, ex); + __dev_exception_rm(>exceptions, ex); +} + +/* + * called under devcgroup_mutex + */ +static int __dev_exception_add(struct list_head *exceptions, + struct dev_exception_item *ex) { struct dev_exception_item *excopy, *walk; @@ -133,30 +180,26 @@ static int dev_exception_add(struct list return 0; } -/* - * called under devcgroup_mutex - */ -static void dev_exception_rm(struct list_head *exceptions, +static int dev_exception_add(struct dev_cgroup *devcgroup, struct dev_exception_item *ex) { - struct dev_exception_item *walk, *tmp; + int rc; lockdep_assert_held(_mutex); - list_for_each_entry_safe(walk, tmp, exceptions, list) { - if (walk->type != ex->type) - continue; - if (walk->major != ex->major) - continue; - if (walk->minor != ex->minor) - continue; + /* +* we add to the local list so we can preserve local preferences if +* the parent propagates down new rules +*/ + rc = __dev_exception_add(>local.exceptions, ex); + if (rc) + return rc; + + rc = __dev_exception_add(>exceptions, ex); + if (rc) + __dev_exception_rm(>local.exceptions, ex); - walk->access &= ~ex->access; - if (!walk->access) { - list_del_rcu(>list); - kfree_rcu(walk, rcu); - } - } + return rc; } static void __dev_exception_clean(struct dev_cgroup *dev_cgroup) @@ -167,6 +210,11 @@ static void __dev_exception_clean(struct list_del_rcu(>list); kfree_rcu(ex, rcu); } + list_for_each_entry_safe(ex, tmp, _cgroup->local.exceptions, +list) { + list_del_rcu(>list); + kfree_rcu(ex, rcu); + } } /** @@ -195,6 +243,8 @@ static struct cgroup_subsys_state *devcg if (!dev_cgroup) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(_cgroup->exceptions); + INIT_LIST_HEAD(_cgroup->local.exceptions); + dev_cgroup->local.behavior = DEVCG_DEFAULT_NONE; parent_cgroup = cgroup->parent; if (parent_cgroup == NULL) @@ -413,18 +463,19 @@ memset(, 0, sizeof(ex)); if (!may_allow_all(parent))
[PATCH v2 2/4] device_cgroup: keep track of local group settings
In preparation for better hierarchy support, it's needed to retain the local settings in order to try to reapply them after a propagated change if they're still valid. Cc: Tejun Heo t...@kernel.org Cc: Serge Hallyn serge.hal...@canonical.com Signed-off-by: Aristeu Rozanski a...@redhat.com --- security/device_cgroup.c | 115 +-- 1 file changed, 83 insertions(+), 32 deletions(-) --- github.orig/security/device_cgroup.c2013-01-24 10:40:33.913068234 -0500 +++ github/security/device_cgroup.c 2013-01-24 10:40:46.384253615 -0500 @@ -39,13 +39,27 @@ struct dev_exception_item { struct rcu_head rcu; }; +enum devcg_behavior { + DEVCG_DEFAULT_NONE, + DEVCG_DEFAULT_ALLOW, + DEVCG_DEFAULT_DENY, +}; + struct dev_cgroup { struct cgroup_subsys_state css; + + /* result of merging the parent's rules with local ones */ struct list_head exceptions; - enum { - DEVCG_DEFAULT_ALLOW, - DEVCG_DEFAULT_DENY, - } behavior; + enum devcg_behavior behavior; + + /* +* local set rules, saved so when a parent propagates new rules, the +* local preferences can be preserved +*/ + struct { + struct list_head exceptions; + enum devcg_behavior behavior; + } local; }; static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) @@ -104,8 +118,41 @@ free_and_exit: /* * called under devcgroup_mutex */ -static int dev_exception_add(struct list_head *exceptions, -struct dev_exception_item *ex) +static void __dev_exception_rm(struct list_head *exceptions, + struct dev_exception_item *ex) +{ + struct dev_exception_item *walk, *tmp; + + lockdep_assert_held(devcgroup_mutex); + + list_for_each_entry_safe(walk, tmp, exceptions, list) { + if (walk-type != ex-type) + continue; + if (walk-major != ex-major) + continue; + if (walk-minor != ex-minor) + continue; + + walk-access = ~ex-access; + if (!walk-access) { + list_del_rcu(walk-list); + kfree_rcu(walk, rcu); + } + } +} + +static void dev_exception_rm(struct dev_cgroup *devcgroup, + struct dev_exception_item *ex) +{ + __dev_exception_rm(devcgroup-local.exceptions, ex); + __dev_exception_rm(devcgroup-exceptions, ex); +} + +/* + * called under devcgroup_mutex + */ +static int __dev_exception_add(struct list_head *exceptions, + struct dev_exception_item *ex) { struct dev_exception_item *excopy, *walk; @@ -133,30 +180,26 @@ static int dev_exception_add(struct list return 0; } -/* - * called under devcgroup_mutex - */ -static void dev_exception_rm(struct list_head *exceptions, +static int dev_exception_add(struct dev_cgroup *devcgroup, struct dev_exception_item *ex) { - struct dev_exception_item *walk, *tmp; + int rc; lockdep_assert_held(devcgroup_mutex); - list_for_each_entry_safe(walk, tmp, exceptions, list) { - if (walk-type != ex-type) - continue; - if (walk-major != ex-major) - continue; - if (walk-minor != ex-minor) - continue; + /* +* we add to the local list so we can preserve local preferences if +* the parent propagates down new rules +*/ + rc = __dev_exception_add(devcgroup-local.exceptions, ex); + if (rc) + return rc; + + rc = __dev_exception_add(devcgroup-exceptions, ex); + if (rc) + __dev_exception_rm(devcgroup-local.exceptions, ex); - walk-access = ~ex-access; - if (!walk-access) { - list_del_rcu(walk-list); - kfree_rcu(walk, rcu); - } - } + return rc; } static void __dev_exception_clean(struct dev_cgroup *dev_cgroup) @@ -167,6 +210,11 @@ static void __dev_exception_clean(struct list_del_rcu(ex-list); kfree_rcu(ex, rcu); } + list_for_each_entry_safe(ex, tmp, dev_cgroup-local.exceptions, +list) { + list_del_rcu(ex-list); + kfree_rcu(ex, rcu); + } } /** @@ -195,6 +243,8 @@ static struct cgroup_subsys_state *devcg if (!dev_cgroup) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(dev_cgroup-exceptions); + INIT_LIST_HEAD(dev_cgroup-local.exceptions); + dev_cgroup-local.behavior = DEVCG_DEFAULT_NONE; parent_cgroup = cgroup-parent; if (parent_cgroup == NULL) @@ -413,18 +463,19
Re: [PATCH v2 2/4] device_cgroup: keep track of local group settings
On Thu, Jan 24, 2013 at 02:49:59PM -0500, a...@redhat.com wrote: In preparation for better hierarchy support, it's needed to retain the local settings in order to try to reapply them after a propagated change if they're still valid. Cc: Tejun Heo t...@kernel.org Cc: Serge Hallyn serge.hal...@canonical.com Signed-off-by: Aristeu Rozanski a...@redhat.com Looks okay to me but it would be better if you separate out moving dev_exception_rm() above dev_exception_add() into a separate patch. It currently mixes functional and non-functional changes which isn't very nice. Thanks. -- tejun -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/