drbd: Iterate over all overlapping intervals in a tree
authorAndreas Gruenbacher <agruen@linbit.com>
Thu, 17 Feb 2011 17:11:24 +0000 (18:11 +0100)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Fri, 14 Oct 2011 14:47:37 +0000 (16:47 +0200)
Add a macro and helper function for doing that.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_interval.c
drivers/block/drbd/drbd_interval.h

index 14dbe2dd2d3312420a7c7c22a9ee1f5b1b3c8d84..0e53f102e68ab33574bf4f8c9304f404a809707a 100644 (file)
@@ -157,3 +157,21 @@ drbd_find_overlap(struct rb_root *root, sector_t sector, unsigned int size)
        }
        return overlap;
 }
+
+struct drbd_interval *
+drbd_next_overlap(struct drbd_interval *i, sector_t sector, unsigned int size)
+{
+       sector_t end = sector + (size >> 9);
+       struct rb_node *node;
+
+       for (;;) {
+               node = rb_next(&i->rb);
+               if (!node)
+                       return NULL;
+               i = rb_entry(node, struct drbd_interval, rb);
+               if (i->sector >= end)
+                       return NULL;
+               if (sector < i->sector + (i->size >> 9))
+                       return i;
+       }
+}
index 4010ad923948b0bafcd80b1f0c10da6017426e0b..f38fcb00c10d6c39b09c334483d80296b463e608 100644 (file)
@@ -23,10 +23,18 @@ static inline bool drbd_interval_empty(struct drbd_interval *i)
        return RB_EMPTY_NODE(&i->rb);
 }
 
-bool drbd_insert_interval(struct rb_root *, struct drbd_interval *);
-bool drbd_contains_interval(struct rb_root *, sector_t, struct drbd_interval *);
-void drbd_remove_interval(struct rb_root *, struct drbd_interval *);
-struct drbd_interval *drbd_find_overlap(struct rb_root *, sector_t,
+extern bool drbd_insert_interval(struct rb_root *, struct drbd_interval *);
+extern bool drbd_contains_interval(struct rb_root *, sector_t,
+                                  struct drbd_interval *);
+extern void drbd_remove_interval(struct rb_root *, struct drbd_interval *);
+extern struct drbd_interval *drbd_find_overlap(struct rb_root *, sector_t,
                                        unsigned int);
+extern struct drbd_interval *drbd_next_overlap(struct drbd_interval *, sector_t,
+                                       unsigned int);
+
+#define drbd_for_each_overlap(i, root, sector, size)           \
+       for (i = drbd_find_overlap(root, sector, size);         \
+            i;                                                 \
+            i = drbd_next_overlap(i, sector, size))
 
 #endif  /* __DRBD_INTERVAL_H */