#ifdef RESOURCE_TRACK
struct resource_track rtrack;
#endif
- struct dir_info *dir;
struct check_dir_struct cd;
struct dx_dir_info *dx_dir;
struct dx_dirblock_info *dx_db, *dx_parent;
if (!(ctx->options & E2F_OPT_PREEN))
fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
- cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
+ e2fsck_setup_tdb_icount(ctx, EXT2_ICOUNT_OPT_INCREMENT,
+ &ctx->inode_count);
+ if (ctx->inode_count)
+ cd.pctx.errcode = 0;
+ else
+ cd.pctx.errcode = ext2fs_create_icount2(fs,
+ EXT2_ICOUNT_OPT_INCREMENT,
0, ctx->inode_link_info,
&ctx->inode_count);
if (cd.pctx.errcode) {
* present. (If the root directory is not present, we will
* create it in pass 3.)
*/
- dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
- if (dir)
- dir->parent = EXT2_ROOT_INO;
+ (void) e2fsck_dir_info_set_parent(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
cd.buf = buf;
cd.ctx = ctx;
*/
static int check_dotdot(e2fsck_t ctx,
struct ext2_dir_entry *dirent,
- struct dir_info *dir, struct problem_context *pctx)
+ ext2_ino_t ino, struct problem_context *pctx)
{
- int problem = 0;
+ int problem = 0;
if (!dirent->inode)
problem = PR_2_MISSING_DOT_DOT;
}
return 0;
}
- dir->dotdot = dirent->inode;
+ if (e2fsck_dir_info_set_dotdot(ctx, ino, dirent->inode)) {
+ fix_problem(ctx, PR_2_NO_DIRINFO, pctx);
+ return -1;
+ }
return 0;
}
{
char *cp = (char *) dirent;
int left = fs->blocksize - *offset - dirent->rec_len;
- int name_len = dirent->name_len & 0xFF;
+ unsigned int name_len = dirent->name_len & 0xFF;
/*
* Special case of directory entry of size 8: copy what's left
* record length.
*/
if ((left < 0) &&
- (name_len + 8 <= dirent->rec_len + left) &&
+ (name_len + 8 <= dirent->rec_len + (unsigned) left) &&
dirent->inode <= fs->super->s_inodes_count &&
strnlen(dirent->name, name_len) == name_len) {
dirent->rec_len += left;
struct ext2_db_entry *db,
void *priv_data)
{
- struct dir_info *subdir, *dir;
+ struct dir_info *subdir;
struct dx_dir_info *dx_dir;
#ifdef ENABLE_HTREE
struct dx_dirblock_info *dx_db = 0;
int dot_state;
blk_t block_nr = db->blk;
ext2_ino_t ino = db->ino;
+ ext2_ino_t subdir_parent;
__u16 links;
struct check_dir_struct *cd;
char *buf;
static dict_t de_dict;
struct problem_context pctx;
int dups_found = 0;
+ int ret;
cd = (struct check_dir_struct *) priv_data;
buf = cd->buf;
clear_htree(ctx, ino);
dx_dir->numblocks = 0;
dx_db = 0;
- }
+ }
dx_dir->hashversion = root->hash_version;
+ if ((dx_dir->hashversion <= EXT2_HASH_TEA) &&
+ (fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH))
+ dx_dir->hashversion += 3;
dx_dir->depth = root->indirect_levels + 1;
} else if ((dirent->inode == 0) &&
(dirent->rec_len == fs->blocksize) &&
if (check_dot(ctx, dirent, ino, &cd->pctx))
dir_modified++;
} else if (dot_state == 1) {
- dir = e2fsck_get_dir_info(ctx, ino);
- if (!dir) {
- fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
+ ret = check_dotdot(ctx, dirent, ino, &cd->pctx);
+ if (ret < 0)
goto abort_free_dict;
- }
- if (check_dotdot(ctx, dirent, dir, &cd->pctx))
+ if (ret)
dir_modified++;
} else if (dirent->inode == ino) {
problem = PR_2_LINK_DOT;
if ((dot_state > 1) &&
(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
dirent->inode))) {
- subdir = e2fsck_get_dir_info(ctx, dirent->inode);
- if (!subdir) {
+ if (e2fsck_dir_info_get_parent(ctx, dirent->inode,
+ &subdir_parent)) {
cd->pctx.ino = dirent->inode;
fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
goto abort_free_dict;
}
- if (subdir->parent) {
- cd->pctx.ino2 = subdir->parent;
+ if (subdir_parent) {
+ cd->pctx.ino2 = subdir_parent;
if (fix_problem(ctx, PR_2_LINK_DIR,
&cd->pctx)) {
dirent->inode = 0;
goto next;
}
cd->pctx.ino2 = 0;
- } else
- subdir->parent = ino;
+ } else {
+ (void) e2fsck_dir_info_set_parent(ctx,
+ dirent->inode, ino);
+ }
}
if (dups_found) {
}
switch (fs->super->s_creator_os) {
- case EXT2_OS_LINUX:
- frag = &inode.osd2.linux2.l_i_frag;
- fsize = &inode.osd2.linux2.l_i_fsize;
- break;
case EXT2_OS_HURD:
frag = &inode.osd2.hurd2.h_i_frag;
fsize = &inode.osd2.hurd2.h_i_fsize;
pctx.num = 0;
}
+ if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
+ !(fs->super->s_feature_ro_compat &
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+ (inode.osd2.linux2.l_i_blocks_hi != 0)) {
+ pctx.num = inode.osd2.linux2.l_i_blocks_hi;
+ if (fix_problem(ctx, PR_2_BLOCKS_HI_ZERO, &pctx)) {
+ inode.osd2.linux2.l_i_blocks_hi = 0;
+ inode_modified++;
+ }
+ }
+
if (inode.i_file_acl &&
((inode.i_file_acl < fs->super->s_first_data_block) ||
(inode.i_file_acl >= fs->super->s_blocks_count))) {