idr: separate out idr_mark_full()
Separate out idr_mark_full() from sub_alloc() and make marking the allocated slot full the responsibility of idr_get_new_above_int(). Allocation part of idr_get_new_above_int() is renamed to idr_get_empty_slot(). New idr_get_new_above_int() allocates a slot using the function, install the user pointer and marks it full using idr_mark_full(). This change doesn't introduce any behavior change. This will be used by ida. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
7aae6dd80e
commit
e33ac8bdb0
71
lib/idr.c
71
lib/idr.c
|
@ -70,6 +70,26 @@ static void free_layer(struct idr *idp, struct idr_layer *p)
|
||||||
spin_unlock_irqrestore(&idp->lock, flags);
|
spin_unlock_irqrestore(&idp->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void idr_mark_full(struct idr_layer **pa, int id)
|
||||||
|
{
|
||||||
|
struct idr_layer *p = pa[0];
|
||||||
|
int l = 0;
|
||||||
|
|
||||||
|
__set_bit(id & IDR_MASK, &p->bitmap);
|
||||||
|
/*
|
||||||
|
* If this layer is full mark the bit in the layer above to
|
||||||
|
* show that this part of the radix tree is full. This may
|
||||||
|
* complete the layer above and require walking up the radix
|
||||||
|
* tree.
|
||||||
|
*/
|
||||||
|
while (p->bitmap == IDR_FULL) {
|
||||||
|
if (!(p = pa[++l]))
|
||||||
|
break;
|
||||||
|
id = id >> IDR_BITS;
|
||||||
|
__set_bit((id & IDR_MASK), &p->bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* idr_pre_get - reserver resources for idr allocation
|
* idr_pre_get - reserver resources for idr allocation
|
||||||
* @idp: idr handle
|
* @idp: idr handle
|
||||||
|
@ -95,11 +115,10 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(idr_pre_get);
|
EXPORT_SYMBOL(idr_pre_get);
|
||||||
|
|
||||||
static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
|
static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
|
||||||
{
|
{
|
||||||
int n, m, sh;
|
int n, m, sh;
|
||||||
struct idr_layer *p, *new;
|
struct idr_layer *p, *new;
|
||||||
struct idr_layer *pa[MAX_LEVEL];
|
|
||||||
int l, id, oid;
|
int l, id, oid;
|
||||||
long bm;
|
long bm;
|
||||||
|
|
||||||
|
@ -156,30 +175,13 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
|
||||||
pa[l--] = p;
|
pa[l--] = p;
|
||||||
p = p->ary[m];
|
p = p->ary[m];
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* We have reached the leaf node, plant the
|
pa[l] = p;
|
||||||
* users pointer and return the raw id.
|
return id;
|
||||||
*/
|
|
||||||
p->ary[m] = (struct idr_layer *)ptr;
|
|
||||||
__set_bit(m, &p->bitmap);
|
|
||||||
p->count++;
|
|
||||||
/*
|
|
||||||
* If this layer is full mark the bit in the layer above
|
|
||||||
* to show that this part of the radix tree is full.
|
|
||||||
* This may complete the layer above and require walking
|
|
||||||
* up the radix tree.
|
|
||||||
*/
|
|
||||||
n = id;
|
|
||||||
while (p->bitmap == IDR_FULL) {
|
|
||||||
if (!(p = pa[++l]))
|
|
||||||
break;
|
|
||||||
n = n >> IDR_BITS;
|
|
||||||
__set_bit((n & IDR_MASK), &p->bitmap);
|
|
||||||
}
|
|
||||||
return(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
|
static int idr_get_empty_slot(struct idr *idp, int starting_id,
|
||||||
|
struct idr_layer **pa)
|
||||||
{
|
{
|
||||||
struct idr_layer *p, *new;
|
struct idr_layer *p, *new;
|
||||||
int layers, v, id;
|
int layers, v, id;
|
||||||
|
@ -225,12 +227,31 @@ build_up:
|
||||||
}
|
}
|
||||||
idp->top = p;
|
idp->top = p;
|
||||||
idp->layers = layers;
|
idp->layers = layers;
|
||||||
v = sub_alloc(idp, ptr, &id);
|
v = sub_alloc(idp, &id, pa);
|
||||||
if (v == -2)
|
if (v == -2)
|
||||||
goto build_up;
|
goto build_up;
|
||||||
return(v);
|
return(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
|
||||||
|
{
|
||||||
|
struct idr_layer *pa[MAX_LEVEL];
|
||||||
|
int id;
|
||||||
|
|
||||||
|
id = idr_get_empty_slot(idp, starting_id, pa);
|
||||||
|
if (id >= 0) {
|
||||||
|
/*
|
||||||
|
* Successfully found an empty slot. Install the user
|
||||||
|
* pointer and mark the slot full.
|
||||||
|
*/
|
||||||
|
pa[0]->ary[id & IDR_MASK] = (struct idr_layer *)ptr;
|
||||||
|
pa[0]->count++;
|
||||||
|
idr_mark_full(pa, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* idr_get_new_above - allocate new idr entry above or equal to a start id
|
* idr_get_new_above - allocate new idr entry above or equal to a start id
|
||||||
* @idp: idr handle
|
* @idp: idr handle
|
||||||
|
|
Loading…
Reference in New Issue