idr: Add idr_alloc_u32 helper
All current users of idr_alloc_ext() actually want to allocate a u32 and idr_alloc_u32() fits their needs better. Like idr_get_next(), it uses a 'nextid' argument which serves as both a pointer to the start ID and the assigned ID (instead of a separate minimum and pointer-to-assigned-ID argument). It uses a 'max' argument rather than 'end' because the semantics that idr_alloc has for 'end' don't work well for unsigned types. Since idr_alloc_u32() returns an errno instead of the allocated ID, mark it as __must_check to help callers use it correctly. Include copious kernel-doc. Chris Mi <chrism@mellanox.com> has promised to contribute test-cases for idr_alloc_u32. Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
This commit is contained in:
Родитель
322d884ba7
Коммит
e096f6a762
|
@ -131,6 +131,8 @@ static inline int idr_alloc_ext(struct idr *idr, void *ptr,
|
|||
return idr_alloc_cmn(idr, ptr, index, start, end, gfp, true);
|
||||
}
|
||||
|
||||
int __must_check idr_alloc_u32(struct idr *, void *ptr, u32 *nextid,
|
||||
unsigned long max, gfp_t);
|
||||
int idr_alloc_cyclic(struct idr *, void *entry, int start, int end, gfp_t);
|
||||
int idr_for_each(const struct idr *,
|
||||
int (*fn)(int id, void *p, void *data), void *data);
|
||||
|
|
31
lib/idr.c
31
lib/idr.c
|
@ -7,6 +7,37 @@
|
|||
DEFINE_PER_CPU(struct ida_bitmap *, ida_bitmap);
|
||||
static DEFINE_SPINLOCK(simple_ida_lock);
|
||||
|
||||
/**
|
||||
* idr_alloc_u32() - Allocate an ID.
|
||||
* @idr: IDR handle.
|
||||
* @ptr: Pointer to be associated with the new ID.
|
||||
* @nextid: Pointer to an ID.
|
||||
* @max: The maximum ID to allocate (inclusive).
|
||||
* @gfp: Memory allocation flags.
|
||||
*
|
||||
* Allocates an unused ID in the range specified by @nextid and @max.
|
||||
* Note that @max is inclusive whereas the @end parameter to idr_alloc()
|
||||
* is exclusive.
|
||||
*
|
||||
* The caller should provide their own locking to ensure that two
|
||||
* concurrent modifications to the IDR are not possible. Read-only
|
||||
* accesses to the IDR may be done under the RCU read lock or may
|
||||
* exclude simultaneous writers.
|
||||
*
|
||||
* Return: 0 if an ID was allocated, -ENOMEM if memory allocation failed,
|
||||
* or -ENOSPC if no free IDs could be found. If an error occurred,
|
||||
* @nextid is unchanged.
|
||||
*/
|
||||
int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,
|
||||
unsigned long max, gfp_t gfp)
|
||||
{
|
||||
unsigned long tmp = *nextid;
|
||||
int ret = idr_alloc_ext(idr, ptr, &tmp, tmp, max + 1, gfp);
|
||||
*nextid = tmp;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(idr_alloc_u32);
|
||||
|
||||
int idr_alloc_cmn(struct idr *idr, void *ptr, unsigned long *index,
|
||||
unsigned long start, unsigned long end, gfp_t gfp,
|
||||
bool ext)
|
||||
|
|
Загрузка…
Ссылка в новой задаче