dumpe2fs.c revision 1e3472c5f37ca3686dd69b079d4d02a302f5798d
1/* 2 * dumpe2fs.c - List the control structures of a second 3 * extended filesystem 4 * 5 * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr> 6 * Laboratoire MASI, Institut Blaise Pascal 7 * Universite Pierre et Marie Curie (Paris VI) 8 * 9 * This file can be redistributed under the terms of the GNU General 10 * Public License 11 */ 12 13/* 14 * History: 15 * 94/01/09 - Creation 16 * 94/02/27 - Ported to use the ext2fs library 17 */ 18 19#ifdef HAVE_GETOPT_H 20#include <getopt.h> 21#endif 22#include <fcntl.h> 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26#include <unistd.h> 27 28#include <linux/ext2_fs.h> 29 30#include "ext2fs/ext2fs.h" 31#include "e2p/e2p.h" 32 33#include "../version.h" 34 35#define in_use(m, x) (ext2fs_test_bit ((x), (m))) 36 37const char * program_name = "dumpe2fs"; 38char * device_name = NULL; 39 40static volatile void usage (void) 41{ 42 fprintf (stderr, "usage: %s device\n", program_name); 43 exit (1); 44} 45 46static void print_free (unsigned long group, char * bitmap, 47 unsigned long nbytes, unsigned long offset) 48{ 49 int p = 0; 50 unsigned long i; 51 unsigned long j; 52 53 for (i = 0; i < nbytes; i++) 54 if (!in_use (bitmap, i)) 55 { 56 if (p) 57 printf (", "); 58 if (i == nbytes - 1 || in_use (bitmap, i + 1)) 59 printf ("%lu", group * nbytes + i + offset); 60 else 61 { 62 for (j = i; j < nbytes && !in_use (bitmap, j); 63 j++) 64 ; 65 printf ("%lu-%lu", group * nbytes + i + offset, 66 group * nbytes + (j - 1) + offset); 67 i = j - 1; 68 } 69 p = 1; 70 } 71} 72 73static void list_desc (ext2_filsys fs) 74{ 75 unsigned long i; 76 char * block_bitmap = fs->block_map->bitmap; 77 char * inode_bitmap = fs->inode_map->bitmap; 78 79 printf ("\n"); 80 for (i = 0; i < fs->group_desc_count; i++) 81 { 82 printf ("Group %lu:\n", i); 83 printf (" Block bitmap at %u, Inode bitmap at %u, " 84 "Inode table at %u\n", 85 fs->group_desc[i].bg_block_bitmap, 86 fs->group_desc[i].bg_inode_bitmap, 87 fs->group_desc[i].bg_inode_table); 88 printf (" %d free blocks, %d free inodes, %d directories\n", 89 fs->group_desc[i].bg_free_blocks_count, 90 fs->group_desc[i].bg_free_inodes_count, 91 fs->group_desc[i].bg_used_dirs_count); 92 printf (" Free blocks: "); 93 print_free (i, block_bitmap, fs->super->s_blocks_per_group, 94 fs->super->s_first_data_block); 95 block_bitmap += fs->super->s_blocks_per_group / 8; 96 printf ("\n"); 97 printf (" Free inodes: "); 98 print_free (i, inode_bitmap, fs->super->s_inodes_per_group, 1); 99 inode_bitmap += fs->super->s_inodes_per_group / 8; 100 printf ("\n"); 101 } 102} 103 104static void list_bad_blocks(ext2_filsys fs) 105{ 106 badblocks_list bb_list = 0; 107 badblocks_iterate bb_iter; 108 blk_t blk; 109 errcode_t retval; 110 111 retval = ext2fs_read_bb_inode(fs, &bb_list); 112 if (retval) { 113 com_err("ext2fs_read_bb_inode", retval, ""); 114 exit(1); 115 } 116 retval = badblocks_list_iterate_begin(bb_list, &bb_iter); 117 if (retval) { 118 com_err("badblocks_list_iterate_begin", retval, 119 "while printing bad block list"); 120 exit(1); 121 } 122 if (badblocks_list_iterate(bb_iter, &blk)) 123 printf("Bad blocks: %d", blk); 124 while (badblocks_list_iterate(bb_iter, &blk)) 125 printf(", %d", blk); 126 badblocks_list_iterate_end(bb_iter); 127 printf("\n"); 128} 129 130static void dump_bad_blocks(ext2_filsys fs) 131{ 132 badblocks_list bb_list = 0; 133 badblocks_iterate bb_iter; 134 blk_t blk; 135 errcode_t retval; 136 137 retval = ext2fs_read_bb_inode(fs, &bb_list); 138 if (retval) { 139 com_err("ext2fs_read_bb_inode", retval, ""); 140 exit(1); 141 } 142 retval = badblocks_list_iterate_begin(bb_list, &bb_iter); 143 if (retval) { 144 com_err("badblocks_list_iterate_begin", retval, 145 "while printing bad block list"); 146 exit(1); 147 } 148 while (badblocks_list_iterate(bb_iter, &blk)) 149 printf("%d\n", blk); 150 badblocks_list_iterate_end(bb_iter); 151} 152 153static int i386_byteorder(void) 154{ 155 int one = 1; 156 char *cp = (char *) &one; 157 158 return (*cp == 1); 159} 160 161void main (int argc, char ** argv) 162{ 163 errcode_t retval; 164 ext2_filsys fs; 165 int print_badblocks = 0; 166 int big_endian; 167 char c; 168 169 fprintf (stderr, "dumpe2fs %s, %s for EXT2 FS %s, %s\n", 170 E2FSPROGS_VERSION, E2FSPROGS_DATE, 171 EXT2FS_VERSION, EXT2FS_DATE); 172 if (argc && *argv) 173 program_name = *argv; 174 175 while ((c = getopt (argc, argv, "b")) != EOF) { 176 switch (c) { 177 case 'b': 178 print_badblocks++; 179 break; 180 default: 181 usage (); 182 } 183 } 184 if (optind > argc - 1) 185 usage (); 186 device_name = argv[optind++]; 187 initialize_ext2_error_table(); 188 retval = ext2fs_open (device_name, 0, 0, 0, unix_io_manager, &fs); 189 if (retval) { 190 com_err (program_name, retval, "while trying to open %s", 191 device_name); 192 printf ("Couldn't find valid filesystem superblock.\n"); 193 exit (1); 194 } 195 if (print_badblocks) { 196 dump_bad_blocks(fs); 197 } else { 198 retval = ext2fs_read_bitmaps (fs); 199 if (retval) { 200 com_err (program_name, retval, 201 "while trying to read the bitmaps", 202 device_name); 203 ext2fs_close (fs); 204 exit (1); 205 } 206 big_endian = ((fs->flags & EXT2_SWAP_BYTES) != 0); 207 if (!i386_byteorder()) 208 big_endian = !big_endian; 209 if (big_endian) 210 printf("Note: This is a byte-swapped filesystem\n"); 211 list_super (fs->super); 212 list_bad_blocks (fs); 213 list_desc (fs); 214 } 215 ext2fs_close (fs); 216 exit (0); 217} 218