logdump.c revision 4bb0c0434c06da97836a3efba8a978a0d1ad5c6e
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#ifdef HAVE_OPTRESET 32da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oextern int optreset; /* defined by BSD, but not others */ 33da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#endif 34da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 35da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include "debugfs.h" 36da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#include "jfs_user.h" 37da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 38da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oenum journal_location {JOURNAL_IS_INTERNAL, JOURNAL_IS_EXTERNAL}; 39da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 40da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oint dump_all, dump_contents, dump_descriptors; 41da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ounsigned int block_to_dump, group_to_dump, bitmap_to_dump; 42da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ounsigned int inode_block_to_dump, inode_offset_to_dump, bitmap_to_dump; 43da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oext2_ino_t inode_to_dump; 44da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 45da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostruct journal_source 46da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 47da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o enum journal_location where; 48da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int fd; 49da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ext2_file_t file; 50da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o}; 51da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 52da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_journal(char *, FILE *, struct journal_source *); 53da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 54da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_descriptor_block(FILE *, struct journal_source *, 55da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *, journal_superblock_t *, 56da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int *, int, tid_t); 57da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 58da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_revoke_block(FILE *, char *, journal_superblock_t *, 59da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int, int, tid_t); 60da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 61da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_metadata_block(FILE *, struct journal_source *, 62da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_superblock_t*, 63da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int, unsigned int, int, tid_t); 64da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 65da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void do_hexdump (FILE *, char *, int); 66da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 67da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#define WRAP(jsb, blocknr) \ 68da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (blocknr >= be32_to_cpu((jsb)->s_maxlen)) \ 69da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr -= (be32_to_cpu((jsb)->s_maxlen) - \ 70da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o be32_to_cpu((jsb)->s_first)); 71da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 72da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 73da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ovoid do_logdump(int argc, char **argv) 74da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 75da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ext2_ino_t inode; 76da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int c; 77da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int fd; 78da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int retval; 79da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *out_fn; 80da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o FILE *out_file; 81da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 82da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *inode_spec = NULL; 83da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *journal_fn = NULL; 84da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int journal_fd = 0; 85da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ext2_ino_t journal_inum; 86da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o struct ext2_inode journal_inode; 87da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ext2_file_t journal_file; 88da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 89da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *tmp; 90da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 91da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o const char *logdump_usage = ("Usage: logdump " 92da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "[-ac] [-b<block>] [-i<inode>] " 93da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "[-f<journal_file>] [output_file]"); 94da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 95da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o struct journal_source journal_source = {}; 96da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 97da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o optind = 0; 98da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#ifdef HAVE_OPTRESET 99da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o optreset = 1; /* Makes BSD getopt happy */ 100da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o#endif 101da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_all = 0; 102da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_contents = 0; 103da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_descriptors = 1; 104da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o block_to_dump = -1; 105da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o bitmap_to_dump = -1; 106da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_block_to_dump = -1; 107da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_to_dump = -1; 108da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 109da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o while ((c = getopt (argc, argv, "ab:ci:f:")) != EOF) { 110da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o switch (c) { 111da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case 'a': 112da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_all++; 113da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o break; 114da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case 'b': 115da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o block_to_dump = strtoul(optarg, &tmp, 0); 116da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (*tmp) { 117da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], 0, 118da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "Bad block number - %s", optarg); 119da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 120da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 121da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_descriptors = 0; 122da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o break; 123da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case 'c': 124da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_contents++; 125da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o break; 126da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case 'f': 127da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_fn = optarg; 128da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o break; 129da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case 'i': 130da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_spec = optarg; 131da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_descriptors = 0; 132da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o break; 133da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o default: 134da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], 0, logdump_usage); 135da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 136da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 137da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 138da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (optind != argc && optind != argc-1) { 139da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], 0, logdump_usage); 140da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 141da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 142da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 143da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (inode_spec) { 144da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int inode_group, group_offset, inodes_per_block; 145da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 146da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (check_fs_open(argv[0])) 147da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 148da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 149da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_to_dump = string_to_inode(inode_spec); 150da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!inode_to_dump) 151da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 152da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 153da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_group = ((inode_to_dump - 1) 154da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o / current_fs->super->s_inodes_per_group); 155da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o group_offset = ((inode_to_dump - 1) 156da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o % current_fs->super->s_inodes_per_group); 157da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inodes_per_block = (current_fs->blocksize 158da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o / sizeof(struct ext2_inode)); 159da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 160da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_block_to_dump = 161da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o current_fs->group_desc[inode_group].bg_inode_table + 162da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o (group_offset / inodes_per_block); 163da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_offset_to_dump = ((group_offset % inodes_per_block) 164da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * sizeof(struct ext2_inode)); 165da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o printf("Inode %u is at group %u, block %u, offset %u\n", 166da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_to_dump, inode_group, 167da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_block_to_dump, inode_offset_to_dump); 168da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 169da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 170da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (optind == argc) { 171da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o out_file = stdout; 172da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } else { 173da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o out_fn = argv[optind]; 174da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o out_file = fopen(out_fn, "w"); 175da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!out_file < 0) { 176da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], errno, "while opening %s for logdump", 177da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o out_fn); 178da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 179da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 180da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 181da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 182da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (block_to_dump != -1 && current_fs != NULL) { 183da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o group_to_dump = ((block_to_dump - 184da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o current_fs->super->s_first_data_block) 185da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o / current_fs->super->s_blocks_per_group); 186da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o bitmap_to_dump = current_fs->group_desc[group_to_dump].bg_block_bitmap; 187da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 188da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 189da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (journal_fn) { 190da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 191da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* Set up to read journal from a regular file somewhere */ 192da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_fd = open(journal_fn, O_RDONLY, 0); 193da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (journal_fd < 0) { 194da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], errno, "while opening %s for logdump", 195da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_fn); 196da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 197da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 198da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 199da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_source.where = JOURNAL_IS_EXTERNAL; 200da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_source.fd = journal_fd; 201da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 202da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } else { 203da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 204da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* Set up to read journal from the open filesystem */ 205da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (check_fs_open(argv[0])) 206da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 207da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_inum = current_fs->super->s_journal_inum; 208da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!journal_inum) { 209da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], 0, "filesystem has no journal"); 210da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 211da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 212da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 213da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = ext2fs_read_inode(current_fs, journal_inum, 214da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o &journal_inode); 215da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval) { 216da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], retval, 217da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "while reading inode %u", journal_inum); 218da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 219da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 220da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 221da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = ext2fs_file_open(current_fs, journal_inum, 222da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 0, &journal_file); 223da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval) { 224da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(argv[0], retval, "while opening ext2 file"); 225da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 226da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 227da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 228da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_source.where = JOURNAL_IS_INTERNAL; 229da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_source.file = journal_file; 230da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 231da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 232da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_journal(argv[0], out_file, &journal_source); 233da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 234da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (journal_source.where == JOURNAL_IS_INTERNAL) 235da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ext2fs_file_close(journal_file); 236da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o else 237da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o close(journal_fd); 238da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 239da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (out_file != stdout) 240da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fclose(out_file); 241da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 242da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 243da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 244da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 245da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 246da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'oint read_journal_block(char *cmd, struct journal_source *source, off_t offset, 247da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *buf, int size, int *got) 248da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 249da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int retval; 250da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 251da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (source->where == JOURNAL_IS_EXTERNAL) { 2524bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o if (lseek(source->fd, offset, SEEK_SET) < 0) { 2534bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o retval = errno; 2544bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o com_err(cmd, retval, "while seeking in reading journal"); 2554bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o return retval; 2564bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o } 2574bb0c0434c06da97836a3efba8a978a0d1ad5c6eTheodore Ts'o retval = read(source->fd, buf, size); 258da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval >= 0) { 259da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o *got = retval; 260da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = 0; 261da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 262da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = errno; 263da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } else { 264da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = ext2fs_file_lseek(source->file, offset, 265da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o EXT2_SEEK_SET, NULL); 266da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval) { 267da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(cmd, retval, "while seeking in reading journal"); 268da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return retval; 269da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 270da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 271da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = ext2fs_file_read(source->file, buf, size, got); 272da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 273da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 274da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval) 275da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(cmd, retval, "while while reading journal"); 276da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o else if (*got != size) { 277da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o com_err(cmd, 0, "short read (read %d, expected %d) while while reading journal", *got, size); 278da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = -1; 279da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 280da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 281da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return retval; 282da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 283da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 284da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic char *type_to_name(int btype) 285da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 286da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o switch (btype) { 287da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_DESCRIPTOR_BLOCK: 288da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return "descriptor block"; 289da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_COMMIT_BLOCK: 290da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return "commit block"; 291da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_SUPERBLOCK_V1: 292da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return "V1 superblock"; 293da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_SUPERBLOCK_V2: 294da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return "V2 superblock"; 295da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_REVOKE_BLOCK: 296da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return "revoke table"; 297da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o default: 298da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 299da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return "unrecognised type"; 300da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 301da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 302da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 303da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_journal(char *cmdname, FILE *out_file, 304da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o struct journal_source *source) 305da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 306da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char jsb_buffer[1024]; 307da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char buf[8192]; 308da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_superblock_t *jsb; 309da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int blocksize; 310da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int got; 311da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int retval; 312da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o __u32 magic, sequence, blocktype; 313da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_header_t *header; 314da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 315da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tid_t transaction; 316da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int blocknr; 317da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 318da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* First: locate the journal superblock */ 319da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 320da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = read_journal_block(cmdname, source, 0, 321da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o jsb_buffer, 1024, &got); 322da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval) 323da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 324da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 325da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o jsb = (journal_superblock_t *) jsb_buffer; 326da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocksize = be32_to_cpu(jsb->s_blocksize); 327da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o transaction = be32_to_cpu(jsb->s_sequence); 328da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr = be32_to_cpu(jsb->s_start); 329da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 330da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "Journal starts at block %u, transaction %u\n", 331da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr, transaction); 332da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 333da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!blocknr) 334da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* Empty journal, nothing to do. */ 335da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 336da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 337da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o while (1) { 338da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = read_journal_block(cmdname, source, 339da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr*blocksize, buf, 340da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocksize, &got); 341da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval || got != blocksize) 342da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 343da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 344da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o header = (journal_header_t *) buf; 345da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 346da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o magic = be32_to_cpu(header->h_magic); 347da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o sequence = be32_to_cpu(header->h_sequence); 348da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocktype = be32_to_cpu(header->h_blocktype); 349da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 350da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (magic != JFS_MAGIC_NUMBER) { 351da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf (out_file, "No magic number at block %u: " 352da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "end of journal.\n", blocknr); 353da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 354da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 355da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 356da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (sequence != transaction) { 357da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf (out_file, "Found sequence %u (not %u) at " 358da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "block %u: end of journal.\n", 359da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o sequence, transaction, blocknr); 360da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 361da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 362da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 363da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (dump_descriptors) { 364da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf (out_file, "Found expected sequence %u, " 365da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "type %u (%s) at block %u\n", 366da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o sequence, blocktype, 367da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o type_to_name(blocktype), blocknr); 368da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 369da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 370da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o switch (blocktype) { 371da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_DESCRIPTOR_BLOCK: 372da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_descriptor_block(out_file, source, buf, jsb, 373da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o &blocknr, blocksize, 374da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o transaction); 375da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o continue; 376da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 377da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_COMMIT_BLOCK: 378da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o transaction++; 379da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr++; 380da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o WRAP(jsb, blocknr); 381da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o continue; 382da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 383da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o case JFS_REVOKE_BLOCK: 384da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_revoke_block(out_file, buf, jsb, 385da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr, blocksize, 386da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o transaction); 387da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr++; 388da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o WRAP(jsb, blocknr); 389da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o continue; 390da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 391da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o default: 392da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf (out_file, "Unexpected block type %u at " 393da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "block %u.\n", blocktype, blocknr); 394da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 395da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 396da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 397da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 398da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 399da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 400da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_descriptor_block(FILE *out_file, 401da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o struct journal_source *source, 402da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *buf, 403da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_superblock_t *jsb, 404da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int *blockp, int blocksize, 405da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tid_t transaction) 406da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 407da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int offset; 408da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *tagp; 409da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_block_tag_t *tag; 410da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int blocknr; 411da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o __u32 tag_block; 412da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o __u32 tag_flags; 413da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 414da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 415da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o offset = sizeof(journal_header_t); 416da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr = *blockp; 417da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 418da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (dump_all) 419da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "Dumping descriptor block, sequence %u, at " 420da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "block %u:\n", transaction, blocknr); 421da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 422da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ++blocknr; 423da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o WRAP(jsb, blocknr); 424da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 425da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o do { 426da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* Work out the location of the current tag, and skip to 427da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * the next one... */ 428da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tagp = &buf[offset]; 429da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tag = (journal_block_tag_t *) tagp; 430da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o offset += sizeof(journal_block_tag_t); 431da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 432da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* ... and if we have gone too far, then we've reached the 433da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o end of this block. */ 434da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (offset > blocksize) 435da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o break; 436da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 437da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tag_block = be32_to_cpu(tag->t_blocknr); 438da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tag_flags = be32_to_cpu(tag->t_flags); 439da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 440da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!(tag_flags & JFS_FLAG_SAME_UUID)) 441da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o offset += 16; 442da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 443da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o dump_metadata_block(out_file, source, jsb, 444da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr, tag_block, blocksize, 445da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o transaction); 446da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 447da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ++blocknr; 448da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o WRAP(jsb, blocknr); 449da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 450da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } while (!(tag_flags & JFS_FLAG_LAST_TAG)); 451da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 452da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o *blockp = blocknr; 453da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 454da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 455da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 456da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_revoke_block(FILE *out_file, char *buf, 457da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_superblock_t *jsb, 458da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int blocknr, int blocksize, 459da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tid_t transaction) 460da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 461da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int offset, max; 462da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_revoke_header_t *header; 463da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int *entry, rblock; 464da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 465da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (dump_all) 466da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "Dumping revoke block, sequence %u, at " 467da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "block %u:\n", transaction, blocknr); 468da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 469da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o header = (journal_revoke_header_t *) buf; 470da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o offset = sizeof(journal_revoke_header_t); 471da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o max = be32_to_cpu(header->r_count); 472da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 473da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o while (offset < max) { 474da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o entry = (unsigned int *) (buf + offset); 475da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o rblock = be32_to_cpu(*entry); 476da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (dump_all || rblock == block_to_dump) { 477da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, " Revoke FS block %u", rblock); 478da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (dump_all) 479da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "\n"); 480da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o else 481da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file," at block %u, sequence %u\n", 482da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocknr, transaction); 483da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 484da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o offset += 4; 485da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 486da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 487da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 488da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 489da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void show_extent(FILE *out_file, int start_extent, int end_extent, 490da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o __u32 first_block) 491da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 492da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (start_extent >= 0 && first_block != 0) 493da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "(%d+%u): %u ", 494da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o start_extent, end_extent-start_extent, first_block); 495da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 496da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 497da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void show_indirect(FILE *out_file, char *name, __u32 where) 498da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 499da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (where) 500da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "(%s): %u ", name, where); 501da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 502da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 503da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 504da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void dump_metadata_block(FILE *out_file, struct journal_source *source, 505da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o journal_superblock_t *jsb, 506da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int log_blocknr, 507da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned int fs_blocknr, 508da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int blocksize, 509da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o tid_t transaction) 510da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 511da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int got, retval; 512da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char buf[8192]; 513da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 514da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!(dump_all 515da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o || (fs_blocknr == block_to_dump) 516da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o || (fs_blocknr == inode_block_to_dump) 517da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o || (fs_blocknr == bitmap_to_dump))) 518da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 519da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 520da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, " FS block %u logged at ", fs_blocknr); 521da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!dump_all) 522da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "sequence %u, ", transaction); 523da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "journal block %u\n", log_blocknr); 524da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 525da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* There are two major special cases to parse: 526da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * 527da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * If this block is a block 528da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * bitmap block, we need to give it special treatment so that we 529da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * can log any allocates and deallocates which affect the 530da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * block_to_dump query block. 531da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * 532da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * If the block is an inode block for the inode being searched 533da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * for, then we need to dump the contents of that inode 534da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * structure symbolically. 535da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o */ 536da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 537da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (!(dump_contents && dump_all) 538da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o && fs_blocknr != block_to_dump 539da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o && fs_blocknr != bitmap_to_dump 540da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o && fs_blocknr != inode_block_to_dump) 541da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 542da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 543da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o retval = read_journal_block("logdump", source, 544da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o blocksize * log_blocknr, 545da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o buf, blocksize, &got); 546da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (retval) 547da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o return; 548da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 549da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (fs_blocknr == bitmap_to_dump) { 550da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o struct ext2_super_block *super; 551da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int offset; 552da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 553da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o super = current_fs->super; 554da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o offset = ((fs_blocknr - super->s_first_data_block) % 555da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o super->s_blocks_per_group); 556da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 557da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, " (block bitmap for block %u: " 558da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o "block is %s)\n", 559da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o block_to_dump, 560da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o ext2fs_test_bit(offset, buf) ? "SET" : "CLEAR"); 561da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 562da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 563da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (fs_blocknr == inode_block_to_dump) { 564da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o struct ext2_inode *inode; 565da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int first, prev, this, start_extent, i; 566da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 567da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, " (inode block for inode %u):\n", 568da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode_to_dump); 569da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 570da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o inode = (struct ext2_inode *) (buf + inode_offset_to_dump); 571da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o internal_dump_inode(out_file, " ", inode_to_dump, inode, 0); 572da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 573da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o /* Dump out the direct/indirect blocks here: 574da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * internal_dump_inode can only dump them from the main 575da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * on-disk inode, not from the journaled copy of the 576da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o * inode. */ 577da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 578da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf (out_file, " Blocks: "); 579da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o start_extent = -1; 580da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 581da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o for (i=0; i<EXT2_NDIR_BLOCKS; i++) { 582da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o this = inode->i_block[i]; 583da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (start_extent >= 0 && this == prev+1) { 584da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o prev = this; 585da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o continue; 586da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } else { 587da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o show_extent(out_file, start_extent, i, first); 588da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o start_extent = i; 589da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o first = prev = this; 590da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 591da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 592da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o show_extent(out_file, start_extent, i, first); 593da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o show_indirect(out_file, "IND", inode->i_block[i++]); 594da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o show_indirect(out_file, "DIND", inode->i_block[i++]); 595da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o show_indirect(out_file, "TIND", inode->i_block[i++]); 596da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 597da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "\n"); 598da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 599da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 600da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (dump_contents) 601da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o do_hexdump(out_file, buf, blocksize); 602da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 603da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 604da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 605da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'ostatic void do_hexdump (FILE *out_file, char *buf, int blocksize) 606da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o{ 607da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int i,j; 608da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o int *intp; 609da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o char *charp; 610da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o unsigned char c; 611da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 612da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o intp = (int *) buf; 613da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o charp = (char *) buf; 614da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 615da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o for (i=0; i<blocksize; i+=16) { 616da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, " %04x: ", i); 617da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o for (j=0; j<16; j+=4) 618da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "%08x ", *intp++); 619da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o for (j=0; j<16; j++) { 620da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o c = *charp++; 621da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o if (c < ' ' || c >= 127) 622da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o c = '.'; 623da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "%c", c); 624da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 625da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o fprintf(out_file, "\n"); 626da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o } 627da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o} 628da81e3fcfe075922e995a1c5f1efded5768d519aTheodore Ts'o 629