struct ext2_db_entry2 *dir_blocks_info,
char *buf, struct problem_context *pctx);
static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
-static int htree_depth(struct dx_dir_info *dx_dir,
- struct dx_dirblock_info *dx_db);
+static short htree_depth(struct dx_dir_info *dx_dir,
+ struct dx_dirblock_info *dx_db);
static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
struct check_dir_struct {
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;
#endif
struct check_dir_struct cd;
struct dx_dir_info *dx_dir;
- struct dx_dirblock_info *dx_db, *dx_parent;
- int b;
- int i, depth;
+ struct dx_dirblock_info *dx_db;
+ blk_t b;
+ ext2_ino_t i;
+ short depth;
problem_t code;
int bad_dir;
int (*check_dir_func)(ext2_filsys fs,
}
#define MAX_DEPTH 32000
-static int htree_depth(struct dx_dir_info *dx_dir,
- struct dx_dirblock_info *dx_db)
+static short htree_depth(struct dx_dir_info *dx_dir,
+ struct dx_dirblock_info *dx_db)
{
- int depth = 0;
+ short depth = 0;
while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
dx_db = &dx_dir->dx_block[dx_db->parent];
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;
#ifdef DX_DEBUG
printf("Root node dump:\n");
printf("\t Reserved zero: %u\n", root->reserved_zero);
- printf("\t Hash Version: %d\n", root->hash_version);
- printf("\t Info length: %d\n", root->info_length);
- printf("\t Indirect levels: %d\n", root->indirect_levels);
- printf("\t Flags: %d\n", root->unused_flags);
+ printf("\t Hash Version: %u\n", root->hash_version);
+ printf("\t Info length: %u\n", root->info_length);
+ printf("\t Indirect levels: %u\n", root->indirect_levels);
+ printf("\t Flags: %x\n", root->unused_flags);
#endif
ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
#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))
int filetype = 0;
int encrypted = 0;
size_t max_block_size;
+ int hash_flags = 0;
+ static char *eop_read_dirblock = NULL;
cd = (struct check_dir_struct *) priv_data;
ibuf = buf = cd->buf;
* very large and then the files are deleted. For now, all that is
* needed is to avoid e2fsck filling in these holes as part of
* feature flag. */
- if (db->blk == 0 && ext2fs_has_feature_largedir(fs->super))
+ if (db->blk == 0 && ext2fs_has_feature_largedir(fs->super) &&
+ !ext2fs_has_feature_inline_data(fs->super))
return 0;
if (db->blk == 0 && !inline_data_size) {
db->blockcnt, ino);
#endif
- ehandler_operation(_("reading directory block"));
+ if (!eop_read_dirblock)
+ eop_read_dirblock = (char *) _("reading directory block");
+ ehandler_operation(eop_read_dirblock);
if (inline_data_size) {
memset(buf, 0, fs->blocksize - inline_data_size);
cd->pctx.errcode = ext2fs_inline_data_get(fs, ino, 0, buf, 0);
dir_modified++;
if (dx_db) {
- ext2fs_dirhash(dx_dir->hashversion, dirent->name,
- ext2fs_dirent_name_len(dirent),
- fs->super->s_hash_seed, &hash, 0);
+ if (dx_dir->casefolded_hash)
+ hash_flags = EXT4_CASEFOLD_FL;
+
+ ext2fs_dirhash2(dx_dir->hashversion, dirent->name,
+ ext2fs_dirent_name_len(dirent),
+ fs->encoding, hash_flags,
+ fs->super->s_hash_seed, &hash, 0);
if (hash < dx_db->min_hash)
dx_db->min_hash = hash;
if (hash > dx_db->max_hash)
struct del_block {
e2fsck_t ctx;
e2_blkcnt_t num;
+ blk64_t last_cluster;
};
/*
void *priv_data)
{
struct del_block *p = priv_data;
+ blk64_t cluster = EXT2FS_B2C(fs, *block_nr);
if (*block_nr == 0)
return 0;
+
+ if (cluster == p->last_cluster)
+ return 0;
+
+ p->last_cluster = cluster;
if ((*block_nr < fs->super->s_first_data_block) ||
(*block_nr >= ext2fs_blocks_count(fs->super)))
return 0;
- if ((*block_nr % EXT2FS_CLUSTER_RATIO(fs)) == 0)
- ext2fs_block_alloc_stats2(fs, *block_nr, -1);
+
+ ext2fs_block_alloc_stats2(fs, *block_nr, -1);
p->num++;
return 0;
}
del_block.ctx = ctx;
del_block.num = 0;
+ del_block.last_cluster = 0;
pctx.errcode = ext2fs_block_iterate3(fs, ino, 0, block_buf,
deallocate_inode_block,
&del_block);