logdump.c revision a435ec3449694a8fa299337197cc09624960a3a6
1da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o/*
2da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * logdump.c --- dump the contents of the journal out to a file
3da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o *
4da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * Authro: Stephen C. Tweedie, 2001  <sct@redhat.com>
5da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * Copyright (C) 2001 Red Hat, Inc.
6da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * Based on portions  Copyright (C) 1994 Theodore Ts'o.
7da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o *
8da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * This file may be redistributed under the terms of the GNU Public
9da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * License.
10da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o */
11da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
12da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <stdio.h>
13da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <unistd.h>
14da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <stdlib.h>
15da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <ctype.h>
16da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <string.h>
17da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <time.h>
18da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#ifdef HAVE_ERRNO_H
19da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <errno.h>
20da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#endif
21da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <sys/types.h>
22da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <sys/stat.h>
23da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <fcntl.h>
24da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <utime.h>
25da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#ifdef HAVE_GETOPT_H
26da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include <getopt.h>
27da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#else
28da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oextern int optind;
29da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oextern char *optarg;
30da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#endif
31da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
32da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include "debugfs.h"
33f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o#include "blkid/blkid.h"
34da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include "jfs_user.h"
354ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o#include <uuid/uuid.h>
36da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
37da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oenum journal_location {JOURNAL_IS_INTERNAL, JOURNAL_IS_EXTERNAL};
38da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
39da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oint		dump_all, dump_contents, dump_descriptors;
40da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ounsigned int	block_to_dump, group_to_dump, bitmap_to_dump;
41da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ounsigned int	inode_block_to_dump, inode_offset_to_dump, bitmap_to_dump;
42da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oext2_ino_t	inode_to_dump;
43da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
44da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostruct journal_source
45da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
46da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	enum journal_location where;
47da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int fd;
48da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	ext2_file_t file;
49da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o};
50da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
51da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_journal(char *, FILE *, struct journal_source *);
52da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
53da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_descriptor_block(FILE *, struct journal_source *,
54da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  char *, journal_superblock_t *,
55da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  unsigned int *, int, tid_t);
56da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
57da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_revoke_block(FILE *, char *, journal_superblock_t *,
58da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  unsigned int, int, tid_t);
59da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
60da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_metadata_block(FILE *, struct journal_source *,
61da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				journal_superblock_t*,
62da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				unsigned int, unsigned int, int, tid_t);
63da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
64da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void do_hexdump (FILE *, char *, int);
65da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
66da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#define WRAP(jsb, blocknr)					\
67da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (blocknr >= be32_to_cpu((jsb)->s_maxlen))		\
68da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		blocknr -= (be32_to_cpu((jsb)->s_maxlen) -	\
69da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			    be32_to_cpu((jsb)->s_first));
70da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
71da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
72da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ovoid do_logdump(int argc, char **argv)
73da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
74da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int		c;
75da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int		retval;
76da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char		*out_fn;
77da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	FILE		*out_file;
78da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
79da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char		*inode_spec = NULL;
80da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char		*journal_fn = NULL;
81da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int		journal_fd = 0;
82a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o	int		use_sb = 0;
83da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	ext2_ino_t	journal_inum;
84da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	struct ext2_inode journal_inode;
85da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	ext2_file_t 	journal_file;
86da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char		*tmp;
87da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	const char	*logdump_usage = ("Usage: logdump "
88da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					  "[-ac] [-b<block>] [-i<inode>] "
89da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					  "[-f<journal_file>] [output_file]");
905e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	struct journal_source journal_source;
91f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o	struct ext2_super_block *es = NULL;
92f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o
935e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	journal_source.where = 0;
945e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	journal_source.fd = 0;
955e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	journal_source.file = 0;
96da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	dump_all = 0;
97da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	dump_contents = 0;
98da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	dump_descriptors = 1;
99da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	block_to_dump = -1;
100da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	bitmap_to_dump = -1;
101da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	inode_block_to_dump = -1;
102da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	inode_to_dump = -1;
103da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
10488494bb6d440f703db98b6cc4452f63d7aa392b9Theodore Ts'o	reset_getopt();
105a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o	while ((c = getopt (argc, argv, "ab:ci:f:s")) != EOF) {
106da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		switch (c) {
107da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case 'a':
108da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			dump_all++;
109da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			break;
110da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case 'b':
111da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			block_to_dump = strtoul(optarg, &tmp, 0);
112da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			if (*tmp) {
113da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				com_err(argv[0], 0,
114da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					"Bad block number - %s", optarg);
115da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				return;
116da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			}
117da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			dump_descriptors = 0;
118da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			break;
119da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case 'c':
120da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			dump_contents++;
121da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			break;
122da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case 'f':
123da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			journal_fn = optarg;
124da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			break;
125da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case 'i':
126da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			inode_spec = optarg;
127da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			dump_descriptors = 0;
128da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			break;
129a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o		case 's':
130a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			use_sb++;
131a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			break;
132da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		default:
133da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			com_err(argv[0], 0, logdump_usage);
134da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
135da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
136da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
137da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (optind != argc && optind != argc-1) {
138da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		com_err(argv[0], 0, logdump_usage);
139da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return;
140da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
141da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
142f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o	if (current_fs)
143f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		es = current_fs->super;
144f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o
145da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (inode_spec) {
146da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		int inode_group, group_offset, inodes_per_block;
147f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o
148da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (check_fs_open(argv[0]))
149da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
150da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
151da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		inode_to_dump = string_to_inode(inode_spec);
152da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (!inode_to_dump)
153da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
154da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
155da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		inode_group = ((inode_to_dump - 1)
156f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o			       / es->s_inodes_per_group);
157da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		group_offset = ((inode_to_dump - 1)
158f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o				% es->s_inodes_per_group);
159da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		inodes_per_block = (current_fs->blocksize
160da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				    / sizeof(struct ext2_inode));
161da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
162da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		inode_block_to_dump =
163da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			current_fs->group_desc[inode_group].bg_inode_table +
164da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			(group_offset / inodes_per_block);
165da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		inode_offset_to_dump = ((group_offset % inodes_per_block)
166da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					* sizeof(struct ext2_inode));
167da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		printf("Inode %u is at group %u, block %u, offset %u\n",
168da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		       inode_to_dump, inode_group,
169da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		       inode_block_to_dump, inode_offset_to_dump);
170da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
171da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
172da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (optind == argc) {
173da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		out_file = stdout;
174da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	} else {
175da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		out_fn = argv[optind];
176da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		out_file = fopen(out_fn, "w");
177da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (!out_file < 0) {
178da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			com_err(argv[0], errno, "while opening %s for logdump",
179da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				out_fn);
180da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
181da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
182da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
183da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
184da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (block_to_dump != -1 && current_fs != NULL) {
185da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		group_to_dump = ((block_to_dump -
186f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o				  es->s_first_data_block)
187f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o				 / es->s_blocks_per_group);
188da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		bitmap_to_dump = current_fs->group_desc[group_to_dump].bg_block_bitmap;
189da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
190da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
1915faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	if (!journal_fn && check_fs_open(argv[0]))
1925faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		return;
1935faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o
1945faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	if (journal_fn) {
195da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		/* Set up to read journal from a regular file somewhere */
196da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		journal_fd = open(journal_fn, O_RDONLY, 0);
197da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (journal_fd < 0) {
198da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			com_err(argv[0], errno, "while opening %s for logdump",
199da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				journal_fn);
200da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
201da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
202da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
203da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		journal_source.where = JOURNAL_IS_EXTERNAL;
204da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		journal_source.fd = journal_fd;
205f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o	} else if ((journal_inum = es->s_journal_inum)) {
206a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o		if (use_sb) {
207a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			if (es->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS) {
208a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o				com_err(argv[0], 0,
209a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o					"no journal backup in super block\n");
210a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o				return;
211a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			}
212a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			memset(&journal_inode, 0, sizeof(struct ext2_inode));
213a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			memcpy(&journal_inode.i_block[0], es->s_jnl_blocks,
214a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			       EXT2_N_BLOCKS*4);
215a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			journal_inode.i_size = es->s_jnl_blocks[16];
216a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			journal_inode.i_links_count = 1;
217a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			journal_inode.i_mode = LINUX_S_IFREG | 0600;
218a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o		} else {
219a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o			if (debugfs_read_inode(journal_inum, &journal_inode,
220a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o					       argv[0]))
221a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o				return;
222a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o		}
223a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o
224a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o		retval = ext2fs_file_open2(current_fs, journal_inum,
225a435ec3449694a8fa299337197cc09624960a3a6Theodore Ts'o					   &journal_inode, 0, &journal_file);
226da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (retval) {
227da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			com_err(argv[0], retval, "while opening ext2 file");
228da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
229da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
230da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		journal_source.where = JOURNAL_IS_INTERNAL;
231da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		journal_source.file = journal_file;
232f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o	} else {
233f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		char uuid[37];
234f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o
235f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		uuid_unparse(es->s_journal_uuid, uuid);
236f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		journal_fn = blkid_get_devname(NULL, "UUID", uuid);
237f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		if (!journal_fn)
238f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o				journal_fn = blkid_devno_to_devname(es->s_journal_dev);
239f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		if (!journal_fn) {
240f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o			com_err(argv[0], 0, "filesystem has no journal");
241f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o			return;
242f364093b1956def0b0f1d037852cbb645284d5f2Theodore Ts'o		}
2435faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		journal_fd = open(journal_fn, O_RDONLY, 0);
2445faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		if (journal_fd < 0) {
2455faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			com_err(argv[0], errno, "while opening %s for logdump",
2465faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o				journal_fn);
2475faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			free(journal_fn);
2485faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			return;
2495faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		}
2505faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		fprintf(out_file, "Using external journal found at %s\n",
2515faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			journal_fn);
2525faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		free(journal_fn);
2535faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		journal_source.where = JOURNAL_IS_EXTERNAL;
2545faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		journal_source.fd = journal_fd;
255da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
256da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
257da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	dump_journal(argv[0], out_file, &journal_source);
258da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
259da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (journal_source.where == JOURNAL_IS_INTERNAL)
260da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		ext2fs_file_close(journal_file);
261da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else
262da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		close(journal_fd);
263da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
264da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (out_file != stdout)
265da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fclose(out_file);
266da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
267da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	return;
268da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
269da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
270da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
2715e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'ostatic int read_journal_block(const char *cmd, struct journal_source *source,
2725e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o			      off_t offset, char *buf, int size,
2735e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o			      unsigned int *got)
274da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
275da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int retval;
276da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
277da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (source->where == JOURNAL_IS_EXTERNAL) {
2784bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o		if (lseek(source->fd, offset, SEEK_SET) < 0) {
2794bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o			retval = errno;
2804bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o			com_err(cmd, retval, "while seeking in reading journal");
2814bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o			return retval;
2824bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o		}
2834bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o		retval = read(source->fd, buf, size);
284da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (retval >= 0) {
285da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			*got = retval;
286da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			retval = 0;
2875faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		} else
2885faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			retval = errno;
289da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	} else {
290da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		retval = ext2fs_file_lseek(source->file, offset,
291da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					   EXT2_SEEK_SET, NULL);
292da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (retval) {
293da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			com_err(cmd, retval, "while seeking in reading journal");
294da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return retval;
295da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
296da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
297da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		retval = ext2fs_file_read(source->file, buf, size, got);
298da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
299da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
300da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (retval)
301da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		com_err(cmd, retval, "while while reading journal");
302da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	else if (*got != size) {
303da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		com_err(cmd, 0, "short read (read %d, expected %d) while while reading journal", *got, size);
304da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		retval = -1;
305da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
306da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
307da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	return retval;
308da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
309da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
3105e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'ostatic const char *type_to_name(int btype)
311da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
312da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	switch (btype) {
313da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	case JFS_DESCRIPTOR_BLOCK:
314da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return "descriptor block";
315da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	case JFS_COMMIT_BLOCK:
316da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return "commit block";
317da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	case JFS_SUPERBLOCK_V1:
318da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return "V1 superblock";
319da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	case JFS_SUPERBLOCK_V2:
320da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return "V2 superblock";
321da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	case JFS_REVOKE_BLOCK:
322da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return "revoke table";
323da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
324da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	return "unrecognised type";
325da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
326da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
327da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
328da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_journal(char *cmdname, FILE *out_file,
329da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			 struct journal_source *source)
330da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
3315faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	struct ext2_super_block *sb;
332da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char			jsb_buffer[1024];
333da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char			buf[8192];
334da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	journal_superblock_t	*jsb;
3355faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	int			blocksize = 1024;
3365e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	unsigned int		got;
337da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int			retval;
338da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	__u32			magic, sequence, blocktype;
339da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	journal_header_t	*header;
340da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
341da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	tid_t			transaction;
3425faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	unsigned int		blocknr = 0;
343da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
3445faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	/* First, check to see if there's an ext2 superblock header */
345da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	retval = read_journal_block(cmdname, source, 0,
3465faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o				    buf, 2048, &got);
347da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (retval)
348da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return;
3495faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o
3505faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	jsb = (journal_superblock_t *) buf;
3515faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	sb = (struct ext2_super_block *) (buf+1024);
352ff63f2686f859418b7248029a967f9f7280109dcStephen Tweedie#ifdef ENABLE_SWAPFS
3535faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
3545faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		ext2fs_swap_super(sb);
355ff63f2686f859418b7248029a967f9f7280109dcStephen Tweedie#endif
356da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
3575faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	if ((be32_to_cpu(jsb->s_header.h_magic) != JFS_MAGIC_NUMBER) &&
3585faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	    (sb->s_magic == EXT2_SUPER_MAGIC) &&
3595faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	    (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
3605faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		blocksize = EXT2_BLOCK_SIZE(sb);
3615faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		blocknr = (blocksize == 1024) ? 2 : 1;
3624ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o		uuid_unparse(sb->s_uuid, jsb_buffer);
3635faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		fprintf(out_file, "Ext2 superblock header found.\n");
3645faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		if (dump_all) {
3655faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			fprintf(out_file, "\tuuid=%s\n", jsb_buffer);
3665faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			fprintf(out_file, "\tblocksize=%d\n", blocksize);
3675faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			fprintf(out_file, "\tjournal data size %ld\n",
3684ea7bd04390935e1f8b473c8b857e518df2e226bTheodore Ts'o				(long) sb->s_blocks_count);
3695faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		}
3705faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	}
3715faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o
3725faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	/* Next, read the journal superblock */
3735faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o
3745faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	retval = read_journal_block(cmdname, source, blocknr*blocksize,
3755faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o				    jsb_buffer, 1024, &got);
3765faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	if (retval)
3775faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		return;
3785faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o
379da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	jsb = (journal_superblock_t *) jsb_buffer;
3805faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	if (be32_to_cpu(jsb->s_header.h_magic) != JFS_MAGIC_NUMBER) {
3815faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		fprintf(out_file,
3825faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o			"Journal superblock magic number invalid!\n");
3835faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o		return;
3845faba3acba0552b1dbae71418e8a002ccae1ae70Theodore Ts'o	}
385da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	blocksize = be32_to_cpu(jsb->s_blocksize);
386da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	transaction = be32_to_cpu(jsb->s_sequence);
387da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	blocknr = be32_to_cpu(jsb->s_start);
388da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
389da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	fprintf(out_file, "Journal starts at block %u, transaction %u\n",
390da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		blocknr, transaction);
391da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
392da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (!blocknr)
393da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		/* Empty journal, nothing to do. */
394da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return;
395da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
396da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	while (1) {
397da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		retval = read_journal_block(cmdname, source,
398da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					    blocknr*blocksize, buf,
399da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					    blocksize, &got);
400da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (retval || got != blocksize)
401da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
402da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
403da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		header = (journal_header_t *) buf;
404da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
405da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		magic = be32_to_cpu(header->h_magic);
406da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		sequence = be32_to_cpu(header->h_sequence);
407da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		blocktype = be32_to_cpu(header->h_blocktype);
408da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
409da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (magic != JFS_MAGIC_NUMBER) {
410da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf (out_file, "No magic number at block %u: "
411da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 "end of journal.\n", blocknr);
412da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
413da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
414da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
415da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (sequence != transaction) {
416da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf (out_file, "Found sequence %u (not %u) at "
417da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 "block %u: end of journal.\n",
418da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 sequence, transaction, blocknr);
419da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
420da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
421da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
422da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (dump_descriptors) {
423da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf (out_file, "Found expected sequence %u, "
424da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 "type %u (%s) at block %u\n",
425da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 sequence, blocktype,
426da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 type_to_name(blocktype), blocknr);
427da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
428da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
429da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		switch (blocktype) {
430da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case JFS_DESCRIPTOR_BLOCK:
431da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			dump_descriptor_block(out_file, source, buf, jsb,
432da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					      &blocknr, blocksize,
433da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					      transaction);
434da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			continue;
435da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
436da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case JFS_COMMIT_BLOCK:
437da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			transaction++;
438da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			blocknr++;
439da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			WRAP(jsb, blocknr);
440da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			continue;
441da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
442da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		case JFS_REVOKE_BLOCK:
443da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			dump_revoke_block(out_file, buf, jsb,
444da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					  blocknr, blocksize,
445da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					  transaction);
446da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			blocknr++;
447da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			WRAP(jsb, blocknr);
448da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			continue;
449da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
450da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		default:
451da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf (out_file, "Unexpected block type %u at "
452da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				 "block %u.\n", blocktype, blocknr);
453da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			return;
454da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
455da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
456da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
457da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
458da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
459da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_descriptor_block(FILE *out_file,
460da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  struct journal_source *source,
461da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  char *buf,
462da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  journal_superblock_t *jsb,
463da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  unsigned int *blockp, int blocksize,
464da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  tid_t transaction)
465da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
466da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int			offset;
467da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char			*tagp;
468da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	journal_block_tag_t	*tag;
469da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	unsigned int		blocknr;
470da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	__u32			tag_block;
471da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	__u32			tag_flags;
472da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
473da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
474da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	offset = sizeof(journal_header_t);
475da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	blocknr = *blockp;
476da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
477da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (dump_all)
478da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "Dumping descriptor block, sequence %u, at "
479da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			"block %u:\n", transaction, blocknr);
480da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
481da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	++blocknr;
482da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	WRAP(jsb, blocknr);
483da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
484da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	do {
485da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		/* Work out the location of the current tag, and skip to
486da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		 * the next one... */
487da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		tagp = &buf[offset];
488da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		tag = (journal_block_tag_t *) tagp;
489da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		offset += sizeof(journal_block_tag_t);
490da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
491da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		/* ... and if we have gone too far, then we've reached the
492da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		   end of this block. */
493da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (offset > blocksize)
494da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			break;
495da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
496da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		tag_block = be32_to_cpu(tag->t_blocknr);
497da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		tag_flags = be32_to_cpu(tag->t_flags);
498da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
499da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (!(tag_flags & JFS_FLAG_SAME_UUID))
500da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			offset += 16;
501da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
502da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		dump_metadata_block(out_file, source, jsb,
503da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				    blocknr, tag_block, blocksize,
504da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				    transaction);
505da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
506da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		++blocknr;
507da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		WRAP(jsb, blocknr);
508da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
509da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	} while (!(tag_flags & JFS_FLAG_LAST_TAG));
510da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
511da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	*blockp = blocknr;
512da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
513da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
514da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
515da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_revoke_block(FILE *out_file, char *buf,
516da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  journal_superblock_t *jsb,
517da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  unsigned int blocknr, int blocksize,
518da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				  tid_t transaction)
519da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
520da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int			offset, max;
521da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	journal_revoke_header_t *header;
522da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	unsigned int		*entry, rblock;
523da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
524da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (dump_all)
525da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "Dumping revoke block, sequence %u, at "
526da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			"block %u:\n", transaction, blocknr);
527da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
528da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	header = (journal_revoke_header_t *) buf;
529da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	offset = sizeof(journal_revoke_header_t);
530da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	max = be32_to_cpu(header->r_count);
531da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
532da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	while (offset < max) {
533da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		entry = (unsigned int *) (buf + offset);
534da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		rblock = be32_to_cpu(*entry);
535da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		if (dump_all || rblock == block_to_dump) {
536da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf(out_file, "  Revoke FS block %u", rblock);
537da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			if (dump_all)
538da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				fprintf(out_file, "\n");
539da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			else
540da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				fprintf(out_file," at block %u, sequence %u\n",
541da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o					blocknr, transaction);
542da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
543da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		offset += 4;
544da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
545da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
546da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
547da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
548da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void show_extent(FILE *out_file, int start_extent, int end_extent,
549da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			__u32 first_block)
550da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
551da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (start_extent >= 0 && first_block != 0)
552da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "(%d+%u): %u ",
553da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			start_extent, end_extent-start_extent, first_block);
554da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
555da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
5565e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'ostatic void show_indirect(FILE *out_file, const char *name, __u32 where)
557da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
558da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (where)
559da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "(%s): %u ", name, where);
560da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
561da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
562da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
563da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_metadata_block(FILE *out_file, struct journal_source *source,
564da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				journal_superblock_t *jsb,
565da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				unsigned int log_blocknr,
566da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				unsigned int fs_blocknr,
567da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				int blocksize,
568da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				tid_t transaction)
569da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
5705e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	unsigned int 	got;
5715e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	int		retval;
5725e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o	char 		buf[8192];
573da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
574da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (!(dump_all
575da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	      || (fs_blocknr == block_to_dump)
576da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	      || (fs_blocknr == inode_block_to_dump)
577da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	      || (fs_blocknr == bitmap_to_dump)))
578da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return;
579da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
580da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	fprintf(out_file, "  FS block %u logged at ", fs_blocknr);
581da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (!dump_all)
582da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "sequence %u, ", transaction);
583da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	fprintf(out_file, "journal block %u\n", log_blocknr);
584da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
585da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	/* There are two major special cases to parse:
586da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 *
587da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * If this block is a block
588da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * bitmap block, we need to give it special treatment so that we
589da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * can log any allocates and deallocates which affect the
590da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * block_to_dump query block.
591da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 *
592da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * If the block is an inode block for the inode being searched
593da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * for, then we need to dump the contents of that inode
594da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 * structure symbolically.
595da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	 */
596da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
597da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (!(dump_contents && dump_all)
598da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	    && fs_blocknr != block_to_dump
599da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	    && fs_blocknr != bitmap_to_dump
600da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	    && fs_blocknr != inode_block_to_dump)
601da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return;
602da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
603da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	retval = read_journal_block("logdump", source,
604da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				    blocksize * log_blocknr,
605da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				    buf, blocksize, &got);
606da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (retval)
607da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		return;
608da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
609da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (fs_blocknr == bitmap_to_dump) {
610da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		struct ext2_super_block *super;
611da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		int offset;
612da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
613da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		super = current_fs->super;
614da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		offset = ((fs_blocknr - super->s_first_data_block) %
615da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			  super->s_blocks_per_group);
616da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
617da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "    (block bitmap for block %u: "
618da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			"block is %s)\n",
619da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			block_to_dump,
620da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			ext2fs_test_bit(offset, buf) ? "SET" : "CLEAR");
621da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
622da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
623da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (fs_blocknr == inode_block_to_dump) {
624da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		struct ext2_inode *inode;
625da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		int first, prev, this, start_extent, i;
626da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
627da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "    (inode block for inode %u):\n",
628da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			inode_to_dump);
629da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
630da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		inode = (struct ext2_inode *) (buf + inode_offset_to_dump);
631da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		internal_dump_inode(out_file, "    ", inode_to_dump, inode, 0);
632da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
633da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		/* Dump out the direct/indirect blocks here:
634da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		 * internal_dump_inode can only dump them from the main
635da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		 * on-disk inode, not from the journaled copy of the
636da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		 * inode. */
637da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
638da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf (out_file, "    Blocks:  ");
6395e4f070952bb4472e28a925f591b551baf2db278Theodore Ts'o		first = prev = start_extent = -1;
640da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
641da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		for (i=0; i<EXT2_NDIR_BLOCKS; i++) {
642da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			this = inode->i_block[i];
643da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			if (start_extent >= 0  && this == prev+1) {
644da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				prev = this;
645da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				continue;
646da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			} else {
647da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				show_extent(out_file, start_extent, i, first);
648da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				start_extent = i;
649da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				first = prev = this;
650da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			}
651da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
652da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		show_extent(out_file, start_extent, i, first);
653da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		show_indirect(out_file, "IND", inode->i_block[i++]);
654da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		show_indirect(out_file, "DIND", inode->i_block[i++]);
655da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		show_indirect(out_file, "TIND", inode->i_block[i++]);
656da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
657da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "\n");
658da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
659da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
660da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	if (dump_contents)
661da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		do_hexdump(out_file, buf, blocksize);
662da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
663da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
664da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
665da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void do_hexdump (FILE *out_file, char *buf, int blocksize)
666da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{
667da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int i,j;
668da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	int *intp;
669da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	char *charp;
670da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	unsigned char c;
671da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
672da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	intp = (int *) buf;
673da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	charp = (char *) buf;
674da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
675da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	for (i=0; i<blocksize; i+=16) {
676da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "    %04x:  ", i);
677da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		for (j=0; j<16; j+=4)
678da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf(out_file, "%08x ", *intp++);
679da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		for (j=0; j<16; j++) {
680da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			c = *charp++;
681da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			if (c < ' ' || c >= 127)
682da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o				c = '.';
683da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o			fprintf(out_file, "%c", c);
684da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		}
685da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o		fprintf(out_file, "\n");
686da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o	}
687da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}
688da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o
689