On Wed, May 01, 2013 at 02:30:48PM -0700, John Johansen wrote:
> remove the use of replaced by chaining and move to profile invalidation
> and lookup to handle task replacement.
> 
> Replacement chaining can result in large chains of profiles being pinned
> in memory when one profile in the chain is use. With implicit labeling
> this will be even more of a problem, so move to a direct lookup method.

Could you explain the old_replacedby in the following few chunks? I just
can't make heads or tails of why it works the way it does. Thanks.

> @@ -992,6 +995,7 @@ static struct aa_profile *__list_lookup_parent(struct 
> list_head *lh,
>   * __replace_profile - replace @old with @new on a list
>   * @old: profile to be replaced  (NOT NULL)
>   * @new: profile to replace @old with  (NOT NULL)
> + * @old_replacedby: transfer @old->replacedby to @new
>   *
>   * Will duplicate and refcount elements that @new inherits from @old
>   * and will inherit @old children.
> @@ -1000,7 +1004,8 @@ static struct aa_profile *__list_lookup_parent(struct 
> list_head *lh,
>   *
>   * Requires: namespace list lock be held, or list not be shared
>   */
> -static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
> +static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
> +                           int old_replacedby)
>  {
>       struct aa_profile *child, *tmp;
>  
> @@ -1015,7 +1020,7 @@ static void __replace_profile(struct aa_profile *old, 
> struct aa_profile *new)
>                       p = __find_child(&new->base.profiles, child->base.name);
>                       if (p) {
>                               /* @p replaces @child  */
> -                             __replace_profile(child, p);
> +                             __replace_profile(child, p, old_replacedby);
>                               continue;
>                       }
>  
> @@ -1034,8 +1039,11 @@ static void __replace_profile(struct aa_profile *old, 
> struct aa_profile *new)
>               struct aa_profile *parent = rcu_dereference(old->parent);
>               rcu_assign_pointer(new->parent, aa_get_profile(parent));
>       }
> -     /* released by free_profile */
> -     old->replacedby = aa_get_profile(new);
> +     __aa_update_replacedby(old, new);
> +     if (old_replacedby) {
> +             aa_put_replacedby(new->replacedby);
> +             new->replacedby = aa_get_replacedby(old->replacedby);
> +     }
>  
>       if (list_empty_rcu(&new->base.list)) {
>               /* new is not on a list already */
> @@ -1159,23 +1167,24 @@ ssize_t aa_replace_profiles(void *udata, size_t size, 
> bool noreplace)
>               audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
>  
>               if (ent->old) {
> -                     __replace_profile(ent->old, ent->new);
> +                     __replace_profile(ent->old, ent->new, 1);
>                       if (ent->rename)
> -                             __replace_profile(ent->rename, ent->new);
> +                             __replace_profile(ent->rename, ent->new, 0);
>               } else if (ent->rename) {
> -                     __replace_profile(ent->rename, ent->new);
> +                     __replace_profile(ent->rename, ent->new, 0);
>               } else if (ent->new->parent) {
>                       struct aa_profile *parent, *newest;
>                       parent = rcu_dereference_protected(ent->new->parent,
>                                                    
> mutex_is_locked(&ns->lock));
> -                     newest = aa_newest_version(parent);
> +                     newest = aa_get_newest_profile(parent);
>  
>                       /* parent replaced in this atomic set? */
>                       if (newest != parent) {
>                               aa_get_profile(newest);
>                               aa_put_profile(parent);
>                               rcu_assign_pointer(ent->new->parent, newest);
> -                     }
> +                     } else
> +                             aa_put_profile(newest);
>                       __list_add_profile(&parent->base.profiles, ent->new);
>               } else
>                       __list_add_profile(&ns->base.profiles, ent->new);
> -- 
> 1.8.1.2
> 
> 
> -- 
> AppArmor mailing list
> AppArmor@lists.ubuntu.com
> Modify settings or unsubscribe at: 
> https://lists.ubuntu.com/mailman/listinfo/apparmor
> 

Attachment: signature.asc
Description: Digital signature

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to