^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2011 STRATO AG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * written by Arne Jansen <sensille@gmx.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #ifndef BTRFS_ULIST_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define BTRFS_ULIST_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * ulist is a generic data structure to hold a collection of unique u64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * values. The only operations it supports is adding to the list and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * enumerating it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * It is possible to store an auxiliary value along with the key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct ulist_iterator {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct list_head *cur_list; /* hint to start search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * element of the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct ulist_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u64 val; /* value to store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u64 aux; /* auxiliary value saved along with the val */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct list_head list; /* used to link node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct rb_node rb_node; /* used to speed up search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct ulist {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * number of elements stored in list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned long nnodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct list_head nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct rb_root root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void ulist_init(struct ulist *ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void ulist_release(struct ulist *ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void ulist_reinit(struct ulist *ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct ulist *ulist_alloc(gfp_t gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void ulist_free(struct ulist *ulist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u64 *old_aux, gfp_t gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int ulist_del(struct ulist *ulist, u64 val, u64 aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* just like ulist_add_merge() but take a pointer for the aux data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static inline int ulist_add_merge_ptr(struct ulist *ulist, u64 val, void *aux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void **old_aux, gfp_t gfp_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #if BITS_PER_LONG == 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u64 old64 = (uintptr_t)*old_aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int ret = ulist_add_merge(ulist, val, (uintptr_t)aux, &old64, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *old_aux = (void *)((uintptr_t)old64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return ulist_add_merge(ulist, val, (u64)aux, (u64 *)old_aux, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct ulist_node *ulist_next(struct ulist *ulist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct ulist_iterator *uiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define ULIST_ITER_INIT(uiter) ((uiter)->cur_list = NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #endif