unsigned long index = mas->index;
void *entry;
- if (mas_is_none(mas))
+ if (mas_is_none(mas) || mas_is_paused(mas))
mas->node = MAS_START;
_mas_walk(mas, &range_min, &range_max);
unsigned long index = mas->index;
void *entry;
- if (mas_is_none(mas))
+ if (mas_is_none(mas) || mas_is_paused(mas))
mas->node = MAS_START;
if (_mas_walk(mas, range_min, range_max))
*/
static void *_mas_next(struct ma_state *mas, unsigned long limit)
{
- void *entry = NULL;
-
-
if (unlikely(mas_is_start(mas))) {
/* First run */
+ void *entry = NULL;
unsigned long range_max;
unsigned long range_start;
if (unlikely(!mas_searchable(mas)))
return NULL;
- entry = __mas_next(mas, limit);
- return entry;
+ return __mas_next(mas, limit);
}
/*
* @mas: The maple state
* @max: The maximum index to check.
*
+ * Returns the next entry after @mas->index.
* Must hold rcu_read_lock or the write lock.
* Can return the zero entry.
*
*/
void *mas_next(struct ma_state *mas, unsigned long max)
{
- if (mas_is_none(mas))
+ if (mas_is_none(mas) || mas_is_paused(mas))
mas->node = MAS_START;
- return _mas_next(mas, max);
+ if (unlikely(!mas_searchable(mas)))
+ return NULL;
+
+ if (mas_is_start(mas)) {
+ mas->index = ++mas->last;
+ return mas_find(mas, max);
+ }
+
+ return __mas_next(mas, max);
}
EXPORT_SYMBOL_GPL(mas_next);
-
+/*
+ * mt_next() - get the next value in the maple tree
+ * @mt: The maple tree
+ * @index: The start index
+ * @max: The maximum index to check
+ *
+ * Returns: The entry at @index or higher, or %NULL if nothing is found.
+ */
void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max)
{
void *entry = NULL;
* Must hold rcu_read_lock or the write lock.
* Will reset mas to MAS_START if the node is MAS_NONE. Will stop on not
* searchable nodes. If mas->node is MAS_START, it will first look up the
- * index, then get the previous entry.
+ * index and return. If there is nothing at mas->index, then the prev entry
+ * will be returned.
*
* Return: the previous value or %NULL.
*/
return NULL;
}
- if (mas_is_none(mas))
+ if (mas_is_none(mas) || mas_is_paused(mas))
mas->node = MAS_START;
if (!mas_searchable(mas))
return NULL;
-
if (mas_is_start(mas)) {
mas_start(mas);
mas_walk(mas);
}
EXPORT_SYMBOL_GPL(mas_prev);
+/*
+ * mt_prev() - get the previous value in the maple tree
+ * @mt: The maple tree
+ * @index: The start index
+ * @max: The minumum index to check
+ *
+ * Returns: The entry at @index or lower, or %NULL if nothing is found.
+ */
void *mt_prev(struct maple_tree *mt, unsigned long index, unsigned long min)
{
void *entry = NULL;
*/
void mas_pause(struct ma_state *mas)
{
- /* Overflow protection */
- if (mas->last == ULONG_MAX) {
- mas->node = MAS_NONE;
- return;
- }
-
- mas_reset(mas);
- mas->last++;
- mas->index = mas->last;
+ mas->node = MAS_PAUSE;
}
EXPORT_SYMBOL_GPL(mas_pause);
+/*
+ * mas_resume_fwd() - resume a forward search.
+ * @mas: The maple state
+ *
+ * Returns: 0 on success, -EFAULT on overflow.
+ */
+static inline int mas_resume_fwd(struct ma_state *mas) {
+ if (mas_is_paused(mas)) {
+ if (unlikely(mas->last == ULONG_MAX)) {
+ mas->node = MAS_NONE;
+ return -EFAULT;
+ }
+ mas->node = MAS_START;
+ mas->index = ++mas->last;
+ }
+ return 0;
+}
/*
* mas_find: If mas->node == MAS_START, find the first
if (mas_is_start(mas) && (mas->index <= max))
first = true;
+ else if (mas_resume_fwd(mas))
+ return NULL;
retry:
while (mas_search_cont(mas, mas->index, max, entry))