struct process_inode_block {
ext2_ino_t ino;
- struct ext2_inode inode;
+ struct ext2_inode_large inode;
};
struct scan_callback_struct {
ext2_extent_handle_t handle;
struct ext2_extent_info info;
struct ext2fs_extent extent;
- int encrypted = 0;
if ((inode->i_size_high || inode->i_size == 0) ||
(inode->i_flags & EXT2_INDEX_FL))
return;
}
+ /* check if there is no place for an EA header */
+ if (inode->i_extra_isize >= max - sizeof(__u32))
+ return;
+
eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
inode->i_extra_isize);
if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
* data. If it's true, we will treat it as a directory.
*/
- extent_fs = (ctx->fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_EXTENTS);
- inlinedata_fs = (ctx->fs->super->s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_INLINE_DATA);
+ extent_fs = ext2fs_has_feature_extents(ctx->fs->super);
+ inlinedata_fs = ext2fs_has_feature_inline_data(ctx->fs->super);
if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL)) {
size_t size;
__u32 dotdot;
int dirty = 0;
/* Both feature flags not set? Just run the regular checks */
- if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT3_FEATURE_INCOMPAT_EXTENTS) &&
- !EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT4_FEATURE_INCOMPAT_INLINE_DATA))
+ if (!ext2fs_has_feature_extents(fs->super) &&
+ !ext2fs_has_feature_inline_data(fs->super))
return 0;
/* Clear both flags if it's a special file */
}
/* If it looks short enough to be inline data, try to clear extents */
- if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
- max_inline_ea_size = EXT2_INODE_SIZE(fs->super) -
+ if (inode_size > EXT2_GOOD_OLD_INODE_SIZE)
+ max_inline_ea_size = inode_size -
(EXT2_GOOD_OLD_INODE_SIZE +
((struct ext2_inode_large *)inode)->i_extra_isize);
else
}
}
+/*
+ * Check if the passed ino is one of the used superblock quota inodes.
+ *
+ * Before the quota inodes were journaled, older superblock quota inodes
+ * were just regular files in the filesystem and not reserved inodes. This
+ * checks if the passed ino is one of the s_*_quota_inum superblock fields,
+ * which may not always be the same as the EXT4_*_QUOTA_INO fields.
+ */
+static int quota_inum_is_super(struct ext2_super_block *sb, ext2_ino_t ino)
+{
+ enum quota_type qtype;
+
+ for (qtype = 0; qtype < MAXQUOTAS; qtype++)
+ if (*quota_sb_inump(sb, qtype) == ino)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Check if the passed ino is one of the reserved quota inodes.
+ * This checks if the inode number is one of the reserved EXT4_*_QUOTA_INO
+ * inodes. These inodes may or may not be in use by the quota feature.
+ */
+static int quota_inum_is_reserved(ext2_filsys fs, ext2_ino_t ino)
+{
+ enum quota_type qtype;
+
+ for (qtype = 0; qtype < MAXQUOTAS; qtype++)
+ if (quota_type2inum(qtype, fs->super) == ino)
+ return 1;
+
+ return 0;
+}
+
void e2fsck_pass1(e2fsck_t ctx)
{
int i;
unsigned int save_type;
int imagic_fs, extent_fs, inlinedata_fs;
int low_dtime_check = 1;
- int inode_size;
+ int inode_size = EXT2_INODE_SIZE(fs->super);
int failed_csum = 0;
ext2_ino_t ino_threshold = 0;
dgrp_t ra_group = 0;
if (!(ctx->options & E2F_OPT_PREEN))
fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
- if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
+ if (ext2fs_has_feature_dir_index(fs->super) &&
!(ctx->options & E2F_OPT_NO)) {
if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
ctx->dirs_to_hash = 0;
}
#undef EXT2_BPP
- imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
- extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
- inlinedata_fs = (sb->s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_INLINE_DATA);
+ imagic_fs = ext2fs_has_feature_imagic_inodes(sb);
+ extent_fs = ext2fs_has_feature_extents(sb);
+ inlinedata_fs = ext2fs_has_feature_inline_data(sb);
/*
* Allocate bitmaps structures
ctx->flags |= E2F_FLAG_ABORT;
return;
}
- inode_size = EXT2_INODE_SIZE(fs->super);
inode = (struct ext2_inode *)
e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
fs->super->s_mkfs_time < fs->super->s_inodes_count))
low_dtime_check = 0;
- if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
+ if (ext2fs_has_feature_mmp(fs->super) &&
fs->super->s_mmp_block > fs->super->s_first_data_block &&
fs->super->s_mmp_block < ext2fs_blocks_count(fs->super))
ext2fs_mark_block_bitmap2(ctx->block_found_map,
pass1_readahead(ctx, &ra_group, &ino_threshold);
ehandler_operation(old_op);
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
+ goto endit;
if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
/*
* If badblocks says badblocks is bad, offer to clear
pctx.errcode = ext2fs_inline_data_size(fs, ino, &size);
if (!pctx.errcode && size &&
fix_problem(ctx, PR_1_INLINE_DATA_FEATURE, &pctx)) {
- sb->s_feature_incompat |=
- EXT4_FEATURE_INCOMPAT_INLINE_DATA;
+ ext2fs_set_feature_inline_data(sb);
ext2fs_mark_super_dirty(fs);
inlinedata_fs = 1;
} else if (fix_problem(ctx, PR_1_INLINE_DATA_SET, &pctx)) {
if ((ext2fs_extent_header_verify(inode->i_block,
sizeof(inode->i_block)) == 0) &&
fix_problem(ctx, PR_1_EXTENT_FEATURE, &pctx)) {
- sb->s_feature_incompat |= EXT3_FEATURE_INCOMPAT_EXTENTS;
+ ext2fs_set_feature_extents(sb);
ext2fs_mark_super_dirty(fs);
extent_fs = 1;
} else if (fix_problem(ctx, PR_1_EXTENTS_SET, &pctx)) {
inode_size, "pass1");
failed_csum = 0;
}
- } else if ((ino == EXT4_USR_QUOTA_INO) ||
- (ino == EXT4_GRP_QUOTA_INO)) {
+ } else if (quota_inum_is_reserved(fs, ino)) {
ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
- if ((fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_QUOTA) &&
- ((fs->super->s_usr_quota_inum == ino) ||
- (fs->super->s_grp_quota_inum == ino))) {
+ if (ext2fs_has_feature_quota(fs->super) &&
+ quota_inum_is_super(fs->super, ino)) {
if (!LINUX_S_ISREG(inode->i_mode) &&
fix_problem(ctx, PR_1_QUOTA_BAD_MODE,
&pctx)) {
(LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
mark_inode_bad(ctx, ino);
if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
- !(fs->super->s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_64BIT) &&
+ !ext2fs_has_feature_64bit(fs->super) &&
inode->osd2.linux2.l_i_file_acl_high != 0)
mark_inode_bad(ctx, ino);
if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
- !(fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+ !ext2fs_has_feature_huge_file(fs->super) &&
(inode->osd2.linux2.l_i_blocks_hi != 0))
mark_inode_bad(ctx, ino);
if (inode->i_flags & EXT2_IMAGIC_FL) {
inode->i_block[EXT2_TIND_BLOCK] ||
ext2fs_file_acl_block(fs, inode))) {
inodes_to_process[process_inode_count].ino = ino;
- inodes_to_process[process_inode_count].inode = *inode;
+ inodes_to_process[process_inode_count].inode =
+ *(struct ext2_inode_large *)inode;
process_inode_count++;
} else
check_blocks(ctx, &pctx, block_buf);
if ((ctx->flags & E2F_FLAG_SIGNAL_MASK) == 0)
print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
+ else
+ ctx->invalid_bitmaps++;
}
#undef FINISH_INODE_LOOP
* Or if the extended attribute block is an invalid block,
* then the inode is also corrupted.
*/
- if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
+ if (!ext2fs_has_feature_xattr(fs->super) ||
(blk < fs->super->s_first_data_block) ||
(blk >= ext2fs_blocks_count(fs->super))) {
mark_inode_bad(ctx, ino);
if ((!LINUX_S_ISDIR(inode->i_mode) &&
fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
- (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
+ (!ext2fs_has_feature_dir_index(fs->super) &&
fix_problem(ctx, PR_1_HTREE_SET, pctx)))
return 1;
ext2_ino_t ino = pctx->ino;
errcode_t retval;
blk64_t eof_lblk;
+ struct ext3_extent_header *eh;
+
+ /* Check for a proper extent header... */
+ eh = (struct ext3_extent_header *) &inode->i_block[0];
+ retval = ext2fs_extent_header_verify(eh, sizeof(inode->i_block));
+ if (retval) {
+ if (fix_problem(ctx, PR_1_MISSING_EXTENT_HEADER, pctx))
+ e2fsck_clear_inode(ctx, ino, inode, 0,
+ "check_blocks_extents");
+ pctx->errcode = 0;
+ return;
+ }
+ /* ...since this function doesn't fail if i_block is zeroed. */
pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
if (pctx->errcode) {
if (fix_problem(ctx, PR_1_READ_EXTENT, pctx))
pctx->ino = ino;
pctx->errcode = 0;
- extent_fs = (ctx->fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_EXTENTS);
- inlinedata_fs = (ctx->fs->super->s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_INLINE_DATA);
+ extent_fs = ext2fs_has_feature_extents(ctx->fs->super);
+ inlinedata_fs = ext2fs_has_feature_inline_data(ctx->fs->super);
if (check_ext_attr(ctx, pctx, block_buf)) {
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
inode->i_flags &= ~EXT2_INDEX_FL;
dirty_inode++;
} else {
-#ifdef ENABLE_HTREE
e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
-#endif
}
}
}
}
- if (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) {
+ if (ino != quota_type2inum(PRJQUOTA, fs->super) &&
+ (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super))) {
quota_data_add(ctx->qctx, inode, ino,
pb.num_blocks * fs->blocksize);
quota_data_inodes(ctx->qctx, inode, ino, +1);
}
- if (!(fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
+ if (!ext2fs_has_feature_huge_file(fs->super) ||
!(inode->i_flags & EXT4_HUGE_FILE_FL))
pb.num_blocks *= (fs->blocksize / 512);
pb.num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
ctx->large_files++;
if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
((pb.num_blocks != ext2fs_inode_i_blocks(fs, inode)) ||
- ((fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+ (ext2fs_has_feature_huge_file(fs->super) &&
(inode->i_flags & EXT4_HUGE_FILE_FL) &&
(inode->osd2.linux2.l_i_blocks_hi != 0)))) {
pctx->num = pb.num_blocks;
* a block mapped file, so rebuild it as an extent file. We can skip
* symlinks because they're never rewritten.
*/
- if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_BIGALLOC) &&
+ if (ext2fs_has_feature_bigalloc(fs->super) &&
(LINUX_S_ISREG(inode->i_mode) || LINUX_S_ISDIR(inode->i_mode)) &&
ext2fs_inode_data_blocks2(fs, inode) > 0 &&
(ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INO(fs->super)) &&
* within the flex_bg, and if that fails then try finding the
* space anywhere in the filesystem.
*/
- is_flexbg = EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT4_FEATURE_INCOMPAT_FLEX_BG);
+ is_flexbg = ext2fs_has_feature_flex_bg(fs->super);
if (is_flexbg) {
flexbg_size = 1 << fs->super->s_log_groups_per_flex;
flexbg = group / flexbg_size;