119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * e2fsck.c - superblock checks 33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header% 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License. 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header% 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef EXT2_SKIP_UUID 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "uuid/uuid.h" 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2fsck.h" 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "problem.h" 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define MIN_CHECK 1 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define MAX_CHECK 2 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void check_super_value(e2fsck_t ctx, const char *descr, 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long value, int flags, 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned long min_val, unsigned long max_val) 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (((flags & MIN_CHECK) && (value < min_val)) || 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((flags & MAX_CHECK) && (value > max_val))) { 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = value; 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.str = descr; 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx); 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; /* never get here! */ 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * helper function to release an inode 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct process_block_struct { 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx; 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf; 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context *pctx; 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int truncating; 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int truncate_offset; 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t truncate_block; 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int truncated_blocks; 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int abort; 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t errcode; 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int release_inode_block(ext2_filsys fs, 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t *block_nr, 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t blockcnt, 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t ref_blk EXT2FS_ATTR((unused)), 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ref_offset EXT2FS_ATTR((unused)), 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data) 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct process_block_struct *pb; 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx; 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context *pctx; 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blk = *block_nr; 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int retval = 0; 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb = (struct process_block_struct *) priv_data; 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx = pb->ctx; 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx = pb->pctx; 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->blk = blk; 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->blkcount = blockcnt; 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (HOLE_BLKADDR(blk)) 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((blk < fs->super->s_first_data_block) || 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (blk >= fs->super->s_blocks_count)) { 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx); 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return_abort: 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->abort = 1; 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ext2fs_test_block_bitmap(fs->block_map, blk)) { 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx); 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto return_abort; 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we are deleting an orphan, then we leave the fields alone. 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we are truncating an orphan, then update the inode fields 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * and clean up any partial block data. 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb->truncating) { 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * We only remove indirect blocks if they are 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * completely empty. 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (blockcnt < 0) { 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i, limit; 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t *bp; 1053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->errcode = io_channel_read_blk(fs->io, blk, 1, 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->buf); 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb->errcode) 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto return_abort; 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project limit = fs->blocksize >> 2; 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0, bp = (blk_t *) pb->buf; 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project i < limit; i++, bp++) 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (*bp) 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * We don't remove direct blocks until we've reached 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the truncation block. 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (blockcnt >= 0 && blockcnt < pb->truncate_block) 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If part of the last block needs truncating, we do 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * it here. 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((blockcnt == pb->truncate_block) && pb->truncate_offset) { 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->errcode = io_channel_read_blk(fs->io, blk, 1, 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->buf); 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb->errcode) 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto return_abort; 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(pb->buf + pb->truncate_offset, 0, 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->blocksize - pb->truncate_offset); 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->errcode = io_channel_write_blk(fs->io, blk, 1, 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->buf); 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb->errcode) 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto return_abort; 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->truncated_blocks++; 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *block_nr = 0; 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval |= BLOCK_CHANGED; 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 1433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_alloc_stats(fs, blk, -1); 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 1473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function releases an inode. Returns 1 if an inconsistency was 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * found. If the inode has a link count, then it is being truncated and 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * not deleted. 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode *inode, char *block_buf, 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context *pctx) 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct process_block_struct pb; 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u32 count; 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ext2fs_inode_has_valid_blocks(inode)) 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.buf = block_buf + 3 * ctx->fs->blocksize; 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.ctx = ctx; 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.abort = 0; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.errcode = 0; 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.pctx = pctx; 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode->i_links_count) { 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncating = 1; 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncate_block = (e2_blkcnt_t) 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((((long long)inode->i_size_high << 32) + 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode->i_size + fs->blocksize - 1) / 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->blocksize); 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncate_offset = inode->i_size % fs->blocksize; 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncating = 0; 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncate_block = 0; 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncate_offset = 0; 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.truncated_blocks = 0; 1833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE, 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_buf, release_inode_block, &pb); 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("release_inode_blocks", retval, 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while calling ext2fs_block_iterate for inode %d"), 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ino); 18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb.abort) 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Refresh the inode since ext2fs_block_iterate may have changed it */ 19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks"); 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb.truncated_blocks) 1983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_iblk_sub_blocks(fs, inode, pb.truncated_blocks); 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode->i_file_acl) { 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl, 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_buf, -1, &count); 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) { 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = 0; 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project count = 1; 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("release_inode_blocks", retval, 20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("while calling ext2fs_adjust_ea_refcount for inode %d"), 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ino); 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (count == 0) 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1); 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode->i_file_acl = 0; 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function releases all of the orphan inodes. It returns 1 if 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * it hit some error, and 0 on success. 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int release_orphan_inodes(e2fsck_t ctx) 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino, next_ino; 22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block_buf; 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((ino = fs->super->s_last_orphan) == 0) 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Win or lose, we won't be using the head of the orphan inode 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * list again. 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_last_orphan = 0; 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If the filesystem contains errors, don't run the orphan 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * list, since the orphan list can't be trusted; and we're 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * going to be running a full e2fsck run anyway... 24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fs->super->s_state & EXT2_ERROR_FS) 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 2493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((ino < EXT2_FIRST_INODE(fs->super)) || 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (ino > fs->super->s_inodes_count)) { 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = ino; 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx); 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "block iterate buffer"); 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_bitmaps(ctx); 2613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (ino) { 26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes"); 26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = ino; 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.inode = &inode; 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.str = inode.i_links_count ? _("Truncating") : 26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project _("Clearing"); 26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx); 27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project next_ino = inode.i_dtime; 27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (next_ino && 27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((next_ino < EXT2_FIRST_INODE(fs->super)) || 27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (next_ino > fs->super->s_inodes_count))) { 27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = next_ino; 27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx); 27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto return_abort; 27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx)) 28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto return_abort; 28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!inode.i_links_count) { 28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_inode_alloc_stats2(fs, ino, -1, 28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project LINUX_S_ISDIR(inode.i_mode)); 28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_dtime = ctx->now; 28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_dtime = 0; 29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_write_inode(ctx, ino, &inode, "delete_file"); 29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ino = next_ino; 29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&block_buf); 29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectreturn_abort: 29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&block_buf); 29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check the resize inode to make sure it is sane. We check both for 30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the case where on-line resizing is not enabled (in which case the 30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * resize inode should be cleared) as well as the case where on-line 30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * resizing is enabled. 30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid check_resize_inode(e2fsck_t ctx) 30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i, gdt_off, ind_off; 31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dgrp_t j; 31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blk, pblk, expect; 31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u32 *dind_buf = 0, *ind_buf; 31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 3213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * If the resize inode feature isn't set, then 32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * s_reserved_gdt_blocks must be zero. 32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(fs->super->s_feature_compat & 32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_COMPAT_RESIZE_INODE)) { 32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fs->super->s_reserved_gdt_blocks) { 32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = fs->super->s_reserved_gdt_blocks; 32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS, 32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &pctx)) { 33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_reserved_gdt_blocks = 0; 33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Read the resize inode */ 33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = EXT2_RESIZE_INO; 33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); 33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 3403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fs->super->s_feature_compat & 34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_COMPAT_RESIZE_INODE) 34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_RESIZE_INODE; 34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 3473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * If the resize inode feature isn't set, check to make sure 34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the resize inode is cleared; then we're done. 34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 3503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(fs->super->s_feature_compat & 35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_COMPAT_RESIZE_INODE)) { 35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < EXT2_N_BLOCKS; i++) { 35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_block[i]) 35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((i < EXT2_N_BLOCKS) && 35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) { 35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(&inode, 0, sizeof(inode)); 35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, 36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "clear_resize"); 36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 36419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * The resize inode feature is enabled; check to make sure the 36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * only block in use is the double indirect block 36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk = inode.i_block[EXT2_DIND_BLOCK]; 37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < EXT2_N_BLOCKS; i++) { 37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (i != EXT2_DIND_BLOCK && inode.i_block[i]) 37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count || 37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(inode.i_mode & LINUX_S_IFREG) || 37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (blk < fs->super->s_first_data_block || 37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk >= fs->super->s_blocks_count)) { 37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project resize_inode_invalid: 37919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) { 38019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(&inode, 0, sizeof(inode)); 38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, 38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "clear_resize"); 38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_RESIZE_INODE; 38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->options & E2F_OPT_READONLY)) { 38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_state &= ~EXT2_VALID_FS; 38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto cleanup; 39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2, 39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "resize dind buffer"); 39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize); 39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_read_ind_block(fs, blk, dind_buf); 39619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto resize_inode_invalid; 39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project gdt_off = fs->desc_blocks; 40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks; 4013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4; 40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project i++, gdt_off++, pblk++) { 40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project gdt_off %= fs->blocksize/4; 40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dind_buf[gdt_off] != pblk) 40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto resize_inode_invalid; 40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_read_ind_block(fs, pblk, ind_buf); 4073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto resize_inode_invalid; 40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ind_off = 0; 41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (j = 1; j < fs->group_desc_count; j++) { 41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ext2fs_bg_has_super(fs, j)) 41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project expect = pblk + (j * fs->super->s_blocks_per_group); 41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ind_buf[ind_off] != expect) 41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto resize_inode_invalid; 41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ind_off++; 41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectcleanup: 42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dind_buf) 42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&dind_buf); 42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function checks the dirhash signed/unsigned hint if necessary. 42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void e2fsck_fix_dirhash_hint(e2fsck_t ctx) 43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_super_block *sb = ctx->fs->super; 43219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char c; 43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((ctx->options & E2F_OPT_READONLY) || 43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) || 43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (sb->s_flags & (EXT2_FLAGS_SIGNED_HASH|EXT2_FLAGS_UNSIGNED_HASH))) 43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project c = (char) 255; 44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_DIRHASH_HINT, &pctx)) { 44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (((int) c) == -1) { 44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_flags |= EXT2_FLAGS_SIGNED_HASH; 44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_flags |= EXT2_FLAGS_UNSIGNED_HASH; 44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(ctx->fs); 45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid check_super_block(e2fsck_t ctx) 45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 45619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t first_block, last_block; 45819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_super_block *sb = fs->super; 45919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_group_desc *gd; 4603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt problem_t problem; 46119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blocks_per_group = fs->super->s_blocks_per_group; 46219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t bpg_max; 46319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int inodes_per_block; 46419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ipg_max; 46519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int inode_size; 4663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int accept_time_fudge; 4678558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall int broken_system_clock; 46819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dgrp_t i; 46919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t should_be; 47019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 4713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t free_blocks = 0; 4723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ino_t free_inodes = 0; 4733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int csum_flag, clear_test_fs_flag; 47419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 47519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super); 47619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ipg_max = inodes_per_block * (blocks_per_group - 4); 47719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb)) 47819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ipg_max = EXT2_MAX_INODES_PER_GROUP(sb); 47919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bpg_max = 8 * EXT2_BLOCK_SIZE(sb); 48019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb)) 48119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb); 48219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 48319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, 48419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap"); 48519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, 48619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sizeof(int) * fs->group_desc_count, "invalid_block_bitmap"); 48719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx, 48819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sizeof(int) * fs->group_desc_count, "invalid_inode_table"); 48919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 49019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 49119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 49219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 49319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Verify the super block constants... 49419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 49519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "inodes_count", sb->s_inodes_count, 49619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK, 1, 0); 49719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "blocks_count", sb->s_blocks_count, 49819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK, 1, 0); 49919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "first_data_block", sb->s_first_data_block, 50019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MAX_CHECK, 0, sb->s_blocks_count); 50119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "log_block_size", sb->s_log_block_size, 50219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK | MAX_CHECK, 0, 50319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE); 50419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "log_frag_size", sb->s_log_frag_size, 50519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size); 50619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "frags_per_group", sb->s_frags_per_group, 50719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group, 50819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bpg_max); 50919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group, 51019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK | MAX_CHECK, 8, bpg_max); 51119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group, 51219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max); 51319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count, 51419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MAX_CHECK, 0, sb->s_blocks_count / 2); 5153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt check_super_value(ctx, "reserved_gdt_blocks", 51619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_reserved_gdt_blocks, MAX_CHECK, 0, 51719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->blocksize/4); 5183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (sb->s_rev_level > EXT2_GOOD_OLD_REV) 5193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt check_super_value(ctx, "first_ino", sb->s_first_ino, 5203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt MIN_CHECK | MAX_CHECK, 5213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_GOOD_OLD_FIRST_INO, sb->s_inodes_count); 52219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_size = EXT2_INODE_SIZE(sb); 52319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project check_super_value(ctx, "inode_size", 52419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_size, MIN_CHECK | MAX_CHECK, 52519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize); 52619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode_size & (inode_size - 1)) { 52719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = inode_size; 52819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.str = "inode_size"; 52919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx); 53019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; /* never get here! */ 53119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 53219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 5333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 53419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((ctx->flags & E2F_FLAG_GOT_DEVSIZE) && 53519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (ctx->num_blocks < sb->s_blocks_count)) { 53619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = sb->s_blocks_count; 53719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk2 = ctx->num_blocks; 53819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) { 53919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 54019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 54119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 54219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 54319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 54419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) { 54519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = EXT2_BLOCK_SIZE(sb); 54619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk2 = EXT2_FRAG_SIZE(sb); 54719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx); 54819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 54919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 55019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 55119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 55219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = sb->s_frags_per_group >> 5533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (sb->s_log_block_size - sb->s_log_frag_size); 55419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sb->s_blocks_per_group != should_be) { 55519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = sb->s_blocks_per_group; 55619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk2 = should_be; 55719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx); 55819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 55919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 56019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 56119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 56219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = (sb->s_log_block_size == 0) ? 1 : 0; 56319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sb->s_first_data_block != should_be) { 56419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = sb->s_first_data_block; 56519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk2 = should_be; 56619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx); 56719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 56819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 56919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 57019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 57119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = sb->s_inodes_per_group * fs->group_desc_count; 57219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sb->s_inodes_count != should_be) { 57319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = sb->s_inodes_count; 57419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino2 = should_be; 57519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) { 57619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_inodes_count = should_be; 57719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 57819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 57919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 58019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 58119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 58219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Verify the group descriptors.... 58319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 5843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_block = sb->s_first_data_block; 5853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt last_block = sb->s_blocks_count-1; 58619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super, 5883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT4_FEATURE_RO_COMPAT_GDT_CSUM); 58919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) { 59019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.group = i; 59119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super, 5933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT4_FEATURE_INCOMPAT_FLEX_BG)) { 5943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_block = ext2fs_group_first_block(fs, i); 5953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt last_block = ext2fs_group_last_block(fs, i); 5963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 59719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 59819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((gd->bg_block_bitmap < first_block) || 59919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (gd->bg_block_bitmap > last_block)) { 60019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = gd->bg_block_bitmap; 60119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx)) 60219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project gd->bg_block_bitmap = 0; 60319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 60419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (gd->bg_block_bitmap == 0) { 60519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_block_bitmap_flag[i]++; 60619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_bitmaps++; 60719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 60819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((gd->bg_inode_bitmap < first_block) || 60919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (gd->bg_inode_bitmap > last_block)) { 61019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = gd->bg_inode_bitmap; 61119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx)) 61219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project gd->bg_inode_bitmap = 0; 61319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 61419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (gd->bg_inode_bitmap == 0) { 61519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_inode_bitmap_flag[i]++; 61619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_bitmaps++; 61719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 61819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((gd->bg_inode_table < first_block) || 61919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((gd->bg_inode_table + 62019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->inode_blocks_per_group - 1) > last_block)) { 62119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = gd->bg_inode_table; 62219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx)) 62319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project gd->bg_inode_table = 0; 62419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 62519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (gd->bg_inode_table == 0) { 62619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_inode_table_flag[i]++; 62719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->invalid_bitmaps++; 62819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 62919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free_blocks += gd->bg_free_blocks_count; 63019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free_inodes += gd->bg_free_inodes_count; 63119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 63219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) || 63319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (gd->bg_free_inodes_count > sb->s_inodes_per_group) || 63419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (gd->bg_used_dirs_count > sb->s_inodes_per_group)) 63519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_valid(fs); 63619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt should_be = 0; 6383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!ext2fs_group_desc_csum_verify(fs, i)) { 6393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) { 6403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT | 6413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_BG_INODE_UNINIT); 6423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_itable_unused = 0; 6433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt should_be = 1; 6443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 6463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!csum_flag && 6493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (gd->bg_flags &(EXT2_BG_BLOCK_UNINIT|EXT2_BG_INODE_UNINIT)|| 6503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_itable_unused != 0)){ 6513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_0_GDT_UNINIT, &pctx)) { 6523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_flags &= ~(EXT2_BG_BLOCK_UNINIT | 6533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_BG_INODE_UNINIT); 6543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_itable_unused = 0; 6553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt should_be = 1; 6563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 6583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (i == fs->group_desc_count - 1 && 6613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_flags & EXT2_BG_BLOCK_UNINIT) { 6623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_0_BB_UNINIT_LAST, &pctx)) { 6633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT; 6643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt should_be = 1; 6653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 6673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (gd->bg_flags & EXT2_BG_BLOCK_UNINIT && 6703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt !(gd->bg_flags & EXT2_BG_INODE_UNINIT)) { 6713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx)) { 6723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_flags &= ~EXT2_BG_BLOCK_UNINIT; 6733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt should_be = 1; 6743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 6763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (csum_flag && 6793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (gd->bg_itable_unused > gd->bg_free_inodes_count || 6803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_itable_unused > sb->s_inodes_per_group)) { 6813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pctx.blk = gd->bg_itable_unused; 6823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx)) { 6833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt gd->bg_itable_unused = 0; 6843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt should_be = 1; 6853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 6873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (should_be) 6903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_group_desc_csum_set(fs, i); 69119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 69219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 69319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 69419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Update the global counts from the block group counts. This 69519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * is needed for an experimental patch which eliminates 69619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * locking the entire filesystem when allocating blocks or 69719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * inodes; if the filesystem is not unmounted cleanly, the 69819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * global counts may not be accurate. 69919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 70019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((free_blocks != sb->s_free_blocks_count) || 70119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (free_inodes != sb->s_free_inodes_count)) { 70219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->options & E2F_OPT_READONLY) 70319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_valid(fs); 70419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 70519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_free_blocks_count = free_blocks; 70619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_free_inodes_count = free_inodes; 70719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 70819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 70919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 71119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((sb->s_free_blocks_count > sb->s_blocks_count) || 71219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (sb->s_free_inodes_count > sb->s_inodes_count)) 71319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_valid(fs); 71419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 71519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 71619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 71719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we have invalid bitmaps, set the error state of the 71819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * filesystem. 71919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 72019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) { 72119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_state &= ~EXT2_VALID_FS; 72219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 72319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 72419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 72519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 7263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 72719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef EXT2_SKIP_UUID 72819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 72919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If the UUID field isn't assigned, assign it. 73019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 73119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) { 73219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) { 73319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project uuid_generate(sb->s_uuid); 73419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 73519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 73619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 73719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 73819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 73919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 74019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 7413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Check to see if we should disable the test_fs flag 7423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 7433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt profile_get_boolean(ctx->profile, "options", 7443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "clear_test_fs_flag", 0, 1, 7453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &clear_test_fs_flag); 7463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(ctx->options & E2F_OPT_READONLY) && 7473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt clear_test_fs_flag && 7483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (fs->super->s_flags & EXT2_FLAGS_TEST_FILESYS) && 7493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (fs_proc_check("ext4") || check_for_modules("ext4"))) { 7503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_0_CLEAR_TESTFS_FLAG, &pctx)) { 7513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS; 7523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_mark_super_dirty(fs); 7533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 7543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 7553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 7563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 75819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * For the Hurd, check to see if the filetype option is set, 75919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * since it doesn't support it. 76019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 76119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->options & E2F_OPT_READONLY) && 76219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_creator_os == EXT2_OS_HURD && 76319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (fs->super->s_feature_incompat & 76419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_INCOMPAT_FILETYPE)) { 76519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) { 76619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_feature_incompat &= 76719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ~EXT2_FEATURE_INCOMPAT_FILETYPE; 76819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 76919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 77019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 77119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 77219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 77319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 77419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we have any of the compatibility flags set, we need to have a 77519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * revision 1 filesystem. Most kernels will not check the flags on 77619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * a rev 0 filesystem and we may have corruption issues because of 77719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the incompatible changes to the filesystem. 77819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 77919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->options & E2F_OPT_READONLY) && 78019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_rev_level == EXT2_GOOD_OLD_REV && 78119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (fs->super->s_feature_compat || 78219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_feature_ro_compat || 78319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_feature_incompat) && 78419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) { 78519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_update_dynamic_rev(fs); 78619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 78719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 78819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 78919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 79019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 79119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Clean up any orphan inodes, if present. 79219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 79319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) { 79419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_state &= ~EXT2_VALID_FS; 79519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 79619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 79719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 79819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 7993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Unfortunately, due to Windows' unfortunate design decision 8003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * to configure the hardware clock to tick localtime, instead 8013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * of the more proper and less error-prone UTC time, many 8023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * users end up in the situation where the system clock is 8033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * incorrectly set at the time when e2fsck is run. 8043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 8053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Historically this was usually due to some distributions 8063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * having buggy init scripts and/or installers that didn't 8073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * correctly detect this case and take appropriate 8083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * countermeasures. However, it's still possible, despite the 8093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * best efforts of init script and installer authors to not be 8103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * able to detect this misconfiguration, usually due to a 8113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * buggy or misconfigured virtualization manager or the 8123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * installer not having access to a network time server during 8133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * the installation process. So by default, we allow the 8143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * superblock times to be fudged by up to 24 hours. This can 8153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * be disabled by setting options.accept_time_fudge to the 8163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * boolean value of false in e2fsck.conf. We also support 8173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * options.buggy_init_scripts for backwards compatibility. 81819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 8193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt profile_get_boolean(ctx->profile, "options", "accept_time_fudge", 8203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 0, 1, &accept_time_fudge); 82119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project profile_get_boolean(ctx->profile, "options", "buggy_init_scripts", 8223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 0, accept_time_fudge, &accept_time_fudge); 8233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ctx->time_fudge = accept_time_fudge ? 86400 : 0; 82419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8258558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall profile_get_boolean(ctx->profile, "options", "broken_system_clock", 8268558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall 0, 0, &broken_system_clock); 8278558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall 8283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 82919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to see if the superblock last mount time or last 83019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * write time is in the future. 83119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 8328558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall if (!broken_system_clock && 8338558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall !(ctx->flags & E2F_FLAG_TIME_INSANE) && 8348558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall fs->super->s_mtime > (__u32) ctx->now) { 83519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = fs->super->s_mtime; 8363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt problem = PR_0_FUTURE_SB_LAST_MOUNT; 8373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fs->super->s_mtime <= (__u32) ctx->now + ctx->time_fudge) 8383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt problem = PR_0_FUTURE_SB_LAST_MOUNT_FUDGED; 8393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, problem, &pctx)) { 84019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_mtime = ctx->now; 84119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 84219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 84319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8448558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall if (!broken_system_clock && 8458558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall !(ctx->flags & E2F_FLAG_TIME_INSANE) && 8468558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall fs->super->s_wtime > (__u32) ctx->now) { 84719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = fs->super->s_wtime; 8483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt problem = PR_0_FUTURE_SB_LAST_WRITE; 8493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fs->super->s_wtime <= (__u32) ctx->now + ctx->time_fudge) 8503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt problem = PR_0_FUTURE_SB_LAST_WRITE_FUDGED; 8513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, problem, &pctx)) { 85219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_wtime = ctx->now; 85319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 85419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 85519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 85619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 85719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 85819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Move the ext3 journal file, if necessary. 85919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 86019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_move_ext3_journal(ctx); 86119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 86219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 86319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Fix journal hint, if necessary 86419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 86519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_fix_ext3_journal_hint(ctx); 86619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 86719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 86819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Add dirhash hint if necessary 86919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 87019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_fix_dirhash_hint(ctx); 87119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 87219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 87319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 87419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 87519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 87619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to see if we should backup the master sb to the backup super 87719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * blocks. Returns non-zero if the sb should be backed up. 87819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 87919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 88019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 88119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * A few flags are set on the fly by the kernel, but only in the 88219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * primary superblock. This is actually a bad thing, and we should 88319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * try to discourage it in the future. In particular, for the newer 88419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * ext4 files, especially EXT4_FEATURE_RO_COMPAT_DIR_NLINK and 88519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * EXT3_FEATURE_INCOMPAT_EXTENTS. So some of these may go away in the 8863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * future. EXT3_FEATURE_INCOMPAT_RECOVER may also get set when 8873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * copying the primary superblock during online resize. 88819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 88919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * The kernel will set EXT2_FEATURE_COMPAT_EXT_ATTR, but 89019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * unfortunately, we shouldn't ignore it since if it's not set in the 89119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * backup, the extended attributes in the filesystem will be stripped 89219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * away. 89319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 89419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define FEATURE_RO_COMPAT_IGNORE (EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ 89519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT4_FEATURE_RO_COMPAT_DIR_NLINK) 8963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define FEATURE_INCOMPAT_IGNORE (EXT3_FEATURE_INCOMPAT_EXTENTS| \ 8973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT3_FEATURE_INCOMPAT_RECOVER) 89819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 89919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint check_backup_super_block(e2fsck_t ctx) 90019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 90119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 90219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 90319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dgrp_t g; 90419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t sb; 90519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ret = 0; 9063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char buf[SUPERBLOCK_SIZE]; 9073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_super_block *backup_sb; 90819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 90919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 91019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we are already writing out the backup blocks, then we 91119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * don't need to test. Also, if the filesystem is invalid, or 91219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the check was aborted or cancelled, we also don't want to 91319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * do the backup. If the filesystem was opened read-only then 91419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * we can't do the backup. 91519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 91619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (((fs->flags & EXT2_FLAG_MASTER_SB_ONLY) == 0) || 91719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !ext2fs_test_valid(fs) || 91819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (fs->super->s_state & EXT2_ERROR_FS) || 91919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (ctx->flags & (E2F_FLAG_ABORT | E2F_FLAG_CANCEL)) || 92019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (ctx->options & E2F_OPT_READONLY)) 92119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 92219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 92319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (g = 1; g < fs->group_desc_count; g++) { 92419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ext2fs_bg_has_super(fs, g)) 92519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 92619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 92719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb = fs->super->s_first_data_block + 92819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (g * fs->super->s_blocks_per_group); 92919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = io_channel_read_blk(fs->io, sb, -SUPERBLOCK_SIZE, 9313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt buf); 9323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 9333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt continue; 9343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt backup_sb = (struct ext2_super_block *) buf; 9353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef WORDS_BIGENDIAN 9363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_swap_super(backup_sb); 9373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 9383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((backup_sb->s_magic != EXT2_SUPER_MAGIC) || 9393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (backup_sb->s_rev_level > EXT2_LIB_CURRENT_REV) || 9403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((backup_sb->s_log_block_size + EXT2_MIN_BLOCK_LOG_SIZE) > 9413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_MAX_BLOCK_LOG_SIZE) || 9423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (EXT2_INODE_SIZE(backup_sb) < EXT2_GOOD_OLD_INODE_SIZE)) 94319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 94419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 94519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SUPER_INCOMPAT_DIFFERENT(x) \ 9463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((fs->super->x & ~FEATURE_INCOMPAT_IGNORE) != \ 9473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (backup_sb->x & ~FEATURE_INCOMPAT_IGNORE)) 94819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SUPER_RO_COMPAT_DIFFERENT(x) \ 9493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((fs->super->x & ~FEATURE_RO_COMPAT_IGNORE) != \ 9503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (backup_sb->x & ~FEATURE_RO_COMPAT_IGNORE)) 95119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define SUPER_DIFFERENT(x) \ 9523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (fs->super->x != backup_sb->x) 95319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 95419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (SUPER_DIFFERENT(s_feature_compat) || 95519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project SUPER_INCOMPAT_DIFFERENT(s_feature_incompat) || 95619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project SUPER_RO_COMPAT_DIFFERENT(s_feature_ro_compat) || 95719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project SUPER_DIFFERENT(s_blocks_count) || 95819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project SUPER_DIFFERENT(s_inodes_count) || 9593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memcmp(fs->super->s_uuid, backup_sb->s_uuid, 96019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sizeof(fs->super->s_uuid))) 96119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = 1; 96219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 96319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 96419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret; 96519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 966