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