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