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 | * |
| 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 | |
Theodore Ts'o | a418d3a | 1997-04-26 14:00:26 +0000 | [diff] [blame] | 19 | #ifdef HAVE_GETOPT_H |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 20 | #include <getopt.h> |
Theodore Ts'o | a418d3a | 1997-04-26 14:00:26 +0000 | [diff] [blame] | 21 | #endif |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 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 | |
Theodore Ts'o | 74becf3 | 1997-04-26 14:37:06 +0000 | [diff] [blame] | 35 | #define in_use(m, x) (ext2fs_test_bit ((x), (m))) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 36 | |
| 37 | const char * program_name = "dumpe2fs"; |
| 38 | char * device_name = NULL; |
| 39 | |
| 40 | static volatile void usage (void) |
| 41 | { |
Theodore Ts'o | 5c57647 | 1997-04-29 15:29:49 +0000 | [diff] [blame^] | 42 | fprintf (stderr, "usage: %s [-bV] device\n", program_name); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 43 | exit (1); |
| 44 | } |
| 45 | |
| 46 | static 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 | |
| 73 | static void list_desc (ext2_filsys fs) |
| 74 | { |
| 75 | unsigned long i; |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 76 | char * block_bitmap = fs->block_map->bitmap; |
| 77 | char * inode_bitmap = fs->inode_map->bitmap; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 78 | |
| 79 | printf ("\n"); |
| 80 | for (i = 0; i < fs->group_desc_count; i++) |
| 81 | { |
| 82 | printf ("Group %lu:\n", i); |
Theodore Ts'o | a418d3a | 1997-04-26 14:00:26 +0000 | [diff] [blame] | 83 | printf (" Block bitmap at %u, Inode bitmap at %u, " |
| 84 | "Inode table at %u\n", |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 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 | |
| 104 | static 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)) |
Theodore Ts'o | a418d3a | 1997-04-26 14:00:26 +0000 | [diff] [blame] | 123 | printf("Bad blocks: %d", blk); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 124 | while (badblocks_list_iterate(bb_iter, &blk)) |
Theodore Ts'o | a418d3a | 1997-04-26 14:00:26 +0000 | [diff] [blame] | 125 | printf(", %d", blk); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 126 | badblocks_list_iterate_end(bb_iter); |
| 127 | printf("\n"); |
| 128 | } |
| 129 | |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 130 | static 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)) |
Theodore Ts'o | a418d3a | 1997-04-26 14:00:26 +0000 | [diff] [blame] | 149 | printf("%d\n", blk); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 150 | badblocks_list_iterate_end(bb_iter); |
| 151 | } |
| 152 | |
Theodore Ts'o | 1e3472c | 1997-04-29 14:53:37 +0000 | [diff] [blame] | 153 | static int i386_byteorder(void) |
| 154 | { |
| 155 | int one = 1; |
| 156 | char *cp = (char *) &one; |
| 157 | |
| 158 | return (*cp == 1); |
| 159 | } |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 160 | |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 161 | void main (int argc, char ** argv) |
| 162 | { |
| 163 | errcode_t retval; |
| 164 | ext2_filsys fs; |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 165 | int print_badblocks = 0; |
Theodore Ts'o | 1e3472c | 1997-04-29 14:53:37 +0000 | [diff] [blame] | 166 | int big_endian; |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 167 | char c; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 168 | |
Theodore Ts'o | 5c57647 | 1997-04-29 15:29:49 +0000 | [diff] [blame^] | 169 | initialize_ext2_error_table(); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 170 | fprintf (stderr, "dumpe2fs %s, %s for EXT2 FS %s, %s\n", |
| 171 | E2FSPROGS_VERSION, E2FSPROGS_DATE, |
| 172 | EXT2FS_VERSION, EXT2FS_DATE); |
| 173 | if (argc && *argv) |
| 174 | program_name = *argv; |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 175 | |
Theodore Ts'o | 5c57647 | 1997-04-29 15:29:49 +0000 | [diff] [blame^] | 176 | while ((c = getopt (argc, argv, "bV")) != EOF) { |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 177 | switch (c) { |
| 178 | case 'b': |
| 179 | print_badblocks++; |
| 180 | break; |
Theodore Ts'o | 5c57647 | 1997-04-29 15:29:49 +0000 | [diff] [blame^] | 181 | case 'V': |
| 182 | /* Print version number and exit */ |
| 183 | fprintf(stderr, "\tUsing %s\n", |
| 184 | error_message(EXT2_ET_BASE)); |
| 185 | exit(0); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 186 | default: |
| 187 | usage (); |
| 188 | } |
| 189 | } |
| 190 | if (optind > argc - 1) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 191 | usage (); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 192 | device_name = argv[optind++]; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 193 | 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] | 194 | if (retval) { |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 195 | com_err (program_name, retval, "while trying to open %s", |
| 196 | device_name); |
| 197 | printf ("Couldn't find valid filesystem superblock.\n"); |
| 198 | exit (1); |
| 199 | } |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 200 | if (print_badblocks) { |
| 201 | dump_bad_blocks(fs); |
| 202 | } else { |
| 203 | retval = ext2fs_read_bitmaps (fs); |
| 204 | if (retval) { |
| 205 | com_err (program_name, retval, |
| 206 | "while trying to read the bitmaps", |
| 207 | device_name); |
| 208 | ext2fs_close (fs); |
| 209 | exit (1); |
| 210 | } |
Theodore Ts'o | 5c57647 | 1997-04-29 15:29:49 +0000 | [diff] [blame^] | 211 | big_endian = ((fs->flags & EXT2_FLAG_SWAP_BYTES) != 0); |
Theodore Ts'o | 1e3472c | 1997-04-29 14:53:37 +0000 | [diff] [blame] | 212 | if (!i386_byteorder()) |
| 213 | big_endian = !big_endian; |
| 214 | if (big_endian) |
| 215 | printf("Note: This is a byte-swapped filesystem\n"); |
Theodore Ts'o | f3db356 | 1997-04-26 13:34:30 +0000 | [diff] [blame] | 216 | list_super (fs->super); |
| 217 | list_bad_blocks (fs); |
| 218 | list_desc (fs); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 219 | } |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 220 | ext2fs_close (fs); |
| 221 | exit (0); |
| 222 | } |