X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fpass2.c;h=3b473af02a43ed5ec2f65ec41cbdf1403c31fd3a;hb=9d8b56b3b5d59691f16a8b8ae5fb763bc6be3d15;hp=9d682a94d6a04c76ae848f3aef78b351b9723ea5;hpb=f15b1aaf8f1241ac55057ec61a0d399147fc644b;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 9d682a9..3b473af 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -332,7 +332,8 @@ static short htree_depth(struct dx_dir_info *dx_dir, return depth; } -static int dict_de_cmp(const void *cmp_ctx, const void *a, const void *b) +static int dict_de_cmp(const void *cmp_ctx EXT2FS_ATTR((unused)), + const void *a, const void *b) { const struct ext2_dir_entry *de_a, *de_b; int a_len, b_len; @@ -359,7 +360,9 @@ static int dict_de_cf_cmp(const void *cmp_ctx, const void *a, const void *b) de_b = (const struct ext2_dir_entry *) b; b_len = ext2fs_dirent_name_len(de_b); - return ext2fs_casefold_cmp(tbl, de_a->name, a_len, de_b->name, b_len); + return ext2fs_casefold_cmp(tbl, + (const unsigned char *) de_a->name, a_len, + (const unsigned char *) de_b->name, b_len); } /* @@ -404,6 +407,7 @@ static int check_dot(e2fsck_t ctx, int status = 0; int created = 0; problem_t problem = 0; + int ftype = EXT2_FT_DIR; if (!dirent->inode) problem = PR_2_MISSING_DOT; @@ -415,12 +419,14 @@ static int check_dot(e2fsck_t ctx, (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); if (problem) { + if (!ext2fs_has_feature_filetype(ctx->fs->super)) + ftype = EXT2_FT_UNKNOWN; if (fix_problem(ctx, problem, pctx)) { if (rec_len < 12) rec_len = dirent->rec_len = 12; dirent->inode = ino; ext2fs_dirent_set_name_len(dirent, 1); - ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN); + ext2fs_dirent_set_file_type(dirent, ftype); dirent->name[0] = '.'; dirent->name[1] = '\0'; status = 1; @@ -441,12 +447,24 @@ static int check_dot(e2fsck_t ctx, nextdir = (struct ext2_dir_entry *) ((char *) dirent + 12); dirent->rec_len = 12; - (void) ext2fs_set_rec_len(ctx->fs, new_len, - nextdir); - nextdir->inode = 0; - ext2fs_dirent_set_name_len(nextdir, 0); - ext2fs_dirent_set_file_type(nextdir, - EXT2_FT_UNKNOWN); + /* if the next entry looks like "..", leave it + * and let check_dotdot() verify the dirent, + * otherwise zap the following entry. */ + if (strncmp(nextdir->name, "..", 3) != 0) { + (void)ext2fs_set_rec_len(ctx->fs, + new_len, + nextdir); + nextdir->inode = 0; + ext2fs_dirent_set_name_len(nextdir, 0); + ext2fs_dirent_set_file_type(nextdir, + ftype); +#ifdef WORDS_BIGENDIAN + } else { + (void) ext2fs_dirent_swab_in2(ctx->fs, + (char *) nextdir, + ctx->fs->blocksize - 12, 0); +#endif + } status = 1; } } @@ -465,6 +483,7 @@ static int check_dotdot(e2fsck_t ctx, { problem_t problem = 0; unsigned int rec_len; + int ftype = EXT2_FT_DIR; if (!dirent->inode) problem = PR_2_MISSING_DOT_DOT; @@ -477,6 +496,8 @@ static int check_dotdot(e2fsck_t ctx, (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); if (problem) { + if (!ext2fs_has_feature_filetype(ctx->fs->super)) + ftype = EXT2_FT_UNKNOWN; if (fix_problem(ctx, problem, pctx)) { if (rec_len < 12) dirent->rec_len = 12; @@ -487,7 +508,7 @@ static int check_dotdot(e2fsck_t ctx, */ dirent->inode = EXT2_ROOT_INO; ext2fs_dirent_set_name_len(dirent, 2); - ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN); + ext2fs_dirent_set_file_type(dirent, ftype); dirent->name[0] = '.'; dirent->name[1] = '.'; dirent->name[2] = '\0'; @@ -777,7 +798,7 @@ static void salvage_directory(ext2_filsys fs, * Special case of directory entry of size 8: copy what's left * of the directory block up to cover up the invalid hole. */ - if ((left >= ext2fs_dir_rec_len(1, hash_in_dirent)) && + if ((left >= (int) ext2fs_dir_rec_len(1, hash_in_dirent)) && (rec_len == EXT2_DIR_ENTRY_HEADER_LEN)) { memmove(cp, cp+EXT2_DIR_ENTRY_HEADER_LEN, left); memset(cp + left, 0, EXT2_DIR_ENTRY_HEADER_LEN); @@ -1283,7 +1304,7 @@ skip_checksum: if (cf_dir) { dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cf_cmp); - dict_set_cmp_context(&de_dict, (void *)ctx->fs->encoding); + dict_set_cmp_context(&de_dict, (const void *)ctx->fs->encoding); } else { dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp); } @@ -1299,7 +1320,7 @@ skip_checksum: unsigned int name_len; /* csum entry is not checked here, so don't worry about it */ int extended = (dot_state > 1) && hash_in_dirent; - int min_dir_len = ext2fs_dir_rec_len(1, extended); + unsigned int min_dir_len = ext2fs_dir_rec_len(1, extended); problem = 0; if (!inline_data_size || dot_state > 1) { @@ -1355,12 +1376,14 @@ skip_checksum: hash_in_dirent); #ifdef WORDS_BIGENDIAN if (need_reswab) { + unsigned int len; + (void) ext2fs_get_rec_len(fs, - dirent, &rec_len); - ext2fs_dirent_swab_in2(fs, - ((char *)dirent) + offset + rec_len, - max_block_size - offset - rec_len, - 0); + dirent, &len); + len += offset; + if (max_block_size > len) + ext2fs_dirent_swab_in2(fs, + ((char *)dirent) + len, max_block_size - len, 0); } #endif dir_modified++; @@ -1418,7 +1441,10 @@ skip_checksum: name_len = ext2fs_dirent_name_len(dirent); if (((dirent->inode != EXT2_ROOT_INO) && (dirent->inode < EXT2_FIRST_INODE(fs->super))) || - (dirent->inode > fs->super->s_inodes_count)) { + (dirent->inode > fs->super->s_inodes_count) || + (dirent->inode == fs->super->s_usr_quota_inum) || + (dirent->inode == fs->super->s_grp_quota_inum) || + (dirent->inode == fs->super->s_prj_quota_inum)) { problem = PR_2_BAD_INO; } else if (ctx->inode_bb_map && (ext2fs_test_inode_bitmap2(ctx->inode_bb_map, @@ -1513,6 +1539,7 @@ skip_checksum: &cd->pctx)){ ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT); + ext2fs_group_desc_csum_set(fs, group); ext2fs_mark_super_dirty(fs); ctx->flags |= E2F_FLAG_RESTART_LATER; } else { @@ -1524,6 +1551,7 @@ skip_checksum: pctx.num = dirent->inode; if (fix_problem(ctx, PR_2_INOREF_IN_UNUSED, &cd->pctx)){ ext2fs_bg_itable_unused_set(fs, group, 0); + ext2fs_group_desc_csum_set(fs, group); ext2fs_mark_super_dirty(fs); ctx->flags |= E2F_FLAG_RESTART_LATER; } else {