}
void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max);
-void *_mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max,
- bool start);
+void *mt_find_after(struct maple_tree *mt, unsigned long *index,
+ unsigned long max);
void *mt_prev(struct maple_tree *mt, unsigned long index, unsigned long min);
void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max);
* Note: Will not return the zero entry.
*/
#define mt_for_each(tree, entry, index, max) \
- for (entry = _mt_find(tree, &index, max, true); \
- entry; entry = _mt_find(tree, &index, max, false))
+ for (entry = mt_find(tree, &index, max); \
+ entry; entry = mt_find_after(tree, &index, max))
#ifdef CONFIG_DEBUG_MAPLE_TREE
return -EBUSY;
}
-/*
- * _mt_find() - Search from start up until an entry is found.
- * @mt: The maple tree
- * @*index: Pointer which contains the start location of the search
- * @max: The maximum value to check
- * @start: If this is the first time being called or not.
- *. Does not return the zero entry. Handles locking.
- * Return: the entry or %NULL
- */
-void *_mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max,
- bool start)
-{
- unsigned long range_start = 0, range_end = 0;
- void *entry = NULL;
- bool leaf;
-#ifdef CONFIG_DEBUG_MAPLE_TREE
- unsigned long copy = *index;
-#endif
-
- MA_STATE(mas, mt, *index, *index);
-
- if ((*index) > max)
- return NULL;
-
- if (!start && !(*index))
- return NULL;
-
- rcu_read_lock();
- leaf = _mas_walk(&mas, &range_start, &range_end);
- if (leaf == true && mas.offset != MAPLE_NODE_SLOTS)
- entry = mas_get_slot(&mas, mas.offset);
-
- mas.last = range_end;
- if (entry && !xa_is_zero(entry)) {
- rcu_read_unlock();
- goto done;
- }
-
- mas.index = range_start;
- while (mas_searchable(&mas) && (mas.index < max)) {
- entry = mas_next_entry(&mas, max);
- if (likely(entry && !xa_is_zero(entry)))
- break;
- }
- rcu_read_unlock();
-
- if (unlikely(xa_is_zero(entry)))
- entry = NULL;
-done:
- if (likely(entry)) {
- *index = mas.last + 1;
-#ifdef CONFIG_DEBUG_MAPLE_TREE
- if ((*index) && (*index) <= copy)
- printk("index not increased! %lx <= %lx\n",
- *index, copy);
- MT_BUG_ON(mt, (*index) && ((*index) <= copy));
-#endif
- }
-
- return entry;
-}
-
/*
* mas_dead_leaves() - Mark all leaves of a node as dead.
* @mas: The maple state
*/
void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max)
{
- return _mt_find(mt, index, max, true);
+ unsigned long range_start = 0, range_end = 0;
+ void *entry = NULL;
+ bool leaf;
+#ifdef CONFIG_DEBUG_MAPLE_TREE
+ unsigned long copy = *index;
+#endif
+
+ MA_STATE(mas, mt, *index, *index);
+
+ if ((*index) > max)
+ return NULL;
+
+ rcu_read_lock();
+ leaf = _mas_walk(&mas, &range_start, &range_end);
+ if (leaf == true && mas.offset != MAPLE_NODE_SLOTS)
+ entry = mas_get_slot(&mas, mas.offset);
+
+ mas.last = range_end;
+ if (entry && !xa_is_zero(entry)) {
+ rcu_read_unlock();
+ goto done;
+ }
+
+ mas.index = range_start;
+ while (mas_searchable(&mas) && (mas.index < max)) {
+ entry = mas_next_entry(&mas, max);
+ if (likely(entry && !xa_is_zero(entry)))
+ break;
+ }
+ rcu_read_unlock();
+
+ if (unlikely(xa_is_zero(entry)))
+ entry = NULL;
+done:
+ if (likely(entry)) {
+ *index = mas.last + 1;
+#ifdef CONFIG_DEBUG_MAPLE_TREE
+ if ((*index) && (*index) <= copy)
+ printk("index not increased! %lx <= %lx\n",
+ *index, copy);
+ MT_BUG_ON(mt, (*index) && ((*index) <= copy));
+#endif
+ }
+
+ return entry;
}
EXPORT_SYMBOL(mt_find);
+/*
+ * mt_find_after() - Search from the start up until an entry is found.
+ * @mt: The maple tree
+ * @*index: Pointer which contains the start location of the search
+ * @max: The maximum value to check
+ *
+ * Handles locking, detects wrapping on *index == 0
+ *
+ * Return: The entry at or after the @*index or %NULL
+ */
+void *mt_find_after(struct maple_tree *mt, unsigned long *index,
+ unsigned long max)
+{
+ if (!(*index))
+ return NULL;
+
+ return mt_find(mt, index, max);
+}
+EXPORT_SYMBOL(mt_find_after);
+
#ifdef CONFIG_DEBUG_MAPLE_TREE
atomic_t maple_tree_tests_run;
EXPORT_SYMBOL_GPL(maple_tree_tests_run);