#if HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <linux/ext2_fs.h>
-
+#include "ext2_fs.h"
#include "ext2fsP.h"
-static int dir_block_cmp(const void *a, const void *b);
+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b);
/*
* Returns the number of directories in the filesystem as reported by
* the group descriptors. Of course, the group descriptors could be
* wrong!
*/
-errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ino_t *ret_num_dirs)
+errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs)
{
- int i;
- ino_t num_dirs;
+ dgrp_t i;
+ ext2_ino_t num_dirs, max_dirs;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
num_dirs = 0;
- for (i = 0; i < fs->group_desc_count; i++)
- num_dirs += fs->group_desc[i].bg_used_dirs_count;
+ max_dirs = fs->super->s_inodes_per_group;
+ for (i = 0; i < fs->group_desc_count; i++) {
+ if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
+ num_dirs += max_dirs / 8;
+ else
+ num_dirs += fs->group_desc[i].bg_used_dirs_count;
+ }
+ if (num_dirs > fs->super->s_inodes_count)
+ num_dirs = fs->super->s_inodes_count;
*ret_num_dirs = num_dirs;
* helper function for making a new directory block list (for
* initialize and copy).
*/
-static errcode_t make_dblist(ext2_filsys fs, ino_t size, ino_t count,
+static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count,
struct ext2_db_entry *list,
ext2_dblist *ret_dblist)
{
(fs->dblist->magic == EXT2_ET_MAGIC_DBLIST))
return 0;
- retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist),
- (void **) &dblist);
+ retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist);
if (retval)
return retval;
memset(dblist, 0, sizeof(struct ext2_struct_dblist));
}
len = (size_t) sizeof(struct ext2_db_entry) * dblist->size;
dblist->count = count;
- retval = ext2fs_get_mem(len, (void **) &dblist->list);
+ retval = ext2fs_get_mem(len, &dblist->list);
if (retval)
goto cleanup;
memcpy(dblist->list, list, len);
else
memset(dblist->list, 0, len);
- *ret_dblist = dblist;
+ if (ret_dblist)
+ *ret_dblist = dblist;
+ else
+ fs->dblist = dblist;
return 0;
cleanup:
if (dblist)
- ext2fs_free_mem((void **) &dblist);
+ ext2fs_free_mem(&dblist);
return retval;
}
/*
* Add a directory block to the directory block list
*/
-errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ino_t ino, blk_t blk,
+errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
int blockcnt)
{
- struct ext2_db_entry *new;
+ struct ext2_db_entry *new_entry;
errcode_t retval;
+ unsigned long old_size;
EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
if (dblist->count >= dblist->size) {
+ old_size = dblist->size * sizeof(struct ext2_db_entry);
dblist->size += 100;
- retval = ext2fs_resize_mem((size_t) dblist->size *
+ retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
sizeof(struct ext2_db_entry),
- (void **) &dblist->list);
+ &dblist->list);
if (retval) {
dblist->size -= 100;
return retval;
}
}
- new = dblist->list + ( (int) dblist->count++);
- new->blk = blk;
- new->ino = ino;
- new->blockcnt = blockcnt;
+ new_entry = dblist->list + ( (int) dblist->count++);
+ new_entry->blk = blk;
+ new_entry->ino = ino;
+ new_entry->blockcnt = blockcnt;
dblist->sorted = 0;
/*
* Change the directory block to the directory block list
*/
-errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ino_t ino, blk_t blk,
+errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
int blockcnt)
{
- int i;
+ dgrp_t i;
EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
dblist->sorted = 0;
return 0;
}
- return EXT2_DB_NOT_FOUND;
+ return EXT2_ET_DB_NOT_FOUND;
+}
+
+void ext2fs_dblist_sort(ext2_dblist dblist,
+ EXT2_QSORT_TYPE (*sortfunc)(const void *,
+ const void *))
+{
+ if (!sortfunc)
+ sortfunc = dir_block_cmp;
+ qsort(dblist->list, (size_t) dblist->count,
+ sizeof(struct ext2_db_entry), sortfunc);
+ dblist->sorted = 1;
}
/*
errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
int (*func)(ext2_filsys fs,
struct ext2_db_entry *db_info,
- void *private),
- void *private)
+ void *priv_data),
+ void *priv_data)
{
- ino_t i;
- int ret;
+ ext2_ino_t i;
+ int ret;
EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
- if (!dblist->sorted) {
- qsort(dblist->list, (size_t) dblist->count,
- sizeof(struct ext2_db_entry), dir_block_cmp);
- dblist->sorted = 1;
- }
+ if (!dblist->sorted)
+ ext2fs_dblist_sort(dblist, 0);
for (i=0; i < dblist->count; i++) {
- ret = (*func)(dblist->fs, &dblist->list[(int)i], private);
+ ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data);
if (ret & DBLIST_ABORT)
return 0;
}
return 0;
}
-
-static int dir_block_cmp(const void *a, const void *b)
+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b)
{
const struct ext2_db_entry *db_a =
(const struct ext2_db_entry *) a;