static void update_parents(struct dx_dir_info *dx_dir, int type)
{
struct dx_dirblock_info *dx_db, *dx_parent, *dx_previous;
- int b;
+ blk_t b;
for (b = 0, dx_db = dx_dir->dx_block;
b < dx_dir->numblocks;
struct check_dir_struct cd;
struct dx_dir_info *dx_dir;
struct dx_dirblock_info *dx_db;
- int b;
+ blk_t b;
ext2_ino_t i;
short depth;
problem_t code;
struct dx_dir_info *dx_dir,
char *block_buf, int failed_csum)
{
- struct ext2_dx_root_info *root;
- struct ext2_dx_entry *ent;
+ struct ext2_dx_root_info *root;
+ struct ext2_dx_entry *ent;
struct ext2_dx_countlimit *limit;
struct dx_dirblock_info *dx_db;
int i, expect_limit, count;
#endif
blk = ext2fs_le32_to_cpu(ent[i].block) & EXT4_DX_BLOCK_MASK;
/* Check to make sure the block is valid */
- if (blk >= (blk_t) dx_dir->numblocks) {
+ if (blk >= dx_dir->numblocks) {
cd->pctx.blk = blk;
if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
&cd->pctx))
errcode_t err;
e2fsck_t ctx;
struct hash_entry *harray;
- int max_array, num_array;
- unsigned int dir_size;
+ blk_t max_array, num_array;
+ ext2_off64_t dir_size;
int compress;
ext2_ino_t parent;
ext2_ino_t dir;
};
struct out_dir {
- int num;
- int max;
+ blk_t num;
+ blk_t max;
char *buf;
ext2_dirhash_t *hashes;
};
continue;
}
if (fd->num_array >= fd->max_array) {
- new_array = realloc(fd->harray,
- sizeof(struct hash_entry) * (fd->max_array+500));
- if (!new_array) {
- fd->err = ENOMEM;
+ errcode_t retval;
+
+ retval = ext2fs_resize_array(sizeof(struct hash_entry),
+ fd->max_array,
+ fd->max_array + 500,
+ &fd->harray);
+ if (retval) {
+ fd->err = retval;
return BLOCK_ABORT;
}
- fd->harray = new_array;
fd->max_array += 500;
}
ent = fd->harray + fd->num_array++;
}
static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
- int blocks)
+ blk_t blocks)
{
- void *new_mem;
+ errcode_t retval;
if (outdir->max) {
- new_mem = realloc(outdir->buf, blocks * fs->blocksize);
- if (!new_mem)
- return ENOMEM;
- outdir->buf = new_mem;
- new_mem = realloc(outdir->hashes,
- blocks * sizeof(ext2_dirhash_t));
- if (!new_mem)
- return ENOMEM;
- outdir->hashes = new_mem;
+ retval = ext2fs_resize_array(fs->blocksize, outdir->max, blocks,
+ &outdir->buf);
+ if (retval)
+ return retval;
+ retval = ext2fs_resize_array(sizeof(ext2_dirhash_t),
+ outdir->max, blocks,
+ &outdir->hashes);
+ if (retval)
+ return retval;
} else {
- outdir->buf = malloc(blocks * fs->blocksize);
- if (!outdir->buf)
- return ENOMEM;
- outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
- if (!outdir->hashes)
- return ENOMEM;
+ retval = ext2fs_get_array(fs->blocksize, blocks, &outdir->buf);
+ if (retval)
+ return retval;
+ retval = ext2fs_get_array(sizeof(ext2_dirhash_t), blocks,
+ &outdir->hashes);
+ if (retval)
+ return retval;
outdir->num = 0;
}
outdir->max = blocks;
if (retval)
return retval;
}
- *ret = outdir->buf + (outdir->num++ * fs->blocksize);
+ *ret = outdir->buf + (size_t)outdir->num++ * fs->blocksize;
memset(*ret, 0, fs->blocksize);
return 0;
}
struct fill_dir_struct *fd)
{
struct problem_context pctx;
- struct hash_entry *ent, *prev;
- int i, j;
+ struct hash_entry *ent, *prev;
+ blk_t i, j;
int fixed = 0;
char new_name[256];
unsigned int new_len;
(inode.i_flags & EXT4_INLINE_DATA_FL))
return 0;
- retval = ENOMEM;
- dir_buf = malloc(inode.i_size);
- if (!dir_buf)
+ retval = ext2fs_get_mem(inode.i_size, &dir_buf);
+ if (retval)
goto errout;
fd.max_array = inode.i_size / 32;
- fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
- if (!fd.harray)
+ retval = ext2fs_get_array(sizeof(struct hash_entry),
+ fd.max_array, &fd.harray);
+ if (retval)
goto errout;
fd.ino = ino;
else
retval = e2fsck_check_rebuild_extents(ctx, ino, &inode, pctx);
errout:
- free(dir_buf);
- free(fd.harray);
+ ext2fs_free_mem(&dir_buf);
+ ext2fs_free_mem(&fd.harray);
free_out_dir(&outdir);
return retval;
extern errcode_t ext2fs_free_mem(void *ptr);
extern errcode_t ext2fs_resize_mem(unsigned long old_size,
unsigned long size, void *ptr);
+extern errcode_t ext2fs_resize_array(unsigned long old_count, unsigned long count,
+ unsigned long size, void *ptr);
extern void ext2fs_mark_super_dirty(ext2_filsys fs);
extern void ext2fs_mark_changed(ext2_filsys fs);
extern int ext2fs_test_changed(ext2_filsys fs);
return 0;
}
-_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
+_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size,
+ void *ptr)
{
if (count && (~0UL)/count < size)
return EXT2_ET_NO_MEMORY;
_INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count,
unsigned long size, void *ptr)
{
- void *pp;
-
if (count && (~0UL)/count < size)
return EXT2_ET_NO_MEMORY;
- pp = calloc(count, size);
- if (!pp)
- return EXT2_ET_NO_MEMORY;
- memcpy(ptr, &pp, sizeof(pp));
- return 0;
+
+ return ext2fs_get_memzero((size_t)count * size, ptr);
}
/*
memcpy(ptr, &p, sizeof(p));
return 0;
}
+
+/*
+ * Resize array. The 'ptr' arg must point to a pointer.
+ */
+_INLINE_ errcode_t ext2fs_resize_array(unsigned long size,
+ unsigned long old_count,
+ unsigned long count, void *ptr)
+{
+ unsigned long old_size;
+ errcode_t retval;
+
+ if (count && (~0UL)/count < size)
+ return EXT2_ET_NO_MEMORY;
+
+ size *= count;
+ old_size = size * old_count;
+ retval = ext2fs_resize_mem(old_size, size, ptr);
+ if (retval)
+ return retval;
+
+ if (size > old_size) {
+ void *p;
+
+ memcpy(&p, ptr, sizeof(p));
+ memset((char *)p + old_size, 0, size - old_size);
+ memcpy(ptr, &p, sizeof(p));
+ }
+
+ return 0;
+}
#endif /* Custom memory routines */
/*