Whamcloud - gitweb
Many files:
[tools/e2fsprogs.git] / misc / dumpe2fs.c
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)    (test_bit ((x), (m)))
36
37 const char * program_name = "dumpe2fs";
38 char * device_name = NULL;
39
40 static volatile void usage (void)
41 {
42         fprintf (stderr, "usage: %s device\n", program_name);
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;
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
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))
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
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))
149                 printf("%d\n", blk);
150         badblocks_list_iterate_end(bb_iter);
151 }
152
153
154 void main (int argc, char ** argv)
155 {
156         errcode_t       retval;
157         ext2_filsys     fs;
158         int             print_badblocks = 0;
159         char            c;
160
161         fprintf (stderr, "dumpe2fs %s, %s for EXT2 FS %s, %s\n",
162                  E2FSPROGS_VERSION, E2FSPROGS_DATE,
163                  EXT2FS_VERSION, EXT2FS_DATE);
164         if (argc && *argv)
165                 program_name = *argv;
166         
167         while ((c = getopt (argc, argv, "b")) != EOF) {
168                 switch (c) {
169                 case 'b':
170                         print_badblocks++;
171                         break;
172                 default:
173                         usage ();
174                 }
175         }
176         if (optind > argc - 1)
177                 usage ();
178         device_name = argv[optind++];
179         initialize_ext2_error_table();
180         retval = ext2fs_open (device_name, 0, 0, 0, unix_io_manager, &fs);
181         if (retval) {
182                 com_err (program_name, retval, "while trying to open %s",
183                          device_name);
184                 printf ("Couldn't find valid filesystem superblock.\n");
185                 exit (1);
186         }
187         if (print_badblocks) {
188                 dump_bad_blocks(fs);
189         } else {
190                 retval = ext2fs_read_bitmaps (fs);
191                 if (retval) {
192                         com_err (program_name, retval,
193                                  "while trying to read the bitmaps",
194                                  device_name);
195                         ext2fs_close (fs);
196                         exit (1);
197                 }
198                 list_super (fs->super);
199                 list_bad_blocks (fs);
200                 list_desc (fs);
201         }
202         ext2fs_close (fs);
203         exit (0);
204 }