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