aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/backref.c18
-rw-r--r--fs/btrfs/ulist.c23
-rw-r--r--fs/btrfs/ulist.h9
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 */
204struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev) 204struct 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}
220EXPORT_SYMBOL(ulist_next); 213EXPORT_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
27struct 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);
63void ulist_free(struct ulist *ulist); 67void ulist_free(struct ulist *ulist);
64int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, 68int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
65 unsigned long gfp_mask); 69 unsigned long gfp_mask);
66struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev); 70struct 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