Whamcloud - gitweb
AOSP: Move system_shared_libs into target.bionic clause
[tools/e2fsprogs.git] / e2fsck / region.c
index e50c8a4..698f7bd 100644 (file)
@@ -9,6 +9,7 @@
  * %End-Header%
  */
 
+#include "config.h"
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -29,18 +30,21 @@ struct region_struct {
        region_addr_t   min;
        region_addr_t   max;
        struct region_el *allocated;
+       struct region_el *last;
 };
 
 region_t region_create(region_addr_t min, region_addr_t max)
 {
        region_t        region;
+       errcode_t       retval;
 
-       region = malloc(sizeof(struct region_struct));
-       if (!region)
+       retval = ext2fs_get_memzero(sizeof(struct region_struct), &region);
+       if (retval)
                return NULL;
-       memset(region, 0, sizeof(struct region_struct));
+
        region->min = min;
        region->max = max;
+       region->last = NULL;
        return region;
 }
 
@@ -50,16 +54,17 @@ void region_free(region_t region)
 
        for (r = region->allocated; r; r = next) {
                next = r->next;
-               free(r);
+               ext2fs_free_mem(&r);
        }
        memset(region, 0, sizeof(struct region_struct));
-       free(region);
+       ext2fs_free_mem(&region);
 }
 
 int region_allocate(region_t region, region_addr_t start, int n)
 {
        struct region_el        *r, *new_region, *prev, *next;
        region_addr_t end;
+       errcode_t retval;
 
        end = start+n;
        if ((start < region->min) || (end > region->max))
@@ -67,9 +72,21 @@ int region_allocate(region_t region, region_addr_t start, int n)
        if (n == 0)
                return 1;
 
+       if (region->last && region->last->end == start &&
+           !region->last->next) {
+               region->last->end = end;
+               return 0;
+       }
+       if (region->last && start > region->last->end &&
+           !region->last->next) {
+               r = NULL;
+               prev = region->last;
+               goto append_to_list;
+       }
+
        /*
         * Search through the linked list.  If we find that it
-        * conflicts witih something that's already allocated, return
+        * conflicts with something that's already allocated, return
         * 1; if we can find an existing region which we can grow, do
         * so.  Otherwise, stop when we find the appropriate place
         * insert a new region element into the linked list.
@@ -90,7 +107,9 @@ int region_allocate(region_t region, region_addr_t start, int n)
                                if (end == next->start) {
                                        r->end = next->end;
                                        r->next = next->next;
-                                       free(next);
+                                       ext2fs_free_mem(&next);
+                                       if (!r->next)
+                                               region->last = r;
                                        return 0;
                                }
                        }
@@ -103,12 +122,15 @@ int region_allocate(region_t region, region_addr_t start, int n)
        /*
         * Insert a new region element structure into the linked list
         */
-       new_region = malloc(sizeof(struct region_el));
-       if (!new_region)
+append_to_list:
+       retval = ext2fs_get_mem(sizeof(struct region_el), &new_region);
+       if (retval)
                return -1;
        new_region->start = start;
        new_region->end = start + n;
        new_region->next = r;
+       if (!new_region->next)
+               region->last = new_region;
        if (prev)
                prev->next = new_region;
        else
@@ -158,10 +180,13 @@ void region_print(region_t region, FILE *f)
        struct region_el        *r;
        int     i = 0;
 
-       fprintf(f, "Printing region (min=%d. max=%d)\n\t", region->min,
-               region->max);
+       fprintf(f, "Printing region (min=%llu. max=%llu)\n\t",
+               (unsigned long long) region->min,
+               (unsigned long long) region->max);
        for (r = region->allocated; r; r = r->next) {
-               fprintf(f, "(%d, %d)  ", r->start, r->end);
+               fprintf(f, "(%llu, %llu)  ",
+                       (unsigned long long) r->start,
+                       (unsigned long long) r->end);
                if (++i >= 8)
                        fprintf(f, "\n\t");
        }
@@ -170,9 +195,9 @@ void region_print(region_t region, FILE *f)
 
 int main(int argc, char **argv)
 {
-       region_t        r;
+       region_t        r = NULL;
        int             pc = 0, ret;
-       region_addr_t   start, end, len;
+       region_addr_t   start, end;
 
 
        while (1) {
@@ -182,8 +207,9 @@ int main(int argc, char **argv)
                case BCODE_CREATE:
                        start = bcode_program[pc++];
                        end = bcode_program[pc++];
-                       printf("Creating region with args(%d, %d)\n",
-                              start, end);
+                       printf("Creating region with args(%llu, %llu)\n",
+                              (unsigned long long) start,
+                              (unsigned long long) end);
                        r = region_create(start, end);
                        if (!r) {
                                fprintf(stderr, "Couldn't create region.\n");
@@ -194,14 +220,17 @@ int main(int argc, char **argv)
                        start = bcode_program[pc++];
                        end = bcode_program[pc++];
                        ret = region_allocate(r, start, end);
-                       printf("Region_allocate(%d, %d) returns %d\n",
-                              start, end, ret);
+                       printf("Region_allocate(%llu, %llu) returns %d\n",
+                              (unsigned long long) start,
+                              (unsigned long long) end, ret);
                        break;
                case BCODE_PRINT:
                        region_print(r, stdout);
                        break;
                }
        }
+       if (r)
+               region_free(r);
 }
 
 #endif /* TEST_PROGRAM */