119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * icheck.c --- given a list of blocks, generate a list of inodes 33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * under the terms of the GNU Public License. 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h> 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h> 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <time.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h> 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h> 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "debugfs.h" 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct block_info { 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t blk; 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino; 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct block_walk_struct { 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct block_info *barray; 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t blocks_left; 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t num_blocks; 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t inode; 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int icheck_proc(ext2_filsys fs EXT2FS_ATTR((unused)), 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t *block_nr, 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t ref_block EXT2FS_ATTR((unused)), 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ref_offset EXT2FS_ATTR((unused)), 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *private) 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct block_walk_struct *bw = (struct block_walk_struct *) private; 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t i; 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0; i < bw->num_blocks; i++) { 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!bw->barray[i].ino && bw->barray[i].blk == *block_nr) { 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bw->barray[i].ino = bw->inode; 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bw->blocks_left--; 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!bw->blocks_left) 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid do_icheck(int argc, char **argv) 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct block_walk_struct bw; 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct block_info *binfo; 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int i; 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_inode_scan scan = 0; 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino; 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block_buf; 653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (argc < 2) { 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err(argv[0], 0, "Usage: icheck <block number> ..."); 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (check_fs_open(argv[0])) 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bw.barray = malloc(sizeof(struct block_info) * argc); 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!bw.barray) { 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("icheck", ENOMEM, 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "while allocating inode info array"); 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project memset(bw.barray, 0, sizeof(struct block_info) * argc); 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block_buf = malloc(current_fs->blocksize * 3); 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!block_buf) { 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("icheck", ENOMEM, "while allocating block buffer"); 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto error_out; 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=1; i < argc; i++) { 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (strtoblk(argv[0], argv[i], &bw.barray[i-1].blk)) 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto error_out; 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bw.num_blocks = bw.blocks_left = argc-1; 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_open_inode_scan(current_fs, 0, &scan); 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("icheck", retval, "while opening inode scan"); 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto error_out; 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_next_inode(scan, &ino, &inode); 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("icheck", retval, "while starting inode scan"); 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto error_out; 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 1073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (ino) { 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!inode.i_links_count) 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project bw.inode = ino; 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_file_acl) { 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project icheck_proc(current_fs, &inode.i_file_acl, 0, 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 0, 0, &bw); 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bw.blocks_left == 0) 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (!ext2fs_inode_has_valid_blocks(&inode)) 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * To handle filesystems touched by 0.3c extfs; can be 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * removed later. 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (inode.i_dtime) 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_block_iterate2(current_fs, ino, 1313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt BLOCK_FLAG_READ_ONLY, block_buf, 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project icheck_proc, &bw); 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("icheck", retval, 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "while calling ext2fs_block_iterate"); 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (bw.blocks_left == 0) 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project break; 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project next: 14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_next_inode(scan, &ino, &inode); 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project com_err("icheck", retval, 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project "while doing inode scan"); 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto error_out; 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("Block\tInode number\n"); 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project for (i=0, binfo = bw.barray; i < bw.num_blocks; i++, binfo++) { 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (binfo->ino == 0) { 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("%u\t<block not found>\n", binfo->blk); 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project continue; 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("%u\t%u\n", binfo->blk, binfo->ino); 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterror_out: 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project free(bw.barray); 1643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(block_buf); 16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (scan) 16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_close_inode_scan(scan); 16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return; 16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 169