119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * pass2.c --- check directory structure 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% 103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Pass 2 of e2fsck iterates through all active directory inodes, and 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * applies to following tests to each directory entry in the directory 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * blocks in the inodes: 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The length of the directory entry (rec_len) should be at 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * least 8 bytes, and no more than the remaining space 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * left in the directory block. 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The length of the name in the directory entry (name_len) 193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * should be less than (rec_len - 8). 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode number in the directory entry should be within 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * legal bounds. 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode number should refer to a in-use inode. 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The first entry should be '.', and its inode should be 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the inode of the directory. 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The second entry should be '..'. 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * To minimize disk seek time, the directory blocks are processed in 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * sorted order of block numbers. 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Pass 2 also collects the following information: 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode numbers of the subdirectories for each directory. 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Pass 2 relies on the following information from previous passes: 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The directory information collected in pass 1. 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode_used_map bitmap 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode_bad_map bitmap 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode_dir_map bitmap 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Pass 2 frees the following data structures 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode_bad_map bitmap 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * - The inode_reg_map bitmap 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _GNU_SOURCE 1 /* get strnlen() */ 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2fsck.h" 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "problem.h" 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "dict.h" 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef NO_INLINE_FUNCS 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _INLINE_ 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _INLINE_ inline 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* #define DX_DEBUG */ 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Keeps track of how many times an inode is referenced. 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf); 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_dir_block(ext2_filsys fs, 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_db_entry *dir_blocks_info, 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data); 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int allocate_dir_block(e2fsck_t ctx, 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_db_entry *dir_blocks_info, 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf, struct problem_context *pctx); 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void clear_htree(e2fsck_t ctx, ext2_ino_t ino); 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int htree_depth(struct dx_dir_info *dx_dir, 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dirblock_info *dx_db); 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b); 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct check_dir_struct { 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf; 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int count, max; 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx; 793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}; 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid e2fsck_pass2(e2fsck_t ctx) 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_super_block *sb = ctx->fs->super; 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf; 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef RESOURCE_TRACK 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct resource_track rtrack; 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct check_dir_struct cd; 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dir_info *dx_dir; 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dirblock_info *dx_db, *dx_parent; 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int b; 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i, depth; 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem_t code; 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int bad_dir; 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt init_resource_track(&rtrack, ctx->fs->io); 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&cd.pctx); 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MTRACE 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project mtrace_print("Pass 2"); 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->options & E2F_OPT_PREEN)) 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx); 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt e2fsck_setup_tdb_icount(ctx, EXT2_ICOUNT_OPT_INCREMENT, 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &ctx->inode_count); 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->inode_count) 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd.pctx.errcode = 0; 1123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 1133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt cd.pctx.errcode = ext2fs_create_icount2(fs, 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_ICOUNT_OPT_INCREMENT, 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 0, ctx->inode_link_info, 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &ctx->inode_count); 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (cd.pctx.errcode) { 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx); 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize, 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "directory scan buffer"); 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Set up the parent pointer for the root directory, if 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * present. (If the root directory is not present, we will 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * create it in pass 3.) 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (void) e2fsck_dir_info_set_parent(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO); 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd.buf = buf; 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd.ctx = ctx; 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd.count = 1; 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd.max = ext2fs_dblist_count(fs->dblist); 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->progress) 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (void) (ctx->progress)(ctx, 2, 0, cd.max); 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp); 1423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block, 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &cd); 1453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART) 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 1473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ctx->flags & E2F_FLAG_RESTART_LATER) { 1493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ctx->flags |= E2F_FLAG_RESTART; 1503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 1513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 1523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (cd.pctx.errcode) { 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx); 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_HTREE 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) { 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_dir->numblocks == 0) 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_dir = 0; 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.dir = dx_dir->ino; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = dx_dir->dx_block; 16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db->flags & DX_FLAG_REFERENCED) 17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_DUP_REF; 17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_REFERENCED; 17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Find all of the first and last leaf blocks, and 17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * update their parent's min and max hash values 17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (b=0, dx_db = dx_dir->dx_block; 17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project b < dx_dir->numblocks; 17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project b++, dx_db++) { 18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((dx_db->type != DX_DIRBLOCK_LEAF) || 18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST))) 18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_parent = &dx_dir->dx_block[dx_db->parent]; 18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * XXX Make sure dx_parent->min_hash > dx_db->min_hash 18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db->flags & DX_FLAG_FIRST) 18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_parent->min_hash = dx_db->min_hash; 18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * XXX Make sure dx_parent->max_hash < dx_db->max_hash 19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db->flags & DX_FLAG_LAST) 19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_parent->max_hash = dx_db->max_hash; 19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 1953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (b=0, dx_db = dx_dir->dx_block; 19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project b < dx_dir->numblocks; 19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project b++, dx_db++) { 19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blkcount = b; 20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.group = dx_db->parent; 20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project code = 0; 20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(dx_db->flags & DX_FLAG_FIRST) && 20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dx_db->min_hash < dx_db->node_min_hash)) { 20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = dx_db->min_hash; 20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk2 = dx_db->node_min_hash; 20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project code = PR_2_HTREE_MIN_HASH; 20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, code, &pctx); 20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_dir++; 20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db->type == DX_DIRBLOCK_LEAF) { 21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project depth = htree_depth(dx_dir, dx_db); 21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (depth != dx_dir->depth) { 2133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pctx.num = dx_dir->depth; 21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project code = PR_2_HTREE_BAD_DEPTH; 21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, code, &pctx); 21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_dir++; 21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 2203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * This test doesn't apply for the root block 22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * at block #0 22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (b && 22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dx_db->max_hash > dx_db->node_max_hash)) { 22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = dx_db->max_hash; 22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk2 = dx_db->node_max_hash; 22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project code = PR_2_HTREE_MAX_HASH; 22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, code, &pctx); 22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_dir++; 23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(dx_db->flags & DX_FLAG_REFERENCED)) { 23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project code = PR_2_HTREE_NOTREF; 23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, code, &pctx); 23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_dir++; 23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (dx_db->flags & DX_FLAG_DUP_REF) { 23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project code = PR_2_HTREE_DUPREF; 23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, code, &pctx); 23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bad_dir++; 23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) { 24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_htree(ctx, dx_dir->ino); 24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->numblocks = 0; 24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt e2fsck_free_dx_dir_info(ctx); 24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&buf); 24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_dblist(fs->dblist); 25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->inode_bad_map) { 25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_inode_bitmap(ctx->inode_bad_map); 25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->inode_bad_map = 0; 25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->inode_reg_map) { 25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_inode_bitmap(ctx->inode_reg_map); 25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->inode_reg_map = 0; 25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->large_files) { 26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(sb->s_feature_ro_compat & 26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_RO_COMPAT_LARGE_FILE) && 26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) { 26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sb->s_feature_ro_compat |= 26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_RO_COMPAT_LARGE_FILE; 26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (sb->s_rev_level == EXT2_GOOD_OLD_REV && 27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) { 27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_update_dynamic_rev(fs); 27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_super_dirty(fs); 27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 2763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt print_resource_track(ctx, _("Pass 2"), &rtrack, fs->io); 27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define MAX_DEPTH 32000 28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int htree_depth(struct dx_dir_info *dx_dir, 28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dirblock_info *dx_db) 28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int depth = 0; 28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) { 28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = &dx_dir->dx_block[dx_db->parent]; 28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project depth++; 28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return depth; 29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int dict_de_cmp(const void *a, const void *b) 29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const struct ext2_dir_entry *de_a, *de_b; 29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int a_len, b_len; 29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project de_a = (const struct ext2_dir_entry *) a; 29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project a_len = de_a->name_len & 0xFF; 30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project de_b = (const struct ext2_dir_entry *) b; 30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project b_len = de_b->name_len & 0xFF; 30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (a_len != b_len) 30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (a_len - b_len); 30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return strncmp(de_a->name, de_b->name, a_len); 30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This is special sort function that makes sure that directory blocks 31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * with a dirblock of zero are sorted to the beginning of the list. 31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This guarantees that the root node of the htree directories are 31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * processed first, so we know what hash version to use. 31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b) 31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const struct ext2_db_entry *db_a = 31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (const struct ext2_db_entry *) a; 31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const struct ext2_db_entry *db_b = 32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (const struct ext2_db_entry *) b; 32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db_a->blockcnt && !db_b->blockcnt) 32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!db_a->blockcnt && db_b->blockcnt) 32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return -1; 3273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db_a->blk != db_b->blk) 32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (int) (db_a->blk - db_b->blk); 3303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db_a->ino != db_b->ino) 33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (int) (db_a->ino - db_b->ino); 33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (int) (db_a->blockcnt - db_b->blockcnt); 33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Make sure the first entry in the directory is '.', and that the 34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * directory entry is sane. 34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_dot(e2fsck_t ctx, 34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, 34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino, struct problem_context *pctx) 34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *nextdir; 3473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int rec_len, new_len; 34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int status = 0; 34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int created = 0; 35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int problem = 0; 3513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!dirent->inode) 35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_MISSING_DOT; 35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (((dirent->name_len & 0xFF) != 1) || 35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name[0] != '.')) 35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_1ST_NOT_DOT; 35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (dirent->name[1] != '\0') 35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_DOT_NULL_TERM; 3593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 3603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); 36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (problem) { 36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, problem, pctx)) { 3633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (rec_len < 12) 3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt rec_len = dirent->rec_len = 12; 36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = ino; 36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name_len = 1; 36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name[0] = '.'; 36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name[1] = '\0'; 36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project status = 1; 37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project created = 1; 37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dirent->inode != ino) { 37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) { 37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = ino; 37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project status = 1; 37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 3793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (rec_len > 12) { 3803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt new_len = rec_len - 12; 38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (new_len > 12) { 38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (created || 38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { 38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nextdir = (struct ext2_dir_entry *) 38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((char *) dirent + 12); 38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->rec_len = 12; 3873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_set_rec_len(ctx->fs, new_len, 3883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt nextdir); 38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nextdir->inode = 0; 39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project nextdir->name_len = 0; 39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project status = 1; 39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return status; 39619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Make sure the second entry in the directory is '..', and that the 40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * directory entry is sane. We do not check the inode number of '..' 40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * here; this gets done in pass 3. 40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_dotdot(e2fsck_t ctx, 40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, 40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino, struct problem_context *pctx) 40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 4073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int rec_len, problem = 0; 4083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!dirent->inode) 41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_MISSING_DOT_DOT; 41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (((dirent->name_len & 0xFF) != 2) || 41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name[0] != '.') || 41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name[1] != '.')) 41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_2ND_NOT_DOT_DOT; 41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (dirent->name[2] != '\0') 41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_DOT_DOT_NULL_TERM; 41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); 41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (problem) { 42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, problem, pctx)) { 4213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (rec_len < 12) 42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->rec_len = 12; 42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Note: we don't have the parent inode just 42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * yet, so we will fill it in with the root 42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * inode. This will get fixed in pass 3. 42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = EXT2_ROOT_INO; 42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name_len = 2; 43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name[0] = '.'; 43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name[1] = '.'; 43219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name[2] = '\0'; 43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 4343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (e2fsck_dir_info_set_dotdot(ctx, ino, dirent->inode)) { 43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_NO_DIRINFO, pctx); 43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return -1; 44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to make sure a directory entry doesn't contain any illegal 44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * characters. 44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_name(e2fsck_t ctx, 44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, 4503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_ino_t dir_ino EXT2FS_ATTR((unused)), 45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context *pctx) 45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i; 45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int fixup = -1; 45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ret = 0; 4563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for ( i = 0; i < (dirent->name_len & 0xFF); i++) { 45819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dirent->name[i] == '/' || dirent->name[i] == '\0') { 45919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fixup < 0) { 46019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx); 46119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 46219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fixup) { 46319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name[i] = '.'; 46419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = 1; 46519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 46619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 46719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 46819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret; 46919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 47019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 47119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 47219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check the directory filetype (if present) 47319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 47419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic _INLINE_ int check_filetype(e2fsck_t ctx, 47519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, 47619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t dir_ino EXT2FS_ATTR((unused)), 47719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context *pctx) 47819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 47919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int filetype = dirent->name_len >> 8; 48019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int should_be = EXT2_FT_UNKNOWN; 48119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 48219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 48319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!(ctx->fs->super->s_feature_incompat & 48419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_FEATURE_INCOMPAT_FILETYPE)) { 48519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (filetype == 0 || 48619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx)) 48719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 48819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name_len = dirent->name_len & 0xFF; 48919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 49019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 49119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 49219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) { 49319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = EXT2_FT_DIR; 49419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map, 49519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode)) { 49619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = EXT2_FT_REG_FILE; 49719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (ctx->inode_bad_map && 49819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_test_inode_bitmap(ctx->inode_bad_map, 49919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode)) 50019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = 0; 50119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 50219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, dirent->inode, &inode, 50319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "check_filetype"); 50419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project should_be = ext2_file_type(inode.i_mode); 50519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 50619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (filetype == should_be) 50719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 50819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->num = should_be; 50919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 51019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE, 51119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx) == 0) 51219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 5133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 51419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8; 51519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 51619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 51719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 51819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_HTREE 51919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void parse_int_node(ext2_filsys fs, 52019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_db_entry *db, 52119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct check_dir_struct *cd, 52219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dir_info *dx_dir, 52319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block_buf) 52419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 52519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dx_root_info *root; 52619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dx_entry *ent; 52719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dx_countlimit *limit; 52819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dirblock_info *dx_db; 52919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i, expect_limit, count; 53019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blk; 53119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_dirhash_t min_hash = 0xffffffff; 53219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_dirhash_t max_hash = 0; 53319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_dirhash_t hash = 0, prev_hash; 53419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 53519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db->blockcnt == 0) { 53619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project root = (struct ext2_dx_root_info *) (block_buf + 24); 5373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 53819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DX_DEBUG 53919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Root node dump:\n"); 54019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t Reserved zero: %u\n", root->reserved_zero); 54119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t Hash Version: %d\n", root->hash_version); 54219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t Info length: %d\n", root->info_length); 54319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t Indirect levels: %d\n", root->indirect_levels); 54419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\t Flags: %d\n", root->unused_flags); 54519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 54619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 54719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length); 54819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 54919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ent = (struct ext2_dx_entry *) (block_buf+8); 55019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 55119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project limit = (struct ext2_dx_countlimit *) ent; 55219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 55319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DX_DEBUG 5543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Number of entries (count): %d\n", 55519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_le16_to_cpu(limit->count)); 5563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Number of entries (limit): %d\n", 55719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_le16_to_cpu(limit->limit)); 55819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 55919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 56019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project count = ext2fs_le16_to_cpu(limit->count); 56119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project expect_limit = (fs->blocksize - ((char *) ent - block_buf)) / 56219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sizeof(struct ext2_dx_entry); 56319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) { 56419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.num = ext2fs_le16_to_cpu(limit->limit); 56519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx)) 56619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto clear_and_exit; 56719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 56819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (count > expect_limit) { 56919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.num = count; 57019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx)) 57119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto clear_and_exit; 57219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project count = expect_limit; 57319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 5743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 57519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < count; i++) { 57619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project prev_hash = hash; 57719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0; 57819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DX_DEBUG 57919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Entry #%d: Hash 0x%08x, block %u\n", i, 58019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project hash, ext2fs_le32_to_cpu(ent[i].block)); 58119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 58219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff; 58319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* Check to make sure the block is valid */ 58419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (blk >= (blk_t) dx_dir->numblocks) { 58519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.blk = blk; 58619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK, 58719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &cd->pctx)) 58819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto clear_and_exit; 58919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 59019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 59119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (hash < prev_hash && 59219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx)) 59319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto clear_and_exit; 59419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = &dx_dir->dx_block[blk]; 59519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db->flags & DX_FLAG_REFERENCED) { 59619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_DUP_REF; 59719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 59819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_REFERENCED; 59919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->parent = db->blockcnt; 60019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 60119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (hash < min_hash) 60219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project min_hash = hash; 60319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (hash > max_hash) 60419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project max_hash = hash; 60519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->node_min_hash = hash; 60619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((i+1) < count) 6073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dx_db->node_max_hash = 60819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_le32_to_cpu(ent[i+1].hash) & ~1; 60919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else { 61019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->node_max_hash = 0xfffffffe; 61119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_LAST; 61219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 61319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (i == 0) 61419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_FIRST; 61519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 61619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DX_DEBUG 61719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n", 61819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project db->blockcnt, min_hash, max_hash); 61919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 62019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = &dx_dir->dx_block[db->blockcnt]; 62119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->min_hash = min_hash; 62219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->max_hash = max_hash; 62319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 62419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 62519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectclear_and_exit: 62619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_htree(cd->ctx, cd->pctx.ino); 62719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->numblocks = 0; 62819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 62919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* ENABLE_HTREE */ 63019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 63119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 63219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Given a busted directory, try to salvage it somehow. 6333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 63419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 63519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void salvage_directory(ext2_filsys fs, 63619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, 63719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *prev, 63819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int *offset) 63919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 64019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *cp = (char *) dirent; 6413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int left; 6423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int rec_len, prev_rec_len; 64319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int name_len = dirent->name_len & 0xFF; 64419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 6463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt left = fs->blocksize - *offset - rec_len; 6473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 64819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 64919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Special case of directory entry of size 8: copy what's left 65019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * of the directory block up to cover up the invalid hole. 65119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 6523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((left >= 12) && (rec_len == 8)) { 65319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memmove(cp, cp+8, left); 65419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(cp + left, 0, 8); 65519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 65619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 65719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 65819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If the directory entry overruns the end of the directory 65919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * block, and the name is small enough to fit, then adjust the 66019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * record length. 66119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 66219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((left < 0) && 6633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((int) rec_len + left > 8) && 6643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (name_len + 8 <= (int) rec_len + left) && 66519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode <= fs->super->s_inodes_count && 66619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project strnlen(dirent->name, name_len) == name_len) { 6673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_set_rec_len(fs, (int) rec_len + left, dirent); 66819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 66919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 67019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 67119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If the record length of the directory entry is a multiple 67219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * of four, and not too big, such that it is valid, let the 67319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * previous directory entry absorb the invalid one. 67419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 6753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (prev && rec_len && (rec_len % 4) == 0 && 6763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (*offset + rec_len <= fs->blocksize)) { 6773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(fs, prev, &prev_rec_len); 6783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt prev_rec_len += rec_len; 6793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_set_rec_len(fs, prev_rec_len, prev); 6803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *offset += rec_len; 68119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 68219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 68319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 68419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Default salvage method --- kill all of the directory 68519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * entries for the rest of the block. We will either try to 68619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * absorb it into the previous directory entry, or create a 68719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * new empty directory entry the rest of the directory block. 68819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 68919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (prev) { 6903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(fs, prev, &prev_rec_len); 6913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt prev_rec_len += fs->blocksize - *offset; 6923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_set_rec_len(fs, prev_rec_len, prev); 69319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *offset = fs->blocksize; 69419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 6953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt rec_len = fs->blocksize - *offset; 6963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_set_rec_len(fs, rec_len, dirent); 69719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name_len = 0; 69819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = 0; 69919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 70019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 70119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 70219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_dir_block(ext2_filsys fs, 70319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_db_entry *db, 70419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data) 70519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 70619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dir_info *dx_dir; 70719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_HTREE 70819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct dx_dirblock_info *dx_db = 0; 70919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* ENABLE_HTREE */ 71019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dir_entry *dirent, *prev; 71119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_dirhash_t hash; 71219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned int offset = 0; 71319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project const char * old_op; 71419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int dir_modified = 0; 71519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int dot_state; 7163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt unsigned int rec_len; 71719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t block_nr = db->blk; 71819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino = db->ino; 71919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t subdir_parent; 72019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u16 links; 72119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct check_dir_struct *cd; 72219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf; 72319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx; 72419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int problem; 72519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dx_root_info *root; 72619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_dx_countlimit *limit; 72719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project static dict_t de_dict; 72819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 72919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int dups_found = 0; 73019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ret; 73119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 73219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd = (struct check_dir_struct *) priv_data; 73319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf = cd->buf; 73419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx = cd->ctx; 73519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART) 73719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return DIRENT_ABORT; 7383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 73919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max)) 74019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return DIRENT_ABORT; 7413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 74219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 7433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Make sure the inode is still in use (could have been 74419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * deleted in the duplicate/bad blocks pass. 74519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 7463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))) 74719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 74819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 74919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.ino = ino; 75019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.blk = block_nr; 75119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.blkcount = db->blockcnt; 75219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.ino2 = 0; 75319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.dirent = 0; 75419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.num = 0; 75519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 75619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db->blk == 0) { 75719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (allocate_dir_block(ctx, db, buf, &cd->pctx)) 75819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 75919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_nr = db->blk; 76019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 76219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db->blockcnt) 76319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dot_state = 2; 76419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 76519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dot_state = 0; 76619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 76719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->dirs_to_hash && 76819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_u32_list_test(ctx->dirs_to_hash, ino)) 76919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dups_found++; 77019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 77119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if 0 77219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr, 77319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project db->blockcnt, ino); 77419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 7753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 77619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project old_op = ehandler_operation(_("reading directory block")); 77719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf); 77819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ehandler_operation(0); 77919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED) 78019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.errcode = 0; /* We'll handle this ourselves */ 78119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (cd->pctx.errcode) { 78219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) { 78319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 78419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return DIRENT_ABORT; 78519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 78619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(buf, 0, fs->blocksize); 78719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 78819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_HTREE 78919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir = e2fsck_get_dx_dir_info(ctx, ino); 79019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_dir && dx_dir->numblocks) { 79119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db->blockcnt >= dx_dir->numblocks) { 7923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_2_UNEXPECTED_HTREE_BLOCK, 79319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &pctx)) { 79419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_htree(ctx, ino); 79519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->numblocks = 0; 79619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = 0; 79719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto out_htree; 79819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 79919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fatal_error(ctx, _("Can not continue.")); 80019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 80119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = &dx_dir->dx_block[db->blockcnt]; 80219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->type = DX_DIRBLOCK_LEAF; 80319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->phys = block_nr; 80419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->min_hash = ~0; 80519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->max_hash = 0; 8063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 80719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent = (struct ext2_dir_entry *) buf; 8083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 80919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project limit = (struct ext2_dx_countlimit *) (buf+8); 81019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db->blockcnt == 0) { 81119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project root = (struct ext2_dx_root_info *) (buf + 24); 81219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->type = DX_DIRBLOCK_ROOT; 81319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST; 81419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((root->reserved_zero || 81519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project root->info_length < 8 || 81619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project root->indirect_levels > 1) && 81719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) { 81819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_htree(ctx, ino); 81919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->numblocks = 0; 82019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db = 0; 82119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 82219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->hashversion = root->hash_version; 82319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((dx_dir->hashversion <= EXT2_HASH_TEA) && 82419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH)) 82519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->hashversion += 3; 82619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_dir->depth = root->indirect_levels + 1; 82719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if ((dirent->inode == 0) && 8283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (rec_len == fs->blocksize) && 82919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name_len == 0) && 8303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (ext2fs_le16_to_cpu(limit->limit) == 8313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((fs->blocksize-8) / 83219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project sizeof(struct ext2_dx_entry)))) 83319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->type = DX_DIRBLOCK_NODE; 83419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 83519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectout_htree: 83619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* ENABLE_HTREE */ 83719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 83819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp); 83919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project prev = 0; 84019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 8413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int group; 8423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_ino_t first_unused_inode; 8433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 84419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = 0; 84519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent = (struct ext2_dir_entry *) (buf + offset); 8463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 84719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.dirent = dirent; 84819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.num = offset; 8493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (((offset + rec_len) > fs->blocksize) || 8503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (rec_len < 12) || 8513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((rec_len % 4) != 0) || 8523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (((dirent->name_len & (unsigned) 0xFF)+8) > rec_len)) { 85319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) { 85419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project salvage_directory(fs, dirent, prev, &offset); 85519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 85619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 85719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 85819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto abort_free_dict; 85919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 86019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) { 86119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) { 86219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->name_len = EXT2_NAME_LEN; 86319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 86419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 86519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 86619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 86719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dot_state == 0) { 86819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (check_dot(ctx, dirent, ino, &cd->pctx)) 86919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 87019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (dot_state == 1) { 87119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = check_dotdot(ctx, dirent, ino, &cd->pctx); 87219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ret < 0) 87319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto abort_free_dict; 87419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ret) 87519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 87619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (dirent->inode == ino) { 87719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_LINK_DOT; 87819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) { 87919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = 0; 88019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 88119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 88219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 88319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!dirent->inode) 88519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 8863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 88719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 88819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Make sure the inode listed is a legal one. 8893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 89019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (((dirent->inode != EXT2_ROOT_INO) && 89119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->inode < EXT2_FIRST_INODE(fs->super))) || 89219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->inode > fs->super->s_inodes_count)) { 89319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BAD_INO; 89419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (ctx->inode_bb_map && 89519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (ext2fs_test_inode_bitmap(ctx->inode_bb_map, 89619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode))) { 89719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 89819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If the inode is in a bad block, offer to 89919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * clear it. 90019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 90119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BB_INODE; 90219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if ((dot_state > 1) && 90319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((dirent->name_len & 0xFF) == 1) && 90419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name[0] == '.')) { 90519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 90619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If there's a '.' entry in anything other 90719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * than the first directory entry, it's a 90819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * duplicate entry that should be removed. 90919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 91019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_DUP_DOT; 91119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if ((dot_state > 1) && 91219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((dirent->name_len & 0xFF) == 2) && 9133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (dirent->name[0] == '.') && 91419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name[1] == '.')) { 91519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 91619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If there's a '..' entry in anything other 91719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * than the second directory entry, it's a 91819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * duplicate entry that should be removed. 91919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 92019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_DUP_DOT_DOT; 92119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if ((dot_state > 1) && 92219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->inode == EXT2_ROOT_INO)) { 92319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 92419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Don't allow links to the root directory. 92519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * We check this specially to make sure we 92619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * catch this error case even if the root 92719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * directory hasn't been created yet. 92819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 92919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_LINK_ROOT; 93019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if ((dot_state > 1) && 93119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name_len & 0xFF) == 0) { 93219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 93319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Don't allow zero-length directory names. 93419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 93519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_NULL_NAME; 93619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 93719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 93819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (problem) { 93919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, problem, &cd->pctx)) { 94019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = 0; 94119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 94219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 94319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 94419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_valid(fs); 94519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (problem == PR_2_BAD_INO) 94619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 94719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 94819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 94919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 95019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 95119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If the inode was marked as having bad fields in 95219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * pass1, process it and offer to fix/clear it. 95319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * (We wait until now so that we can display the 95419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * pathname to the user.) 95519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 95619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->inode_bad_map && 95719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_test_inode_bitmap(ctx->inode_bad_map, 95819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode)) { 95919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (e2fsck_process_bad_inode(ctx, ino, 96019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode, 96119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project buf + fs->blocksize)) { 96219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = 0; 96319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 96419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 96519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 96619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 96719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return DIRENT_ABORT; 96819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 96919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt group = ext2fs_group_of_ino(fs, dirent->inode); 9713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_unused_inode = group * fs->super->s_inodes_per_group + 9723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1 + fs->super->s_inodes_per_group - 9733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fs->group_desc[group].bg_itable_unused; 9743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt cd->pctx.group = group; 9753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 9773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Check if the inode was missed out because 9783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * _INODE_UNINIT flag was set or bg_itable_unused was 9793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * incorrect. If so, clear the _INODE_UNINIT flag and 9803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * restart e2fsck. In the future it would be nice if 9813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * we could call a function in pass1.c that checks the 9823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * newly visible inodes. 9833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 9843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fs->group_desc[group].bg_flags & EXT2_BG_INODE_UNINIT) { 9853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pctx.num = dirent->inode; 9863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_2_INOREF_BG_INO_UNINIT, 9873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &cd->pctx)){ 9883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fs->group_desc[group].bg_flags &= 9893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ~EXT2_BG_INODE_UNINIT; 9903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_mark_super_dirty(fs); 9913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ctx->flags |= E2F_FLAG_RESTART_LATER; 9923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 9933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 9943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (problem == PR_2_BAD_INO) 9953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto next; 9963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (dirent->inode >= first_unused_inode) { 9983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pctx.num = dirent->inode; 9993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_2_INOREF_IN_UNUSED, &cd->pctx)){ 10003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fs->group_desc[group].bg_itable_unused = 0; 10013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_mark_super_dirty(fs); 10023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ctx->flags |= E2F_FLAG_RESTART_LATER; 10033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 10043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 10053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (problem == PR_2_BAD_INO) 10063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto next; 10073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10108558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall /* 10118558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * Offer to clear unused inodes; if we are going to be 10128558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * restarting the scan due to bg_itable_unused being 10138558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * wrong, then don't clear any inodes to avoid zapping 10148558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * inodes that were skipped during pass1 due to an 10158558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * incorrect bg_itable_unused; we'll get any real 10168558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * problems after we restart. 10178558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall */ 10188558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall if (!(ctx->flags & E2F_FLAG_RESTART_LATER) && 10198558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall !(ext2fs_test_inode_bitmap(ctx->inode_used_map, 10208558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall dirent->inode))) 10213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt problem = PR_2_UNUSED_INODE; 10223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (problem) { 10243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, problem, &cd->pctx)) { 10253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dirent->inode = 0; 10263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dir_modified++; 10273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto next; 10283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 10293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_unmark_valid(fs); 10303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (problem == PR_2_BAD_INO) 10313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto next; 10323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 103519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (check_name(ctx, dirent, ino, &cd->pctx)) 103619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 103719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 103819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (check_filetype(ctx, dirent, ino, &cd->pctx)) 103919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 104019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 104119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_HTREE 104219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db) { 104319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_dirhash(dx_dir->hashversion, dirent->name, 104419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dirent->name_len & 0xFF), 104519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->super->s_hash_seed, &hash, 0); 104619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (hash < dx_db->min_hash) 104719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->min_hash = hash; 104819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (hash > dx_db->max_hash) 104919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->max_hash = hash; 105019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 105119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 105219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 105319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 105419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If this is a directory, then mark its parent in its 105519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * dir_info structure. If the parent field is already 105619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * filled in, then this directory has more than one 105719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * hard link. We assume the first link is correct, 105819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * and ask the user if he/she wants to clear this one. 105919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 106019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((dot_state > 1) && 106119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (ext2fs_test_inode_bitmap(ctx->inode_dir_map, 106219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode))) { 106319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (e2fsck_dir_info_get_parent(ctx, dirent->inode, 106419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &subdir_parent)) { 106519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.ino = dirent->inode; 106619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx); 106719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto abort_free_dict; 106819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 106919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (subdir_parent) { 107019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.ino2 = subdir_parent; 107119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_LINK_DIR, 107219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &cd->pctx)) { 107319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode = 0; 107419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 107519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 107619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 107719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.ino2 = 0; 107819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else { 10793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) e2fsck_dir_info_set_parent(ctx, 108019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->inode, ino); 108119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 108219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 108319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 108419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dups_found) { 108519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ; 108619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else if (dict_lookup(&de_dict, dirent)) { 108719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 108819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = ino; 108919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.dirent = dirent; 109019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx); 109119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ctx->dirs_to_hash) 109219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_u32_list_create(&ctx->dirs_to_hash, 50); 109319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->dirs_to_hash) 109419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 109519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dups_found++; 109619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 109719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dict_alloc_insert(&de_dict, dirent, dirent); 10983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 109919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_icount_increment(ctx->inode_count, dirent->inode, 110019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &links); 110119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (links > 1) 110219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->fs_links_count++; 110319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->fs_total_count++; 110419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project next: 110519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project prev = dirent; 11063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (dir_modified) 11073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (void) ext2fs_get_rec_len(fs, dirent, &rec_len); 11083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt offset += rec_len; 110919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dot_state++; 111019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } while (offset < fs->blocksize); 111119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if 0 111219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("\n"); 111319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 111419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_HTREE 111519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dx_db) { 111619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DX_DEBUG 111719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n", 111819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project db->blockcnt, dx_db->type, 111919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dx_db->min_hash, dx_db->max_hash); 112019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 112119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.dir = cd->pctx.ino; 112219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((dx_db->type == DX_DIRBLOCK_ROOT) || 112319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (dx_db->type == DX_DIRBLOCK_NODE)) 112419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project parse_int_node(fs, db, cd, dx_dir, buf); 112519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 112619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* ENABLE_HTREE */ 112719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (offset != fs->blocksize) { 11283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt cd->pctx.num = rec_len - fs->blocksize + offset; 112919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) { 113019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dirent->rec_len = cd->pctx.num; 113119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dir_modified++; 113219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 113319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 113419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (dir_modified) { 113519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf); 113619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (cd->pctx.errcode) { 113719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK, 113819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project &cd->pctx)) 113919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto abort_free_dict; 114019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 114119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_changed(fs); 114219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 114319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project dict_free_nodes(&de_dict); 114419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 114519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectabort_free_dict: 114619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 11473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dict_free_nodes(&de_dict); 114819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return DIRENT_ABORT; 114919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 115019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 115119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 115219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This function is called to deallocate a block, and is an interator 115319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * functioned called by deallocate inode via ext2fs_iterate_block(). 115419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 115519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int deallocate_inode_block(ext2_filsys fs, 115619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t *block_nr, 115719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 115819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t ref_block EXT2FS_ATTR((unused)), 115919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ref_offset EXT2FS_ATTR((unused)), 116019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *priv_data) 116119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 116219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_t ctx = (e2fsck_t) priv_data; 11633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 116419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (HOLE_BLKADDR(*block_nr)) 116519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 116619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((*block_nr < fs->super->s_first_data_block) || 116719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (*block_nr >= fs->super->s_blocks_count)) 116819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 116919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); 117019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_alloc_stats(fs, *block_nr, -1); 117119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 117219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 11733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 117419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 117519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This fuction deallocates an inode 117619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 117719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) 117819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 117919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 118019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 118119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 118219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project __u32 count; 11833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 118419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); 11853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt e2fsck_clear_inode(ctx, ino, &inode, 0, "deallocate_inode"); 118619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 118719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = ino; 118819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 118919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 119019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Fix up the bitmaps... 119119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 119219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_bitmaps(ctx); 119319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); 119419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 119519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_file_acl && 119619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { 119719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, 119819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_buf, -1, &count); 119919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { 120019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.errcode = 0; 120119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project count = 1; 120219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 120319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx.errcode) { 120419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.blk = inode.i_file_acl; 120519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx); 120619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 120719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 120819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 120919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (count == 0) { 121019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_block_bitmap(ctx->block_found_map, 121119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_file_acl); 121219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1); 121319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 121419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_file_acl = 0; 121519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 121619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 121719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ext2fs_inode_has_valid_blocks(&inode)) 121819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 121919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 122019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (LINUX_S_ISREG(inode.i_mode) && 122119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (inode.i_size_high || inode.i_size & 0x80000000UL)) 122219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->large_files--; 122319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 122419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, 122519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project deallocate_inode_block, ctx); 122619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx.errcode) { 122719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx); 122819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ctx->flags |= E2F_FLAG_ABORT; 122919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 123019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 123119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 123219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 123319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 123419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This fuction clears the htree flag on an inode 123519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 123619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void clear_htree(e2fsck_t ctx, ext2_ino_t ino) 123719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 123819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 12393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 124019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, ino, &inode, "clear_htree"); 124119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL; 124219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_write_inode(ctx, ino, &inode, "clear_htree"); 124319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->dirs_to_hash) 124419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_u32_list_add(ctx->dirs_to_hash, ino); 124519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 124619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 124719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 124819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, 124919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino, char *buf) 125019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 125119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 125219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 125319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int inode_modified = 0; 125419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int not_fixed = 0; 125519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project unsigned char *frag, *fsize; 125619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context pctx; 125719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int problem = 0; 125819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 125919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode"); 126019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 126119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project clear_problem_context(&pctx); 126219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.ino = ino; 126319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.dir = dir; 126419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.inode = &inode; 126519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 126619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_file_acl && 126719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { 126819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) { 126919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_file_acl = 0; 127019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 127119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 127219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 127319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 127419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 127519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) && 127619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) && 127719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) && 127819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !(LINUX_S_ISSOCK(inode.i_mode))) 127919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BAD_MODE; 128019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (LINUX_S_ISCHR(inode.i_mode) 128119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project && !e2fsck_pass1_check_device_inode(fs, &inode)) 128219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BAD_CHAR_DEV; 128319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (LINUX_S_ISBLK(inode.i_mode) 128419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project && !e2fsck_pass1_check_device_inode(fs, &inode)) 128519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BAD_BLOCK_DEV; 128619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (LINUX_S_ISFIFO(inode.i_mode) 128719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project && !e2fsck_pass1_check_device_inode(fs, &inode)) 128819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BAD_FIFO; 128919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (LINUX_S_ISSOCK(inode.i_mode) 129019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project && !e2fsck_pass1_check_device_inode(fs, &inode)) 129119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_BAD_SOCKET; 129219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else if (LINUX_S_ISLNK(inode.i_mode) 12933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt && !e2fsck_pass1_check_symlink(fs, ino, &inode, buf)) { 129419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = PR_2_INVALID_SYMLINK; 129519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 129619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 129719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (problem) { 129819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, problem, &pctx)) { 129919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project deallocate_inode(ctx, ino, 0); 130019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 130119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 130219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 130319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 130419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 130519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project problem = 0; 130619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 130819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_faddr) { 130919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) { 131019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_faddr = 0; 131119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 131219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 131319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 131419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 131519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 131619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project switch (fs->super->s_creator_os) { 131719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project case EXT2_OS_HURD: 131819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project frag = &inode.osd2.hurd2.h_i_frag; 131919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fsize = &inode.osd2.hurd2.h_i_fsize; 132019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 132119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project default: 132219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project frag = fsize = 0; 132319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 132419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (frag && *frag) { 132519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = *frag; 132619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) { 132719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *frag = 0; 132819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 132919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 133019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 133119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = 0; 133219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 133319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fsize && *fsize) { 133419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = *fsize; 133519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) { 133619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *fsize = 0; 133719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 133819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 133919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 134019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = 0; 134119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 134219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 134319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((fs->super->s_creator_os == EXT2_OS_LINUX) && 13443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt !(fs->super->s_feature_ro_compat & 134519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 134619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (inode.osd2.linux2.l_i_blocks_hi != 0)) { 134719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx.num = inode.osd2.linux2.l_i_blocks_hi; 134819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_BLOCKS_HI_ZERO, &pctx)) { 134919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.osd2.linux2.l_i_blocks_hi = 0; 135019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 135119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 135219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 135319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(fs->super->s_feature_incompat & 13553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT4_FEATURE_INCOMPAT_64BIT) && 13563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt inode.osd2.linux2.l_i_file_acl_high != 0) { 13573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pctx.num = inode.osd2.linux2.l_i_file_acl_high; 13583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (fix_problem(ctx, PR_2_I_FILE_ACL_HI_ZERO, &pctx)) { 13593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt inode.osd2.linux2.l_i_file_acl_high = 0; 13603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt inode_modified++; 13613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 13623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt not_fixed++; 13633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 13643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 136519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_file_acl && 136619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((inode.i_file_acl < fs->super->s_first_data_block) || 136719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project (inode.i_file_acl >= fs->super->s_blocks_count))) { 136819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) { 136919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_file_acl = 0; 137019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 137119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 137219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 137319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 137419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_dir_acl && 137519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project LINUX_S_ISDIR(inode.i_mode)) { 137619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) { 137719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_dir_acl = 0; 137819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode_modified++; 137919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } else 138019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project not_fixed++; 138119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 138219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 138319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode_modified) 138419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode"); 138519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!not_fixed && ctx->inode_bad_map) 138619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); 138719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 138819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 138919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 139019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 139119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 139219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * allocate_dir_block --- this function allocates a new directory 139319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * block for a particular inode; this is done if a directory has 139419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * a "hole" in it, or if a directory has a illegal block number 139519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * that was zeroed out and now needs to be replaced. 139619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 139719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int allocate_dir_block(e2fsck_t ctx, 139819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_db_entry *db, 13993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *buf EXT2FS_ATTR((unused)), 140019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct problem_context *pctx) 140119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 140219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_filsys fs = ctx->fs; 140319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blk; 140419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block; 140519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 140619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 140719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0) 140819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 140919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 141019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 141119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Read the inode and block bitmaps in; we'll be messing with 141219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * them. 141319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 141419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_bitmaps(ctx); 14153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 141619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 141719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * First, find a free block 141819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 141919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); 142019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx->errcode) { 142119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->str = "ext2fs_new_block"; 142219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 142319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 142419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 142519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_block_bitmap(ctx->block_found_map, blk); 142619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_block_bitmap(fs->block_map, blk); 142719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_bb_dirty(fs); 142819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 142919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 143019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Now let's create the actual data block for the inode 143119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 143219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (db->blockcnt) 143319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block); 143419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project else 143519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->errcode = ext2fs_new_dir_block(fs, db->ino, 143619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project EXT2_ROOT_INO, &block); 143719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 143819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx->errcode) { 143919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->str = "ext2fs_new_dir_block"; 144019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 144119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 144219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 144319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 144419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->errcode = ext2fs_write_dir_block(fs, blk, block); 144519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_mem(&block); 144619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx->errcode) { 144719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->str = "ext2fs_write_dir_block"; 144819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 144919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 145019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 145119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 145219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 145319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Update the inode block count 145419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 145519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block"); 14563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_iblk_add_blocks(fs, &inode, 1); 145719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_size < (db->blockcnt+1) * fs->blocksize) 145819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project inode.i_size = (db->blockcnt+1) * fs->blocksize; 145919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block"); 146019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 146119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 146219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Finally, update the block pointers for the inode 146319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 146419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project db->blk = blk; 14653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt pctx->errcode = ext2fs_bmap(fs, db->ino, &inode, 0, BMAP_SET, 14663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt db->blockcnt, &blk); 146719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pctx->errcode) { 146819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pctx->str = "ext2fs_block_iterate"; 146919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); 147019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 1; 147119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 147219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 147319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 147419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 1475