blob: 069ad64411e1a2c64f145019bf84e232848a4386 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
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'oa418d3a1997-04-26 14:00:26 +000019#ifdef HAVE_GETOPT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000020#include <getopt.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000021#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000022#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'o74becf31997-04-26 14:37:06 +000035#define in_use(m, x) (ext2fs_test_bit ((x), (m)))
Theodore Ts'o3839e651997-04-26 13:21:57 +000036
37const char * program_name = "dumpe2fs";
38char * device_name = NULL;
39
40static volatile void usage (void)
41{
Theodore Ts'o5c576471997-04-29 15:29:49 +000042 fprintf (stderr, "usage: %s [-bV] device\n", program_name);
Theodore Ts'o3839e651997-04-26 13:21:57 +000043 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;
Theodore Ts'of3db3561997-04-26 13:34:30 +000076 char * block_bitmap = fs->block_map->bitmap;
77 char * inode_bitmap = fs->inode_map->bitmap;
Theodore Ts'o3839e651997-04-26 13:21:57 +000078
79 printf ("\n");
80 for (i = 0; i < fs->group_desc_count; i++)
81 {
82 printf ("Group %lu:\n", i);
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000083 printf (" Block bitmap at %u, Inode bitmap at %u, "
84 "Inode table at %u\n",
Theodore Ts'o3839e651997-04-26 13:21:57 +000085 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))
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000123 printf("Bad blocks: %d", blk);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000124 while (badblocks_list_iterate(bb_iter, &blk))
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000125 printf(", %d", blk);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000126 badblocks_list_iterate_end(bb_iter);
127 printf("\n");
128}
129
Theodore Ts'of3db3561997-04-26 13:34:30 +0000130static 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'oa418d3a1997-04-26 14:00:26 +0000149 printf("%d\n", blk);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000150 badblocks_list_iterate_end(bb_iter);
151}
152
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000153static int i386_byteorder(void)
154{
155 int one = 1;
156 char *cp = (char *) &one;
157
158 return (*cp == 1);
159}
Theodore Ts'of3db3561997-04-26 13:34:30 +0000160
Theodore Ts'o3839e651997-04-26 13:21:57 +0000161void main (int argc, char ** argv)
162{
163 errcode_t retval;
164 ext2_filsys fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000165 int print_badblocks = 0;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000166 int big_endian;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000167 char c;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000168
Theodore Ts'o5c576471997-04-29 15:29:49 +0000169 initialize_ext2_error_table();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000170 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'of3db3561997-04-26 13:34:30 +0000175
Theodore Ts'o5c576471997-04-29 15:29:49 +0000176 while ((c = getopt (argc, argv, "bV")) != EOF) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000177 switch (c) {
178 case 'b':
179 print_badblocks++;
180 break;
Theodore Ts'o5c576471997-04-29 15:29:49 +0000181 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'of3db3561997-04-26 13:34:30 +0000186 default:
187 usage ();
188 }
189 }
190 if (optind > argc - 1)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000191 usage ();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000192 device_name = argv[optind++];
Theodore Ts'o3839e651997-04-26 13:21:57 +0000193 retval = ext2fs_open (device_name, 0, 0, 0, unix_io_manager, &fs);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000194 if (retval) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000195 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'of3db3561997-04-26 13:34:30 +0000200 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'o5c576471997-04-29 15:29:49 +0000211 big_endian = ((fs->flags & EXT2_FLAG_SWAP_BYTES) != 0);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000212 if (!i386_byteorder())
213 big_endian = !big_endian;
214 if (big_endian)
215 printf("Note: This is a byte-swapped filesystem\n");
Theodore Ts'of3db3561997-04-26 13:34:30 +0000216 list_super (fs->super);
217 list_bad_blocks (fs);
218 list_desc (fs);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000219 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000220 ext2fs_close (fs);
221 exit (0);
222}