diff options
Diffstat (limited to 'fs/btrfs/ulist.c')
| -rw-r--r-- | fs/btrfs/ulist.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c index 12f5147bd2b1..ab942f46b3dd 100644 --- a/fs/btrfs/ulist.c +++ b/fs/btrfs/ulist.c | |||
| @@ -23,9 +23,9 @@ | |||
| 23 | * | 23 | * |
| 24 | * ulist = ulist_alloc(); | 24 | * ulist = ulist_alloc(); |
| 25 | * ulist_add(ulist, root); | 25 | * ulist_add(ulist, root); |
| 26 | * elem = NULL; | 26 | * ULIST_ITER_INIT(&uiter); |
| 27 | * | 27 | * |
| 28 | * while ((elem = ulist_next(ulist, elem)) { | 28 | * while ((elem = ulist_next(ulist, &uiter)) { |
| 29 | * for (all child nodes n in elem) | 29 | * for (all child nodes n in elem) |
| 30 | * ulist_add(ulist, n); | 30 | * ulist_add(ulist, n); |
| 31 | * do something useful with the node; | 31 | * do something useful with the node; |
| @@ -95,7 +95,7 @@ EXPORT_SYMBOL(ulist_reinit); | |||
| 95 | * | 95 | * |
| 96 | * The allocated ulist will be returned in an initialized state. | 96 | * The allocated ulist will be returned in an initialized state. |
| 97 | */ | 97 | */ |
| 98 | struct ulist *ulist_alloc(unsigned long gfp_mask) | 98 | struct ulist *ulist_alloc(gfp_t gfp_mask) |
| 99 | { | 99 | { |
| 100 | struct ulist *ulist = kmalloc(sizeof(*ulist), gfp_mask); | 100 | struct ulist *ulist = kmalloc(sizeof(*ulist), gfp_mask); |
| 101 | 101 | ||
| @@ -144,13 +144,22 @@ EXPORT_SYMBOL(ulist_free); | |||
| 144 | * unaltered. | 144 | * unaltered. |
| 145 | */ | 145 | */ |
| 146 | int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, | 146 | int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, |
| 147 | unsigned long gfp_mask) | 147 | gfp_t gfp_mask) |
| 148 | { | ||
| 149 | return ulist_add_merge(ulist, val, aux, NULL, gfp_mask); | ||
| 150 | } | ||
| 151 | |||
| 152 | int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux, | ||
| 153 | unsigned long *old_aux, gfp_t gfp_mask) | ||
| 148 | { | 154 | { |
| 149 | int i; | 155 | int i; |
| 150 | 156 | ||
| 151 | for (i = 0; i < ulist->nnodes; ++i) { | 157 | for (i = 0; i < ulist->nnodes; ++i) { |
| 152 | if (ulist->nodes[i].val == val) | 158 | if (ulist->nodes[i].val == val) { |
| 159 | if (old_aux) | ||
| 160 | *old_aux = ulist->nodes[i].aux; | ||
| 153 | return 0; | 161 | return 0; |
| 162 | } | ||
| 154 | } | 163 | } |
| 155 | 164 | ||
| 156 | if (ulist->nnodes >= ulist->nodes_alloced) { | 165 | if (ulist->nnodes >= ulist->nodes_alloced) { |
| @@ -188,33 +197,26 @@ EXPORT_SYMBOL(ulist_add); | |||
| 188 | /** | 197 | /** |
| 189 | * ulist_next - iterate ulist | 198 | * ulist_next - iterate ulist |
| 190 | * @ulist: ulist to iterate | 199 | * @ulist: ulist to iterate |
| 191 | * @prev: previously returned element or %NULL to start iteration | 200 | * @uiter: iterator variable, initialized with ULIST_ITER_INIT(&iterator) |
| 192 | * | 201 | * |
| 193 | * Note: locking must be provided by the caller. In case of rwlocks only read | 202 | * Note: locking must be provided by the caller. In case of rwlocks only read |
| 194 | * locking is needed | 203 | * locking is needed |
| 195 | * | 204 | * |
| 196 | * This function is used to iterate an ulist. The iteration is started with | 205 | * This function is used to iterate an ulist. |
| 197 | * @prev = %NULL. It returns the next element from the ulist or %NULL when the | 206 | * It returns the next element from the ulist or %NULL when the |
| 198 | * end is reached. No guarantee is made with respect to the order in which | 207 | * end is reached. No guarantee is made with respect to the order in which |
| 199 | * the elements are returned. They might neither be returned in order of | 208 | * the elements are returned. They might neither be returned in order of |
| 200 | * addition nor in ascending order. | 209 | * addition nor in ascending order. |
| 201 | * It is allowed to call ulist_add during an enumeration. Newly added items | 210 | * It is allowed to call ulist_add during an enumeration. Newly added items |
| 202 | * are guaranteed to show up in the running enumeration. | 211 | * are guaranteed to show up in the running enumeration. |
| 203 | */ | 212 | */ |
| 204 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev) | 213 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_iterator *uiter) |
| 205 | { | 214 | { |
| 206 | int next; | ||
| 207 | |||
| 208 | if (ulist->nnodes == 0) | 215 | if (ulist->nnodes == 0) |
| 209 | return NULL; | 216 | return NULL; |
| 210 | 217 | if (uiter->i < 0 || uiter->i >= ulist->nnodes) | |
| 211 | if (!prev) | ||
| 212 | return &ulist->nodes[0]; | ||
| 213 | |||
| 214 | next = (prev - ulist->nodes) + 1; | ||
| 215 | if (next < 0 || next >= ulist->nnodes) | ||
| 216 | return NULL; | 218 | return NULL; |
| 217 | 219 | ||
| 218 | return &ulist->nodes[next]; | 220 | return &ulist->nodes[uiter->i++]; |
| 219 | } | 221 | } |
| 220 | EXPORT_SYMBOL(ulist_next); | 222 | EXPORT_SYMBOL(ulist_next); |
