aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ulist.h
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2012-05-22 08:56:50 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2012-05-26 06:17:49 -0400
commitcd1b413c5c863a96bfdeab8e91b1fb3a52665e42 (patch)
treea433c13c530c487f2d7e209402ef72ec67e48647 /fs/btrfs/ulist.h
parentb9fab919b748c7b39c19ff236ed6c5682c266dde (diff)
Btrfs: ulist realloc bugfix
ulist_next gets the pointer to the previously returned element to find the next element from there. However, when we call ulist_add while iteration with ulist_next is in progress (ulist explicitly supports this), we can realloc the ulist internal memory, which makes the pointer to the previous element useless. Instead, we now use an iterator parameter that's independent from the internal pointers. Reported-by: Alexander Block <ablock84@googlemail.com> Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs/btrfs/ulist.h')
-rw-r--r--fs/btrfs/ulist.h9
1 files changed, 8 insertions, 1 deletions
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