diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/backref.c | 18 | ||||
-rw-r--r-- | fs/btrfs/ulist.c | 23 | ||||
-rw-r--r-- | fs/btrfs/ulist.h | 9 |
3 files changed, 29 insertions, 21 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index bcec06750232..b41d94a6471b 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -201,6 +201,7 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, | |||
201 | struct __prelim_ref *new_ref; | 201 | struct __prelim_ref *new_ref; |
202 | struct ulist *parents; | 202 | struct ulist *parents; |
203 | struct ulist_node *node; | 203 | struct ulist_node *node; |
204 | struct ulist_iterator uiter; | ||
204 | 205 | ||
205 | parents = ulist_alloc(GFP_NOFS); | 206 | parents = ulist_alloc(GFP_NOFS); |
206 | if (!parents) | 207 | if (!parents) |
@@ -225,11 +226,12 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, | |||
225 | } | 226 | } |
226 | 227 | ||
227 | /* we put the first parent into the ref at hand */ | 228 | /* we put the first parent into the ref at hand */ |
228 | node = ulist_next(parents, NULL); | 229 | ULIST_ITER_INIT(&uiter); |
230 | node = ulist_next(parents, &uiter); | ||
229 | ref->parent = node ? node->val : 0; | 231 | ref->parent = node ? node->val : 0; |
230 | 232 | ||
231 | /* additional parents require new refs being added here */ | 233 | /* additional parents require new refs being added here */ |
232 | while ((node = ulist_next(parents, node))) { | 234 | while ((node = ulist_next(parents, &uiter))) { |
233 | new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS); | 235 | new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS); |
234 | if (!new_ref) { | 236 | if (!new_ref) { |
235 | ret = -ENOMEM; | 237 | ret = -ENOMEM; |
@@ -788,6 +790,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | |||
788 | { | 790 | { |
789 | struct ulist *tmp; | 791 | struct ulist *tmp; |
790 | struct ulist_node *node = NULL; | 792 | struct ulist_node *node = NULL; |
793 | struct ulist_iterator uiter; | ||
791 | int ret; | 794 | int ret; |
792 | 795 | ||
793 | tmp = ulist_alloc(GFP_NOFS); | 796 | tmp = ulist_alloc(GFP_NOFS); |
@@ -799,6 +802,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | |||
799 | return -ENOMEM; | 802 | return -ENOMEM; |
800 | } | 803 | } |
801 | 804 | ||
805 | ULIST_ITER_INIT(&uiter); | ||
802 | while (1) { | 806 | while (1) { |
803 | ret = find_parent_nodes(trans, fs_info, bytenr, seq, | 807 | ret = find_parent_nodes(trans, fs_info, bytenr, seq, |
804 | tmp, *roots); | 808 | tmp, *roots); |
@@ -807,7 +811,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | |||
807 | ulist_free(*roots); | 811 | ulist_free(*roots); |
808 | return ret; | 812 | return ret; |
809 | } | 813 | } |
810 | node = ulist_next(tmp, node); | 814 | node = ulist_next(tmp, &uiter); |
811 | if (!node) | 815 | if (!node) |
812 | break; | 816 | break; |
813 | bytenr = node->val; | 817 | bytenr = node->val; |
@@ -1176,6 +1180,8 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, | |||
1176 | struct ulist_node *ref_node = NULL; | 1180 | struct ulist_node *ref_node = NULL; |
1177 | struct ulist_node *root_node = NULL; | 1181 | struct ulist_node *root_node = NULL; |
1178 | struct seq_list seq_elem; | 1182 | struct seq_list seq_elem; |
1183 | struct ulist_iterator ref_uiter; | ||
1184 | struct ulist_iterator root_uiter; | ||
1179 | struct btrfs_delayed_ref_root *delayed_refs = NULL; | 1185 | struct btrfs_delayed_ref_root *delayed_refs = NULL; |
1180 | 1186 | ||
1181 | pr_debug("resolving all inodes for extent %llu\n", | 1187 | pr_debug("resolving all inodes for extent %llu\n", |
@@ -1201,12 +1207,14 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, | |||
1201 | if (ret) | 1207 | if (ret) |
1202 | goto out; | 1208 | goto out; |
1203 | 1209 | ||
1204 | while (!ret && (ref_node = ulist_next(refs, ref_node))) { | 1210 | ULIST_ITER_INIT(&ref_uiter); |
1211 | while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) { | ||
1205 | ret = btrfs_find_all_roots(trans, fs_info, ref_node->val, -1, | 1212 | ret = btrfs_find_all_roots(trans, fs_info, ref_node->val, -1, |
1206 | seq_elem.seq, &roots); | 1213 | seq_elem.seq, &roots); |
1207 | if (ret) | 1214 | if (ret) |
1208 | break; | 1215 | break; |
1209 | while (!ret && (root_node = ulist_next(roots, root_node))) { | 1216 | ULIST_ITER_INIT(&root_uiter); |
1217 | while (!ret && (root_node = ulist_next(roots, &root_uiter))) { | ||
1210 | pr_debug("root %llu references leaf %llu\n", | 1218 | pr_debug("root %llu references leaf %llu\n", |
1211 | root_node->val, ref_node->val); | 1219 | root_node->val, ref_node->val); |
1212 | ret = iterate_leaf_refs(fs_info, ref_node->val, | 1220 | ret = iterate_leaf_refs(fs_info, ref_node->val, |
diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c index 12f5147bd2b1..17e68bdc307c 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; |
@@ -188,33 +188,26 @@ EXPORT_SYMBOL(ulist_add); | |||
188 | /** | 188 | /** |
189 | * ulist_next - iterate ulist | 189 | * ulist_next - iterate ulist |
190 | * @ulist: ulist to iterate | 190 | * @ulist: ulist to iterate |
191 | * @prev: previously returned element or %NULL to start iteration | 191 | * @uiter: iterator variable, initialized with ULIST_ITER_INIT(&iterator) |
192 | * | 192 | * |
193 | * Note: locking must be provided by the caller. In case of rwlocks only read | 193 | * Note: locking must be provided by the caller. In case of rwlocks only read |
194 | * locking is needed | 194 | * locking is needed |
195 | * | 195 | * |
196 | * This function is used to iterate an ulist. The iteration is started with | 196 | * This function is used to iterate an ulist. |
197 | * @prev = %NULL. It returns the next element from the ulist or %NULL when the | 197 | * 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 | 198 | * 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 | 199 | * the elements are returned. They might neither be returned in order of |
200 | * addition nor in ascending order. | 200 | * addition nor in ascending order. |
201 | * It is allowed to call ulist_add during an enumeration. Newly added items | 201 | * It is allowed to call ulist_add during an enumeration. Newly added items |
202 | * are guaranteed to show up in the running enumeration. | 202 | * are guaranteed to show up in the running enumeration. |
203 | */ | 203 | */ |
204 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev) | 204 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_iterator *uiter) |
205 | { | 205 | { |
206 | int next; | ||
207 | |||
208 | if (ulist->nnodes == 0) | 206 | if (ulist->nnodes == 0) |
209 | return NULL; | 207 | return NULL; |
210 | 208 | 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; | 209 | return NULL; |
217 | 210 | ||
218 | return &ulist->nodes[next]; | 211 | return &ulist->nodes[uiter->i++]; |
219 | } | 212 | } |
220 | EXPORT_SYMBOL(ulist_next); | 213 | EXPORT_SYMBOL(ulist_next); |
diff --git a/fs/btrfs/ulist.h b/fs/btrfs/ulist.h index 2e25dec58ec0..62d2574f775a 100644 --- a/fs/btrfs/ulist.h +++ b/fs/btrfs/ulist.h | |||
@@ -24,6 +24,10 @@ | |||
24 | */ | 24 | */ |
25 | #define ULIST_SIZE 16 | 25 | #define ULIST_SIZE 16 |
26 | 26 | ||
27 | struct ulist_iterator { | ||
28 | int i; | ||
29 | }; | ||
30 | |||
27 | /* | 31 | /* |
28 | * element of the list | 32 | * element of the list |
29 | */ | 33 | */ |
@@ -63,6 +67,9 @@ struct ulist *ulist_alloc(unsigned long gfp_mask); | |||
63 | void ulist_free(struct ulist *ulist); | 67 | void ulist_free(struct ulist *ulist); |
64 | int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, | 68 | int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, |
65 | unsigned long gfp_mask); | 69 | unsigned long gfp_mask); |
66 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev); | 70 | struct ulist_node *ulist_next(struct ulist *ulist, |
71 | struct ulist_iterator *uiter); | ||
72 | |||
73 | #define ULIST_ITER_INIT(uiter) ((uiter)->i = 0) | ||
67 | 74 | ||
68 | #endif | 75 | #endif |