Whamcloud - gitweb
e2fsck: Do not trash user limits when processing orphan list
[tools/e2fsprogs.git] / e2fsck / dx_dirinfo.c
index ff90e99..caca3e3 100644 (file)
@@ -5,18 +5,19 @@
  * under the terms of the GNU Public License.
  */
 
+#include "config.h"
 #include "e2fsck.h"
-#ifdef ENABLE_HTREE
 
 /*
  * This subroutine is called during pass1 to create a directory info
  * entry.  During pass1, the passed-in parent is 0; it will get filled
- * in during pass2.  
+ * in during pass2.
  */
-void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
+void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, struct ext2_inode *inode,
+                      int num_blocks)
 {
        struct dx_dir_info *dir;
-       int             i, j;
+       ext2_ino_t      i, j;
        errcode_t       retval;
        unsigned long   old_size;
 
@@ -31,14 +32,18 @@ void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
                                               * sizeof (struct dx_dir_info),
                                               "directory map");
        }
-       
+
        if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
                old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
                ctx->dx_dir_info_size += 10;
                retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
                                           sizeof(struct dx_dir_info),
-                                          (void **) &ctx->dx_dir_info);
+                                          &ctx->dx_dir_info);
                if (retval) {
+                       fprintf(stderr, "Couldn't reallocate dx_dir_info "
+                               "structure to %u entries\n",
+                               ctx->dx_dir_info_size);
+                       fatal_error(ctx, 0);
                        ctx->dx_dir_info_size -= 10;
                        return;
                }
@@ -59,19 +64,19 @@ void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
                        if (ctx->dx_dir_info[i-1].ino < ino)
                                break;
                dir = &ctx->dx_dir_info[i];
-               if (dir->ino != ino) 
+               if (dir->ino != ino)
                        for (j = ctx->dx_dir_info_count++; j > i; j--)
                                ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
        } else
                dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
-       
+
        dir->ino = ino;
        dir->numblocks = num_blocks;
        dir->hashversion = 0;
+       dir->casefolded_hash = !!(inode->i_flags & EXT4_CASEFOLD_FL);
        dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
                                       * sizeof (struct dx_dirblock_info),
                                       "dx_block info array");
-
 }
 
 /*
@@ -80,7 +85,7 @@ void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
  */
 struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
 {
-       int     low, high, mid;
+       ext2_ino_t low, high, mid;
 
        low = 0;
        high = ctx->dx_dir_info_count-1;
@@ -92,7 +97,8 @@ struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
                return &ctx->dx_dir_info[high];
 
        while (low < high) {
-               mid = (low+high)/2;
+               /* sum may overflow, but result will fit into mid again */
+               mid = (unsigned long long)(low + high) / 2;
                if (mid == low || mid == high)
                        break;
                if (ino == ctx->dx_dir_info[mid].ino)
@@ -110,18 +116,18 @@ struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
  */
 void e2fsck_free_dx_dir_info(e2fsck_t ctx)
 {
-       int     i;
        struct dx_dir_info *dir;
-       
+       ext2_ino_t i;
+
        if (ctx->dx_dir_info) {
                dir = ctx->dx_dir_info;
-               for (i=0; i < ctx->dx_dir_info_count; i++) {
+               for (i=0; i < ctx->dx_dir_info_count; i++,dir++) {
                        if (dir->dx_block) {
-                               ext2fs_free_mem((void **) &dir->dx_block);
+                               ext2fs_free_mem(&dir->dx_block);
                                dir->dx_block = 0;
                        }
                }
-               ext2fs_free_mem((void **) &ctx->dx_dir_info);
+               ext2fs_free_mem(&ctx->dx_dir_info);
                ctx->dx_dir_info = 0;
        }
        ctx->dx_dir_info_size = 0;
@@ -131,7 +137,7 @@ void e2fsck_free_dx_dir_info(e2fsck_t ctx)
 /*
  * Return the count of number of directories in the dx_dir_info structure
  */
-int e2fsck_get_num_dx_dirinfo(e2fsck_t ctx)
+ext2_ino_t e2fsck_get_num_dx_dirinfo(e2fsck_t ctx)
 {
        return ctx->dx_dir_info_count;
 }
@@ -139,12 +145,10 @@ int e2fsck_get_num_dx_dirinfo(e2fsck_t ctx)
 /*
  * A simple interator function
  */
-struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
+struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, ext2_ino_t *control)
 {
        if (*control >= ctx->dx_dir_info_count)
                return 0;
 
-       return(ctx->dx_dir_info + (*control)++);
+       return ctx->dx_dir_info + (*control)++;
 }
-
-#endif /* ENABLE_HTREE */