blob: b71900e76f1b0eed66d9f9d69b322abdaeed17b9 [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 *
Theodore Ts'o19c78dc1997-04-29 16:17:09 +00009 * 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'o3839e651997-04-26 13:21:57 +000015 */
16
17/*
18 * History:
19 * 94/01/09 - Creation
20 * 94/02/27 - Ported to use the ext2fs library
21 */
22
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000023#ifdef HAVE_GETOPT_H
Theodore Ts'o3839e651997-04-26 13:21:57 +000024#include <getopt.h>
Theodore Ts'oa418d3a1997-04-26 14:00:26 +000025#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000026#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'o74becf31997-04-26 14:37:06 +000039#define in_use(m, x) (ext2fs_test_bit ((x), (m)))
Theodore Ts'o3839e651997-04-26 13:21:57 +000040
41const char * program_name = "dumpe2fs";
42char * device_name = NULL;
43
44static volatile void usage (void)
45{
Theodore Ts'o5c576471997-04-29 15:29:49 +000046 fprintf (stderr, "usage: %s [-bV] device\n", program_name);
Theodore Ts'o3839e651997-04-26 13:21:57 +000047 exit (1);
48}
49
50static 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
77static void list_desc (ext2_filsys fs)
78{
79 unsigned long i;
Theodore Ts'o521e3681997-04-29 17:48:10 +000080 blk_t group_blk, next_blk;
Theodore Ts'of3db3561997-04-26 13:34:30 +000081 char * block_bitmap = fs->block_map->bitmap;
82 char * inode_bitmap = fs->inode_map->bitmap;
Theodore Ts'o3839e651997-04-26 13:21:57 +000083
84 printf ("\n");
Theodore Ts'o521e3681997-04-29 17:48:10 +000085 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'o3839e651997-04-26 13:21:57 +000095 fs->group_desc[i].bg_block_bitmap,
Theodore Ts'o521e3681997-04-29 17:48:10 +000096 fs->group_desc[i].bg_block_bitmap - group_blk,
Theodore Ts'o3839e651997-04-26 13:21:57 +000097 fs->group_desc[i].bg_inode_bitmap,
Theodore Ts'o521e3681997-04-29 17:48:10 +000098 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'o3839e651997-04-26 13:21:57 +0000101 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'o521e3681997-04-29 17:48:10 +0000114 group_blk = next_blk;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000115 }
116}
117
118static 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'oa418d3a1997-04-26 14:00:26 +0000137 printf("Bad blocks: %d", blk);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000138 while (badblocks_list_iterate(bb_iter, &blk))
Theodore Ts'oa418d3a1997-04-26 14:00:26 +0000139 printf(", %d", blk);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000140 badblocks_list_iterate_end(bb_iter);
141 printf("\n");
142}
143
Theodore Ts'of3db3561997-04-26 13:34:30 +0000144static 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'oa418d3a1997-04-26 14:00:26 +0000163 printf("%d\n", blk);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000164 badblocks_list_iterate_end(bb_iter);
165}
166
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000167static int i386_byteorder(void)
168{
169 int one = 1;
170 char *cp = (char *) &one;
171
172 return (*cp == 1);
173}
Theodore Ts'of3db3561997-04-26 13:34:30 +0000174
Theodore Ts'o3839e651997-04-26 13:21:57 +0000175void main (int argc, char ** argv)
176{
177 errcode_t retval;
178 ext2_filsys fs;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000179 int print_badblocks = 0;
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000180 int big_endian;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000181 char c;
Theodore Ts'o3839e651997-04-26 13:21:57 +0000182
Theodore Ts'o5c576471997-04-29 15:29:49 +0000183 initialize_ext2_error_table();
Theodore Ts'o3839e651997-04-26 13:21:57 +0000184 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'of3db3561997-04-26 13:34:30 +0000189
Theodore Ts'o5c576471997-04-29 15:29:49 +0000190 while ((c = getopt (argc, argv, "bV")) != EOF) {
Theodore Ts'of3db3561997-04-26 13:34:30 +0000191 switch (c) {
192 case 'b':
193 print_badblocks++;
194 break;
Theodore Ts'o5c576471997-04-29 15:29:49 +0000195 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'of3db3561997-04-26 13:34:30 +0000200 default:
201 usage ();
202 }
203 }
204 if (optind > argc - 1)
Theodore Ts'o3839e651997-04-26 13:21:57 +0000205 usage ();
Theodore Ts'of3db3561997-04-26 13:34:30 +0000206 device_name = argv[optind++];
Theodore Ts'o3839e651997-04-26 13:21:57 +0000207 retval = ext2fs_open (device_name, 0, 0, 0, unix_io_manager, &fs);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000208 if (retval) {
Theodore Ts'o3839e651997-04-26 13:21:57 +0000209 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'of3db3561997-04-26 13:34:30 +0000214 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'o5c576471997-04-29 15:29:49 +0000225 big_endian = ((fs->flags & EXT2_FLAG_SWAP_BYTES) != 0);
Theodore Ts'o1e3472c1997-04-29 14:53:37 +0000226 if (!i386_byteorder())
227 big_endian = !big_endian;
228 if (big_endian)
229 printf("Note: This is a byte-swapped filesystem\n");
Theodore Ts'of3db3561997-04-26 13:34:30 +0000230 list_super (fs->super);
231 list_bad_blocks (fs);
232 list_desc (fs);
Theodore Ts'o3839e651997-04-26 13:21:57 +0000233 }
Theodore Ts'o3839e651997-04-26 13:21:57 +0000234 ext2fs_close (fs);
235 exit (0);
236}