idr: Add idr_alloc_u32 helper

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/e096f6a762bc54d0e5d44ba8b196e70b58e04367
Commit:     e096f6a762bc54d0e5d44ba8b196e70b58e04367
Parent:     322d884ba731e05ca79ae58e9dee1ef7dc4de504
Refname:    refs/heads/master
Author:     Matthew Wilcox <[email protected]>
AuthorDate: Tue Nov 28 10:14:27 2017 -0500
Committer:  Matthew Wilcox <[email protected]>
CommitDate: Tue Feb 6 16:40:32 2018 -0500

    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 <[email protected]> has promised to contribute
    test-cases for idr_alloc_u32.
    
    Signed-off-by: Matthew Wilcox <[email protected]>
---
 include/linux/idr.h |  2 ++
 lib/idr.c           | 31 +++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/include/linux/idr.h b/include/linux/idr.h
index 7867d6117535..561a4cbabca6 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -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);
diff --git a/lib/idr.c b/lib/idr.c
index 577bfd4fe5c2..6d4ec2c2982b 100644
--- a/lib/idr.c
+++ b/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)
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.