1 /* 2 * icheck.c --- given a list of blocks, generate a list of inodes 3 * 4 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed 5 * under the terms of the GNU Public License. 6 */ 7 8 #include "config.h" 9 #include <stdio.h> 10 #include <unistd.h> 11 #include <stdlib.h> 12 #include <ctype.h> 13 #include <string.h> 14 #include <time.h> 15 #ifdef HAVE_ERRNO_H 16 #include <errno.h> 17 #endif 18 #include <sys/types.h> 19 20 #include "debugfs.h" 21 22 struct block_info { 23 blk64_t blk; 24 ext2_ino_t ino; 25 }; 26 27 struct block_walk_struct { 28 struct block_info *barray; 29 e2_blkcnt_t blocks_left; 30 e2_blkcnt_t num_blocks; 31 ext2_ino_t inode; 32 }; 33 34 static int icheck_proc(ext2_filsys fs EXT2FS_ATTR((unused)), 35 blk64_t *block_nr, 36 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 37 blk64_t ref_block EXT2FS_ATTR((unused)), 38 int ref_offset EXT2FS_ATTR((unused)), 39 void *private) 40 { 41 struct block_walk_struct *bw = (struct block_walk_struct *) private; 42 e2_blkcnt_t i; 43 44 for (i=0; i < bw->num_blocks; i++) { 45 if (!bw->barray[i].ino && bw->barray[i].blk == *block_nr) { 46 bw->barray[i].ino = bw->inode; 47 bw->blocks_left--; 48 } 49 } 50 if (!bw->blocks_left) 51 return BLOCK_ABORT; 52 53 return 0; 54 } 55 56 void do_icheck(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)), 57 void *infop EXT2FS_ATTR((unused))) 58 { 59 struct block_walk_struct bw; 60 struct block_info *binfo; 61 int i; 62 ext2_inode_scan scan = 0; 63 ext2_ino_t ino; 64 struct ext2_inode inode; 65 errcode_t retval; 66 char *block_buf; 67 68 if (argc < 2) { 69 com_err(argv[0], 0, "Usage: icheck <block number> ..."); 70 return; 71 } 72 if (check_fs_open(argv[0])) 73 return; 74 75 bw.barray = malloc(sizeof(struct block_info) * argc); 76 if (!bw.barray) { 77 com_err("icheck", ENOMEM, 78 "while allocating inode info array"); 79 return; 80 } 81 memset(bw.barray, 0, sizeof(struct block_info) * argc); 82 83 block_buf = malloc(current_fs->blocksize * 3); 84 if (!block_buf) { 85 com_err("icheck", ENOMEM, "while allocating block buffer"); 86 goto error_out; 87 } 88 89 for (i=1; i < argc; i++) { 90 if (strtoblk(argv[0], argv[i], NULL, &bw.barray[i-1].blk)) 91 goto error_out; 92 } 93 94 bw.num_blocks = bw.blocks_left = argc-1; 95 96 retval = ext2fs_open_inode_scan(current_fs, 0, &scan); 97 if (retval) { 98 com_err("icheck", retval, "while opening inode scan"); 99 goto error_out; 100 } 101 102 do { 103 retval = ext2fs_get_next_inode(scan, &ino, &inode); 104 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); 105 if (retval) { 106 com_err("icheck", retval, "while starting inode scan"); 107 goto error_out; 108 } 109 110 while (ino) { 111 blk64_t blk; 112 113 if (!inode.i_links_count) 114 goto next; 115 116 bw.inode = ino; 117 118 blk = ext2fs_file_acl_block(current_fs, &inode); 119 if (blk) { 120 icheck_proc(current_fs, &blk, 0, 121 0, 0, &bw); 122 if (bw.blocks_left == 0) 123 break; 124 ext2fs_file_acl_block_set(current_fs, &inode, blk); 125 } 126 127 if (!ext2fs_inode_has_valid_blocks2(current_fs, &inode)) 128 goto next; 129 /* 130 * To handle filesystems touched by 0.3c extfs; can be 131 * removed later. 132 */ 133 if (inode.i_dtime) 134 goto next; 135 136 retval = ext2fs_block_iterate3(current_fs, ino, 137 BLOCK_FLAG_READ_ONLY, block_buf, 138 icheck_proc, &bw); 139 if (retval) { 140 com_err("icheck", retval, 141 "while calling ext2fs_block_iterate"); 142 goto next; 143 } 144 145 if (bw.blocks_left == 0) 146 break; 147 148 next: 149 do { 150 retval = ext2fs_get_next_inode(scan, &ino, &inode); 151 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); 152 if (retval) { 153 com_err("icheck", retval, 154 "while doing inode scan"); 155 goto error_out; 156 } 157 } 158 159 printf("Block\tInode number\n"); 160 for (i=0, binfo = bw.barray; i < bw.num_blocks; i++, binfo++) { 161 if (binfo->ino == 0) { 162 printf("%llu\t<block not found>\n", binfo->blk); 163 continue; 164 } 165 printf("%llu\t%u\n", binfo->blk, binfo->ino); 166 } 167 168 error_out: 169 free(bw.barray); 170 free(block_buf); 171 if (scan) 172 ext2fs_close_inode_scan(scan); 173 return; 174 } 175