]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - libfrog/bitmap.c
libfrog: convert bitmap.c to negative error codes
[thirdparty/xfsprogs-dev.git] / libfrog / bitmap.c
index be95965fcbe4b8d82240549018c273a5acbdb45f..5af5ab8dd6b3bb853d2ff3e8bdfadff4fb8a850f 100644 (file)
@@ -72,21 +72,30 @@ bitmap_alloc(
        struct bitmap           **bmapp)
 {
        struct bitmap           *bmap;
+       int                     ret;
 
        bmap = calloc(1, sizeof(struct bitmap));
        if (!bmap)
-               return errno;
+               return -errno;
        bmap->bt_tree = malloc(sizeof(struct avl64tree_desc));
        if (!bmap->bt_tree) {
-               free(bmap);
-               return errno;
+               ret = -errno;
+               goto out;
        }
 
-       pthread_mutex_init(&bmap->bt_lock, NULL);
+       ret = -pthread_mutex_init(&bmap->bt_lock, NULL);
+       if (ret)
+               goto out_tree;
+
        avl64_init_tree(bmap->bt_tree, &bitmap_ops);
        *bmapp = bmap;
 
        return 0;
+out_tree:
+       free(bmap->bt_tree);
+out:
+       free(bmap);
+       return ret;
 }
 
 /* Free a bitmap. */
@@ -140,12 +149,12 @@ __bitmap_insert(
 
        ext = bitmap_node_init(start, length);
        if (!ext)
-               return errno;
+               return -errno;
 
        node = avl64_insert(bmap->bt_tree, &ext->btn_node);
        if (node == NULL) {
                free(ext);
-               return EEXIST;
+               return -EEXIST;
        }
 
        return 0;
@@ -226,7 +235,7 @@ bitmap_set(
 
 #if 0  /* Unused, provided for completeness. */
 /* Clear a region of bits. */
-bool
+int
 bitmap_clear(
        struct bitmap           *bmap,
        uint64_t                start,
@@ -250,7 +259,7 @@ bitmap_clear(
        /* Nothing, we're done. */
        if (firstn == NULL && lastn == NULL) {
                pthread_mutex_unlock(&bmap->bt_lock);
-               return true;
+               return 0;
        }
 
        assert(firstn != NULL && lastn != NULL);
@@ -288,24 +297,26 @@ bitmap_clear(
                                        new_start;
 
                        ext = bitmap_node_init(new_start, new_length);
-                       if (!ext)
-                               return false;
+                       if (!ext) {
+                               ret = -errno;
+                               goto out;
+                       }
 
                        node = avl64_insert(bmap->bt_tree, &ext->btn_node);
                        if (node == NULL) {
-                               errno = EEXIST;
-                               return false;
+                               ret = -EEXIST;
+                               goto out;
                        }
                        break;
                }
        }
 
+out:
        pthread_mutex_unlock(&bmap->bt_lock);
-       return true;
+       return ret;
 }
 #endif
 
-#ifdef DEBUG
 /* Iterate the set regions of this bitmap. */
 int
 bitmap_iterate(
@@ -328,7 +339,43 @@ bitmap_iterate(
 
        return error;
 }
-#endif
+
+/* Iterate the set regions of part of this bitmap. */
+int
+bitmap_iterate_range(
+       struct bitmap           *bmap,
+       uint64_t                start,
+       uint64_t                length,
+       int                     (*fn)(uint64_t, uint64_t, void *),
+       void                    *arg)
+{
+       struct avl64node        *firstn;
+       struct avl64node        *lastn;
+       struct avl64node        *pos;
+       struct avl64node        *n;
+       struct avl64node        *l;
+       struct bitmap_node      *ext;
+       int                     ret = 0;
+
+       pthread_mutex_lock(&bmap->bt_lock);
+
+       avl64_findranges(bmap->bt_tree, start, start + length, &firstn,
+                       &lastn);
+
+       if (firstn == NULL && lastn == NULL)
+               goto out;
+
+       avl_for_each_range_safe(pos, n, l, firstn, lastn) {
+               ext = container_of(pos, struct bitmap_node, btn_node);
+               ret = fn(ext->btn_start, ext->btn_length, arg);
+               if (ret)
+                       break;
+       }
+
+out:
+       pthread_mutex_unlock(&bmap->bt_lock);
+       return ret;
+}
 
 /* Do any bitmap extents overlap the given one?  (locked) */
 static bool