*/
#define AA_FIRST_SECID 2
-static DEFINE_IDR(aa_secids);
-static DEFINE_SPINLOCK(secid_lock);
+static DEFINE_XARRAY_FLAGS(aa_secids, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
/*
* TODO: allow policy to reserve a secid range?
{
unsigned long flags;
- spin_lock_irqsave(&secid_lock, flags);
- idr_replace(&aa_secids, label, secid);
- spin_unlock_irqrestore(&secid_lock, flags);
+ xa_lock_irqsave(&aa_secids, flags);
+ __xa_store(&aa_secids, secid - AA_FIRST_SECID, label, 0);
+ xa_unlock_irqrestore(&aa_secids, flags);
}
/**
*/
struct aa_label *aa_secid_to_label(u32 secid)
{
- struct aa_label *label;
-
- rcu_read_lock();
- label = idr_find(&aa_secids, secid);
- rcu_read_unlock();
-
- return label;
+ return xa_load(&aa_secids, secid - AA_FIRST_SECID);
}
int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
* @label: the label to allocate a secid for
* @gfp: memory allocation flags
*
- * Returns: 0 with @label->secid initialized
- * <0 returns error with @label->secid set to AA_SECID_INVALID
+ * Return: 0 with @label->secid initialized
+ * <0 returns error with @label->secid set to AA_SECID_INVALID
*/
int aa_alloc_secid(struct aa_label *label, gfp_t gfp)
{
unsigned long flags;
- int ret;
+ int err;
- idr_preload(gfp);
- spin_lock_irqsave(&secid_lock, flags);
- ret = idr_alloc(&aa_secids, label, AA_FIRST_SECID, 0, GFP_ATOMIC);
- spin_unlock_irqrestore(&secid_lock, flags);
- idr_preload_end();
+ label->secid = AA_SECID_INVALID;
- if (ret < 0) {
- label->secid = AA_SECID_INVALID;
- return ret;
- }
+ xa_lock_irqsave(&aa_secids, flags);
+ err = __xa_alloc(&aa_secids, &label->secid, label, xa_limit_32b, gfp);
+ if (!err)
+ label->secid += AA_FIRST_SECID;
+ xa_unlock_irqrestore(&aa_secids, flags);
- AA_BUG(ret == AA_SECID_INVALID);
- label->secid = ret;
- return 0;
+ return err;
}
/**
{
unsigned long flags;
- spin_lock_irqsave(&secid_lock, flags);
- idr_remove(&aa_secids, secid);
- spin_unlock_irqrestore(&secid_lock, flags);
-}
-
-void aa_secids_init(void)
-{
- idr_init_base(&aa_secids, AA_FIRST_SECID);
+ xa_lock_irqsave(&aa_secids, flags);
+ __xa_erase(&aa_secids, secid - AA_FIRST_SECID);
+ xa_unlock_irqrestore(&aa_secids, flags);
}