From ad49c8bba20b611c101c6bd53cbb33d77cd496c6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 20 Feb 2013 13:16:09 +1100 Subject: [PATCH] idr: implement idr_preload[_end]() and idr_alloc() v3: In idr_alloc() treat @end <= 0 as indicating max. This is necessary to always allow using @start + N as @end for a positive integer N. Signed-off-by: Tejun Heo Cc: Rusty Russell Signed-off-by: Andrew Morton --- lib/idr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/idr.c b/lib/idr.c index 511570584b2f..2d016f5c410e 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -439,13 +439,16 @@ EXPORT_SYMBOL(idr_preload); * @idr: the (initialized) idr * @ptr: pointer to be associated with the new id * @start: the minimum id (inclusive) - * @end: the maximum id (exclusive, 0 for max) + * @end: the maximum id (exclusive, <= 0 for max) * @gfp_mask: memory allocation flags * * Allocate an id in [start, end) and associate it with @ptr. If no ID is * available in the specified range, returns -ENOSPC. On memory allocation * failure, returns -ENOMEM. * + * Note that @end is treated as max when <= 0. This is to always allow + * using @start + N as @end as long as N is inside integer range. + * * The user is responsible for exclusively synchronizing all operations * which may modify @idr. However, read-only accesses such as idr_find() * or iteration can be performed under RCU read lock provided the user @@ -453,14 +456,14 @@ EXPORT_SYMBOL(idr_preload); */ int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask) { - int max = end ? end - 1 : INT_MAX; /* inclusive upper limit */ + int max = end > 0 ? end - 1 : INT_MAX; /* inclusive upper limit */ struct idr_layer *pa[MAX_IDR_LEVEL]; int id; might_sleep_if(gfp_mask & __GFP_WAIT); /* sanity checks */ - if (WARN_ON_ONCE(start < 0 || end < 0)) + if (WARN_ON_ONCE(start < 0)) return -EINVAL; if (unlikely(max < start)) return -ENOSPC; -- 2.39.5