diff options
author | Theodore Ts'o <tytso@mit.edu> | 2010-06-13 10:00:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-06-13 10:00:00 -0400 |
commit | ab13b5a9795a8c20f1d6da8fe1da340f545ec0e0 (patch) | |
tree | c5200060143a652d042aef593d9081bf2861e0d1 | |
parent | da3fc25bce5880c5d036d97727299ab09b415219 (diff) | |
download | e2fsprogs-ab13b5a9795a8c20f1d6da8fe1da340f545ec0e0.tar.gz |
libext2fs: Create 64-bit dblist functions
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | lib/ext2fs/dblist.c | 206 | ||||
-rw-r--r-- | lib/ext2fs/dblist_dir.c | 6 | ||||
-rw-r--r-- | lib/ext2fs/dir_iterate.c | 11 | ||||
-rw-r--r-- | lib/ext2fs/ext2fs.h | 21 | ||||
-rw-r--r-- | lib/ext2fs/ext2fsP.h | 10 |
5 files changed, 203 insertions, 51 deletions
diff --git a/lib/ext2fs/dblist.c b/lib/ext2fs/dblist.c index 76c1ab68..8ee61b4c 100644 --- a/lib/ext2fs/dblist.c +++ b/lib/ext2fs/dblist.c @@ -20,6 +20,8 @@ #include "ext2fsP.h" static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b); +static EXT2_QSORT_TYPE dir_block_cmp2(const void *a, const void *b); +static EXT2_QSORT_TYPE (*sortfunc32)(const void *a, const void *b); /* * Returns the number of directories in the filesystem as reported by @@ -53,12 +55,14 @@ errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs) * helper function for making a new directory block list (for * initialize and copy). */ -static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count, - struct ext2_db_entry *list, +static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, + ext2_ino_t count, + struct ext2_db_entry2 *list, ext2_dblist *ret_dblist) { ext2_dblist dblist; errcode_t retval; + ext2_ino_t num_dirs; size_t len; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -77,14 +81,14 @@ static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count, if (size) dblist->size = size; else { - retval = ext2fs_get_num_dirs(fs, &dblist->size); + retval = ext2fs_get_num_dirs(fs, &num_dirs); if (retval) goto cleanup; - dblist->size = (dblist->size * 2) + 12; + dblist->size = (num_dirs * 2) + 12; } - len = (size_t) sizeof(struct ext2_db_entry) * dblist->size; + len = (size_t) sizeof(struct ext2_db_entry2) * dblist->size; dblist->count = count; - retval = ext2fs_get_array(dblist->size, sizeof(struct ext2_db_entry), + retval = ext2fs_get_array(dblist->size, sizeof(struct ext2_db_entry2), &dblist->list); if (retval) goto cleanup; @@ -152,27 +156,27 @@ errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest) /* * Add a directory block to the directory block list */ -errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, - int blockcnt) +errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino, + blk64_t blk, e2_blkcnt_t blockcnt) { - struct ext2_db_entry *new_entry; + struct ext2_db_entry2 *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); + old_size = dblist->size * sizeof(struct ext2_db_entry2); dblist->size += dblist->size > 200 ? dblist->size / 2 : 100; retval = ext2fs_resize_mem(old_size, (size_t) dblist->size * - sizeof(struct ext2_db_entry), + sizeof(struct ext2_db_entry2), &dblist->list); if (retval) { dblist->size -= 100; return retval; } } - new_entry = dblist->list + ( (int) dblist->count++); + new_entry = dblist->list + ( dblist->count++); new_entry->blk = blk; new_entry->ino = ino; new_entry->blockcnt = blockcnt; @@ -185,8 +189,8 @@ errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, /* * Change the directory block to the directory block list */ -errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, - int blockcnt) +errcode_t ext2fs_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino, + blk64_t blk, e2_blkcnt_t blockcnt) { dgrp_t i; @@ -203,47 +207,47 @@ errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, return EXT2_ET_DB_NOT_FOUND; } -void ext2fs_dblist_sort(ext2_dblist dblist, - EXT2_QSORT_TYPE (*sortfunc)(const void *, - const void *)) +void ext2fs_dblist_sort2(ext2_dblist dblist, + EXT2_QSORT_TYPE (*sortfunc)(const void *, + const void *)) { if (!sortfunc) - sortfunc = dir_block_cmp; + sortfunc = dir_block_cmp2; qsort(dblist->list, (size_t) dblist->count, - sizeof(struct ext2_db_entry), sortfunc); + sizeof(struct ext2_db_entry2), sortfunc); dblist->sorted = 1; } /* * This function iterates over the directory block list */ -errcode_t ext2fs_dblist_iterate(ext2_dblist dblist, - int (*func)(ext2_filsys fs, - struct ext2_db_entry *db_info, - void *priv_data), - void *priv_data) +errcode_t ext2fs_dblist_iterate2(ext2_dblist dblist, + int (*func)(ext2_filsys fs, + struct ext2_db_entry2 *db_info, + void *priv_data), + void *priv_data) { - ext2_ino_t i; + unsigned long long i; int ret; EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); if (!dblist->sorted) - ext2fs_dblist_sort(dblist, 0); + ext2fs_dblist_sort2(dblist, 0); for (i=0; i < dblist->count; i++) { - ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data); + ret = (*func)(dblist->fs, &dblist->list[i], priv_data); if (ret & DBLIST_ABORT) return 0; } return 0; } -static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b) +static EXT2_QSORT_TYPE dir_block_cmp2(const void *a, const void *b) { - const struct ext2_db_entry *db_a = - (const struct ext2_db_entry *) a; - const struct ext2_db_entry *db_b = - (const struct ext2_db_entry *) b; + const struct ext2_db_entry2 *db_a = + (const struct ext2_db_entry2 *) a; + const struct ext2_db_entry2 *db_b = + (const struct ext2_db_entry2 *) b; if (db_a->blk != db_b->blk) return (int) (db_a->blk - db_b->blk); @@ -251,16 +255,16 @@ static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b) if (db_a->ino != db_b->ino) return (int) (db_a->ino - db_b->ino); - return (int) (db_a->blockcnt - db_b->blockcnt); + return (db_a->blockcnt - db_b->blockcnt); } -int ext2fs_dblist_count(ext2_dblist dblist) +blk64_t ext2fs_dblist_count2(ext2_dblist dblist) { - return (int) dblist->count; + return dblist->count; } -errcode_t ext2fs_dblist_get_last(ext2_dblist dblist, - struct ext2_db_entry **entry) +errcode_t ext2fs_dblist_get_last2(ext2_dblist dblist, + struct ext2_db_entry2 **entry) { EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); @@ -268,7 +272,7 @@ errcode_t ext2fs_dblist_get_last(ext2_dblist dblist, return EXT2_ET_DBLIST_EMPTY; if (entry) - *entry = dblist->list + ( (int) dblist->count-1); + *entry = dblist->list + ( dblist->count-1); return 0; } @@ -282,3 +286,129 @@ errcode_t ext2fs_dblist_drop_last(ext2_dblist dblist) dblist->count--; return 0; } + +/* + * Legacy 32-bit versions + */ + +/* + * Add a directory block to the directory block list + */ +errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, + int blockcnt) +{ + return ext2fs_add_dir_block2(dblist, ino, blk, blockcnt); +} + +/* + * Change the directory block to the directory block list + */ +errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, + int blockcnt) +{ + return ext2fs_set_dir_block2(dblist, ino, blk, blockcnt); +} + +void ext2fs_dblist_sort(ext2_dblist dblist, + EXT2_QSORT_TYPE (*sortfunc)(const void *, + const void *)) +{ + if (sortfunc) { + sortfunc32 = sortfunc; + sortfunc = dir_block_cmp; + } else + sortfunc = dir_block_cmp2; + qsort(dblist->list, (size_t) dblist->count, + sizeof(struct ext2_db_entry2), sortfunc); + dblist->sorted = 1; +} + +/* + * This function iterates over the directory block list + */ +struct iterate_passthrough { + int (*func)(ext2_filsys fs, + struct ext2_db_entry *db_info, + void *priv_data); + void *priv_data; +}; + +static int passthrough_func(ext2_filsys fs, + struct ext2_db_entry2 *db_info, + void *priv_data) +{ + struct iterate_passthrough *p = priv_data; + struct ext2_db_entry db; + int ret; + + db.ino = db_info->ino; + db.blk = (blk_t) db_info->blk; + db.blockcnt = (int) db_info->blockcnt; + ret = (p->func)(fs, &db, p->priv_data); + db_info->ino = db.ino; + db_info->blk = db.blk; + db_info->blockcnt = db.blockcnt; + return ret; +} + +errcode_t ext2fs_dblist_iterate(ext2_dblist dblist, + int (*func)(ext2_filsys fs, + struct ext2_db_entry *db_info, + void *priv_data), + void *priv_data) +{ + struct iterate_passthrough pass; + + EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); + pass.func = func; + pass.priv_data = priv_data; + + return ext2fs_dblist_iterate2(dblist, passthrough_func, &pass); +} + +static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b) +{ + const struct ext2_db_entry2 *db_a = + (const struct ext2_db_entry2 *) a; + const struct ext2_db_entry2 *db_b = + (const struct ext2_db_entry2 *) b; + + struct ext2_db_entry a32, b32; + + a32.ino = db_a->ino; a32.blk = db_a->blk; + a32.blockcnt = db_a->blockcnt; + + b32.ino = db_b->ino; b32.blk = db_b->blk; + b32.blockcnt = db_b->blockcnt; + + return sortfunc32(&a32, &b32); +} + +int ext2fs_dblist_count(ext2_dblist dblist) +{ + return dblist->count; +} + +errcode_t ext2fs_dblist_get_last(ext2_dblist dblist, + struct ext2_db_entry **entry) +{ + EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST); + static struct ext2_db_entry ret_entry; + struct ext2_db_entry2 *last; + + if (dblist->count == 0) + return EXT2_ET_DBLIST_EMPTY; + + if (!entry) + return 0; + + last = dblist->list + dblist->count -1; + + ret_entry.ino = last->ino; + ret_entry.blk = last->blk; + ret_entry.blockcnt = last->blockcnt; + *entry = &ret_entry; + + return 0; +} + diff --git a/lib/ext2fs/dblist_dir.c b/lib/ext2fs/dblist_dir.c index 8c38d315..07ed8afa 100644 --- a/lib/ext2fs/dblist_dir.c +++ b/lib/ext2fs/dblist_dir.c @@ -19,7 +19,7 @@ #include "ext2_fs.h" #include "ext2fsP.h" -static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info, +static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry2 *db_info, void *priv_data); errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist, @@ -52,7 +52,7 @@ errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist, ctx.priv_data = priv_data; ctx.errcode = 0; - retval = ext2fs_dblist_iterate(dblist, db_dir_proc, &ctx); + retval = ext2fs_dblist_iterate2(dblist, db_dir_proc, &ctx); if (!block_buf) ext2fs_free_mem(&ctx.buf); @@ -61,7 +61,7 @@ errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist, return ctx.errcode; } -static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info, +static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry2 *db_info, void *priv_data) { struct dir_context *ctx; diff --git a/lib/ext2fs/dir_iterate.c b/lib/ext2fs/dir_iterate.c index 3b9c57c4..afe0f1a2 100644 --- a/lib/ext2fs/dir_iterate.c +++ b/lib/ext2fs/dir_iterate.c @@ -120,7 +120,7 @@ errcode_t ext2fs_dir_iterate2(ext2_filsys fs, ctx.func = func; ctx.priv_data = priv_data; ctx.errcode = 0; - retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_READ_ONLY, 0, + retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY, 0, ext2fs_process_dir_block, &ctx); if (!block_buf) ext2fs_free_mem(&ctx.buf); @@ -174,9 +174,9 @@ extern errcode_t ext2fs_dir_iterate(ext2_filsys fs, * ext2fs_dir_iterate() and ext2fs_dblist_dir_iterate() */ int ext2fs_process_dir_block(ext2_filsys fs, - blk_t *blocknr, + blk64_t *blocknr, e2_blkcnt_t blockcnt, - blk_t ref_block EXT2FS_ATTR((unused)), + blk64_t ref_block EXT2FS_ATTR((unused)), int ref_offset EXT2FS_ATTR((unused)), void *priv_data) { @@ -195,7 +195,7 @@ int ext2fs_process_dir_block(ext2_filsys fs, entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE; - ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf); + ctx->errcode = ext2fs_read_dir_block3(fs, *blocknr, ctx->buf, 0); if (ctx->errcode) return BLOCK_ABORT; @@ -256,7 +256,8 @@ next: } if (changed) { - ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf); + ctx->errcode = ext2fs_write_dir_block3(fs, *blocknr, ctx->buf, + 0); if (ctx->errcode) return BLOCK_ABORT; } diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index b788304d..d1c2110a 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -125,6 +125,13 @@ typedef struct ext2_struct_u32_iterate *badblocks_iterate; /* * ext2_dblist structure and abstractions (see dblist.c) */ +struct ext2_db_entry2 { + ext2_ino_t ino; + blk64_t blk; + e2_blkcnt_t blockcnt; +}; + +/* Ye Olde 32-bit version */ struct ext2_db_entry { ext2_ino_t ino; blk_t blk; @@ -854,20 +861,34 @@ extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs); extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist); extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, int blockcnt); +extern errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino, + blk64_t blk, e2_blkcnt_t blockcnt); extern void ext2fs_dblist_sort(ext2_dblist dblist, EXT2_QSORT_TYPE (*sortfunc)(const void *, const void *)); +extern void ext2fs_dblist_sort2(ext2_dblist dblist, + EXT2_QSORT_TYPE (*sortfunc)(const void *, + const void *)); extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist, int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info, void *priv_data), void *priv_data); +extern errcode_t ext2fs_dblist_iterate2(ext2_dblist dblist, + int (*func)(ext2_filsys fs, struct ext2_db_entry2 *db_info, + void *priv_data), + void *priv_data); extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk, int blockcnt); +extern errcode_t ext2fs_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino, + blk64_t blk, e2_blkcnt_t blockcnt); extern errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest); extern int ext2fs_dblist_count(ext2_dblist dblist); +extern blk64_t ext2fs_dblist_count2(ext2_dblist dblist); extern errcode_t ext2fs_dblist_get_last(ext2_dblist dblist, struct ext2_db_entry **entry); +extern errcode_t ext2fs_dblist_get_last2(ext2_dblist dblist, + struct ext2_db_entry2 **entry); extern errcode_t ext2fs_dblist_drop_last(ext2_dblist dblist); /* dblist_dir.c */ diff --git a/lib/ext2fs/ext2fsP.h b/lib/ext2fs/ext2fsP.h index 064a8d1d..ab9ee766 100644 --- a/lib/ext2fs/ext2fsP.h +++ b/lib/ext2fs/ext2fsP.h @@ -35,10 +35,10 @@ struct ext2_struct_u32_iterate { struct ext2_struct_dblist { int magic; ext2_filsys fs; - ext2_ino_t size; - ext2_ino_t count; + unsigned long long size; + unsigned long long count; int sorted; - struct ext2_db_entry * list; + struct ext2_db_entry2 * list; }; /* @@ -79,9 +79,9 @@ struct ext2_inode_cache_ent { /* Function prototypes */ extern int ext2fs_process_dir_block(ext2_filsys fs, - blk_t *blocknr, + blk64_t *blocknr, e2_blkcnt_t blockcnt, - blk_t ref_block, + blk64_t ref_block, int ref_offset, void *priv_data); |