From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 9 Nov 2006 15:29:46 -0000 Subject: [Cluster-devel] cluster/gfs2/edit gfs2hex.c hexedit.c hexedit.h Message-ID: <20061109152946.23349.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Changes by: rpeterso at sourceware.org 2006-11-09 15:29:45 Modified files: gfs2/edit : gfs2hex.c hexedit.c hexedit.h Log message: This is the fix for Bugzilla Bug 214621: Allow gfs2_edit to view, print and edit gfs(1) file systems. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/gfs2hex.c.diff?cvsroot=cluster&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.c.diff?cvsroot=cluster&r1=1.6&r2=1.7 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.h.diff?cvsroot=cluster&r1=1.4&r2=1.5 --- cluster/gfs2/edit/gfs2hex.c 2006/08/09 20:21:59 1.5 +++ cluster/gfs2/edit/gfs2hex.c 2006/11/09 15:29:45 1.6 @@ -201,7 +201,8 @@ { unsigned int x, y; uint64_t p, last; - int isdir = !!(S_ISDIR(di->di_mode)); + int isdir = !!(S_ISDIR(di->di_mode)) || + (gfs1 && di->__pad1 == GFS_FILE_DIR); indirect_blocks = 0; memset(&indirect, 0, sizeof(indirect)); @@ -400,11 +401,20 @@ pv(sb, sb_bsize, "%u", "0x%x"); pv(sb, sb_bsize_shift, "%u", "0x%x"); - gfs2_inum_print2("master dir", &sb->sb_master_dir); + if (gfs1) { + gfs2_inum_print2("jindex ino", &sbd1->sb_jindex_di); + gfs2_inum_print2("rindex ino", &sbd1->sb_rindex_di); + } + else + gfs2_inum_print2("master dir", &sb->sb_master_dir); gfs2_inum_print2("root dir ", &sb->sb_root_dir); pv(sb, sb_lockproto, "%s", NULL); pv(sb, sb_locktable, "%s", NULL); + if (gfs1) { + gfs2_inum_print2("quota ino ", &gfs1_quota_di); + gfs2_inum_print2("license ", &gfs1_license_di); + } } /****************************************************************************** --- cluster/gfs2/edit/hexedit.c 2006/08/09 20:21:59 1.6 +++ cluster/gfs2/edit/hexedit.c 2006/11/09 15:29:45 1.7 @@ -36,7 +36,6 @@ #define EXTERN #include "hexedit.h" -#include "linux/gfs2_ondisk.h" #include "linux_endian.h" #include "libgfs2.h" #include "gfs2hex.h" @@ -286,6 +285,7 @@ move(line++, 0); printw("Other commands:"); gfs2instr(" h","This Help display"); + gfs2instr(" c","Toggle the color scheme"); gfs2instr(" m","Switch display mode: hex -> GFS2 structure -> Extended"); gfs2instr(" q","Quit (same as hitting key)"); gfs2instr("","Edit a value (enter to save, esc to discard)"); @@ -346,7 +346,10 @@ switch (*(lpBuffer+7)) { case GFS2_METATYPE_SB: /* 1 */ print_gfs2("(superblock)"); - struct_len = sizeof(struct gfs2_sb); + if (gfs1) + struct_len = sizeof(struct gfs_sb); + else + struct_len = sizeof(struct gfs2_sb); break; case GFS2_METATYPE_RG: /* 2 */ print_gfs2("(rsrc grp hdr)"); @@ -410,25 +413,37 @@ } if (block == sbd.sd_sb.sb_root_dir.no_addr) print_gfs2("-------------------- Root direcory -------------------"); - else if (block == sbd.sd_sb.sb_master_dir.no_addr) + else if (!gfs1 && block == sbd.sd_sb.sb_master_dir.no_addr) print_gfs2("------------------- Master directory -----------------"); else { - int d; + if (gfs1) { + if (block == sbd1->sb_rindex_di.no_addr) + print_gfs2("--------------------- rindex file -------------------"); + else if (block == gfs1_quota_di.no_addr) + print_gfs2("--------------------- Quota file --------------------"); + else if (block == sbd1->sb_jindex_di.no_addr) + print_gfs2("-------------------- Journal Index ------------------"); + else if (block == gfs1_license_di.no_addr) + print_gfs2("-------------------- License file -------------------"); + } + else { + int d; - for (d = 2; d < 8; d++) { - if (block == masterdir.dirent[d].block) { - if (!strncmp(masterdir.dirent[d].filename, "jindex", 6)) - print_gfs2("-------------------- Journal Index ------------------"); - else if (!strncmp(masterdir.dirent[d].filename, "per_node", 8)) - print_gfs2("-------------------- Per-node Dir -------------------"); - else if (!strncmp(masterdir.dirent[d].filename, "inum", 4)) - print_gfs2("--------------------- Inum file ---------------------"); - else if (!strncmp(masterdir.dirent[d].filename, "statfs", 6)) - print_gfs2("--------------------- statfs file -------------------"); - else if (!strncmp(masterdir.dirent[d].filename, "rindex", 6)) - print_gfs2("--------------------- rindex file -------------------"); - else if (!strncmp(masterdir.dirent[d].filename, "quota", 5)) - print_gfs2("--------------------- Quota file --------------------"); + for (d = 2; d < 8; d++) { + if (block == masterdir.dirent[d].block) { + if (!strncmp(masterdir.dirent[d].filename, "jindex", 6)) + print_gfs2("-------------------- Journal Index ------------------"); + else if (!strncmp(masterdir.dirent[d].filename, "per_node", 8)) + print_gfs2("-------------------- Per-node Dir -------------------"); + else if (!strncmp(masterdir.dirent[d].filename, "inum", 4)) + print_gfs2("--------------------- Inum file ---------------------"); + else if (!strncmp(masterdir.dirent[d].filename, "statfs", 6)) + print_gfs2("--------------------- statfs file -------------------"); + else if (!strncmp(masterdir.dirent[d].filename, "rindex", 6)) + print_gfs2("--------------------- rindex file -------------------"); + else if (!strncmp(masterdir.dirent[d].filename, "quota", 5)) + print_gfs2("--------------------- Quota file --------------------"); + } } } } @@ -513,6 +528,11 @@ eol(0); l+=16; } /* while */ + if (gfs1) { + COLORS_NORMAL; + print_gfs2(" *** This seems to be a GFS-1 file system ***"); + eol(0); + } return (offset+len); }/* hexdump */ @@ -634,7 +654,8 @@ eol(0); start_line = line; if (indirect_blocks || - (gfs2_struct_type == GFS2_METATYPE_DI && S_ISDIR(di.di_mode))) { + (gfs2_struct_type == GFS2_METATYPE_DI && + (S_ISDIR(di.di_mode) || (gfs1 && di.__pad1 == GFS_FILE_DIR)))) { indir_blocks = indirect_blocks; if (!indirect_blocks) { print_gfs2("This directory contains %d directory entries.", @@ -754,7 +775,8 @@ else print_gfs2("This block does not have indirect blocks."); eol(0); - if (block == masterblock("rindex")) { + if ((gfs1 && block == sbd1->sb_rindex_di.no_addr) || + (block == masterblock("rindex"))) { struct gfs2_buffer_head *tmp_bh; tmp_bh = bread(&sbd, block); @@ -762,7 +784,7 @@ print_rindex(tmp_inode); brelse(tmp_bh, not_updated); } - else if (block == masterblock("inum")) { + else if (!gfs1 && block == masterblock("inum")) { struct gfs2_buffer_head *tmp_bh; tmp_bh = bread(&sbd, block); @@ -770,7 +792,7 @@ print_inum(tmp_inode); brelse(tmp_bh, not_updated); } - else if (block == masterblock("statfs")) { + else if (!gfs1 && block == masterblock("statfs")) { struct gfs2_buffer_head *tmp_bh; tmp_bh = bread(&sbd, block); @@ -778,7 +800,8 @@ print_statfs(tmp_inode); brelse(tmp_bh, not_updated); } - else if (block == masterblock("quota")) { + else if ((gfs1 && block == gfs1_quota_di.no_addr) || + (block == masterblock("quota"))) { struct gfs2_buffer_head *tmp_bh; tmp_bh = bread(&sbd, block); @@ -796,6 +819,7 @@ { int x; + sbd1 = (struct gfs_sb *)&sbd.sd_sb; ioctl(fd, BLKFLSBUF, 0); do_lseek(fd, 0x10 * bufsize); do_read(fd, buf, bufsize); /* read in the desired block */ @@ -813,6 +837,20 @@ osi_list_init(&sbd.buf_hash[x]); compute_constants(&sbd); gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */ + /* Check to see if this is really gfs1 */ + if (sbd1->sb_fs_format == GFS_FORMAT_FS && + sbd1->sb_header.mh_type == GFS_METATYPE_SB && + sbd1->sb_header.mh_format == GFS_FORMAT_SB && + sbd1->sb_multihost_format == GFS_FORMAT_MULTI) { + struct gfs_sb *sbbuf = (struct gfs_sb *)buf; + + gfs1 = TRUE; + gfs2_inum_in(&sbd1->sb_rindex_di, (void *)&sbbuf->sb_rindex_di); + gfs2_inum_in(&gfs1_quota_di, (void *)&sbbuf->sb_quota_di); + gfs2_inum_in(&gfs1_license_di, (void *)&sbbuf->sb_license_di); + } + else + gfs1 = FALSE; } /* ------------------------------------------------------------------------ */ @@ -938,10 +976,20 @@ if (bobgets(string, 1, 7, 16)) { if (!strcmp(string,"root")) temp_blk = sbd.sd_sb.sb_root_dir.no_addr; - else if (!strcmp(string,"master")) + else if (!gfs1 && !strcmp(string,"master")) temp_blk = sbd.sd_sb.sb_master_dir.no_addr; - else if (isalpha(string[0])) - temp_blk = masterblock(string); + else if (isalpha(string[0])) { + if (gfs1) { + if (!strcmp(string, "jindex")) + temp_blk = sbd1->sb_jindex_di.no_addr; + else if (!strcmp(string, "rindex")) + temp_blk = sbd1->sb_rindex_di.no_addr; + else if (!strcmp(string, "quota")) + temp_blk = gfs1_quota_di.no_addr; + } + else + temp_blk = masterblock(string); + } else if (string[0] == '0' && string[1] == 'x') sscanf(string, "%"SCNx64, &temp_blk); /* retrieve in hex */ else @@ -957,6 +1005,32 @@ } /* ------------------------------------------------------------------------ */ +/* init_colors */ +/* ------------------------------------------------------------------------ */ +void init_colors() +{ + + if (color_scheme) { + init_pair(COLOR_TITLE, COLOR_BLACK, COLOR_CYAN); /* title lines */ + init_pair(COLOR_NORMAL, COLOR_WHITE, COLOR_BLACK); /* normal text */ + init_pair(COLOR_INVERSE, COLOR_BLACK, COLOR_WHITE); /* inverse text */ + init_pair(COLOR_SPECIAL, COLOR_RED, COLOR_BLACK); /* special text */ + init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_BLACK); /* highlighted */ + init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_BLACK); /* offsets */ + init_pair(COLOR_CONTENTS, COLOR_YELLOW, COLOR_BLACK); /* file data */ + } + else { + init_pair(COLOR_TITLE, COLOR_BLACK, COLOR_CYAN); /* title lines */ + init_pair(COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); /* normal text */ + init_pair(COLOR_INVERSE, COLOR_WHITE, COLOR_BLACK); /* inverse text */ + init_pair(COLOR_SPECIAL, COLOR_RED, COLOR_WHITE); /* special text */ + init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_WHITE); /* highlighted */ + init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_WHITE); /* offsets */ + init_pair(COLOR_CONTENTS, COLOR_BLUE, COLOR_WHITE); /* file data */ + } +} + +/* ------------------------------------------------------------------------ */ /* interactive_mode - accept keystrokes from user and display structures */ /* ------------------------------------------------------------------------ */ void interactive_mode(void) @@ -980,24 +1054,7 @@ keypad(stdscr, TRUE); raw(); curs_set(0); - if (color_scheme) { - init_pair(COLOR_TITLE, COLOR_BLACK, COLOR_CYAN); /* title lines */ - init_pair(COLOR_NORMAL, COLOR_WHITE, COLOR_BLACK); /* normal text */ - init_pair(COLOR_INVERSE, COLOR_BLACK, COLOR_WHITE); /* inverse text */ - init_pair(COLOR_SPECIAL, COLOR_RED, COLOR_BLACK); /* special text */ - init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_BLACK); /* highlighted */ - init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_BLACK); /* offsets */ - init_pair(COLOR_CONTENTS, COLOR_YELLOW, COLOR_BLACK); /* file data */ - } - else { - init_pair(COLOR_TITLE, COLOR_BLACK, COLOR_CYAN); /* title lines */ - init_pair(COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); /* normal text */ - init_pair(COLOR_INVERSE, COLOR_WHITE, COLOR_BLACK); /* inverse text */ - init_pair(COLOR_SPECIAL, COLOR_RED, COLOR_WHITE); /* special text */ - init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_WHITE); /* highlighted */ - init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_WHITE); /* offsets */ - init_pair(COLOR_CONTENTS, COLOR_BLUE, COLOR_WHITE); /* file data */ - } + init_colors(); /* Accept keystrokes and act on them accordingly */ Quit = FALSE; while (!Quit) { @@ -1128,6 +1185,13 @@ offset = 0; break; /* -------------------------------------------------------------- */ + /* c - Change color scheme */ + /* -------------------------------------------------------------- */ + case 'c': + color_scheme = !color_scheme; + init_colors(); + break; + /* -------------------------------------------------------------- */ /* page up key */ /* -------------------------------------------------------------- */ case 0x19: // ctrl-y for vt100 @@ -1295,6 +1359,7 @@ exit(0); } else if (!strcasecmp(argv[i], "-h") || + !strcasecmp(argv[i], "-help") || !strcasecmp(argv[i], "-usage")) { usage(); exit(0); @@ -1303,7 +1368,8 @@ i++; color_scheme = atoi(argv[i]); } - else if (!strcasecmp(argv[i], "-p")) { + else if (!strcasecmp(argv[i], "-p") || + !strcasecmp(argv[i], "-print")) { termlines = 0; /* initial value--we'll figure it out later */ display_mode = GFS2_MODE; } @@ -1323,24 +1389,39 @@ else if (!strcmp(argv[i], "size")) printf("Device size: %" PRIu64 " (0x%" PRIx64 ")\n", max_block, max_block); - else if (!strcmp(argv[i], "sb")) + else if (!strcmp(argv[i], "sb") || + !strcmp(argv[i], "superblock")) push_block(0x10); /* superblock */ - else if (!strcmp(argv[i], "root")) + else if (!strcmp(argv[i], "root") || + !strcmp(argv[i], "rootdir")) push_block(sbd.sd_sb.sb_root_dir.no_addr); - else if (!strcmp(argv[i], "master")) + else if (!gfs1 && !strcmp(argv[i], "master")) push_block(sbd.sd_sb.sb_master_dir.no_addr); - else if (!strcmp(argv[i], "jindex")) - push_block(masterblock("jindex"));/* journal index */ - else if (!strcmp(argv[i], "per_node")) + else if (!strcmp(argv[i], "jindex")) { + if (gfs1) + push_block(sbd1->sb_jindex_di.no_addr); + else + push_block(masterblock("jindex"));/* journal index */ + } + else if (!gfs1 && !strcmp(argv[i], "per_node")) push_block(masterblock("per_node")); - else if (!strcmp(argv[i], "inum")) + else if (!gfs1 && !strcmp(argv[i], "inum")) push_block(masterblock("inum")); - else if (!strcmp(argv[i], "statfs")) + else if (!gfs1 && !strcmp(argv[i], "statfs")) push_block(masterblock("statfs")); - else if (!strcmp(argv[i], "rindex")) - push_block(masterblock("rindex")); - else if (!strcmp(argv[i], "quota")) - push_block(masterblock("quota")); + else if (!strcmp(argv[i], "rindex") || + !strcmp(argv[i], "rgindex")) { + if (gfs1) + push_block(sbd1->sb_rindex_di.no_addr); + else + push_block(masterblock("rindex")); + } + else if (!strcmp(argv[i], "quota")) { + if (gfs1) + push_block(gfs1_quota_di.no_addr); + else + push_block(masterblock("quota")); + } else if (argv[i][0]=='0' && argv[i][1]=='x') { /* hex addr */ sscanf(argv[i], "%"SCNx64, &temp_blk);/* retrieve in hex */ push_block(temp_blk); @@ -1401,7 +1482,8 @@ max_block = lseek(fd, 0, SEEK_END) / bufsize; read_superblock(); - read_master_dir(); + if (!gfs1) + read_master_dir(); block_in_mem = -1; if (!termlines) /* if printing to stdout */ process_parameters(argc, argv, 1); /* get what to print from cmdline */ --- cluster/gfs2/edit/hexedit.h 2006/06/19 20:49:25 1.4 +++ cluster/gfs2/edit/hexedit.h 2006/11/09 15:29:45 1.5 @@ -43,6 +43,20 @@ enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2 }; #define BLOCK_STACK_SIZE 256 +#define GFS_FORMAT_SB (100) /* Super-Block */ +#define GFS_METATYPE_SB (1) /* Super-Block */ +#define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */ +#define GFS_FORMAT_MULTI (1401) /* Multi-Host */ +/* GFS1 Dinode types */ +#define GFS_FILE_NON (0) +#define GFS_FILE_REG (1) /* regular file */ +#define GFS_FILE_DIR (2) /* directory */ +#define GFS_FILE_LNK (5) /* link */ +#define GFS_FILE_BLK (7) /* block device node */ +#define GFS_FILE_CHR (8) /* character device node */ +#define GFS_FILE_FIFO (101) /* fifo/pipe */ +#define GFS_FILE_SOCK (102) /* socket */ + EXTERN char *prog_name; EXTERN int fd; EXTERN uint64_t block INIT(0); @@ -66,6 +80,9 @@ EXTERN int edit_size[DISPLAY_MODES], edit_last[DISPLAY_MODES]; EXTERN char edit_string[1024], edit_fmt[80]; EXTERN struct gfs2_sbd sbd; +EXTERN struct gfs_sb *sbd1; +EXTERN struct gfs2_inum gfs1_quota_di; /* kludge because gfs2 sb too small */ +EXTERN struct gfs2_inum gfs1_license_di; /* kludge because gfs2 sb too small */ EXTERN struct gfs2_dinode di; EXTERN int screen_chunk_size INIT(512); /* how much of the 4K can fit on screen */ EXTERN int gfs2_struct_type; @@ -74,6 +91,7 @@ EXTERN int identify INIT(FALSE); EXTERN int color_scheme INIT(0); EXTERN WINDOW *wind; +EXTERN int gfs1 INIT(0); struct gfs2_dirents { uint64_t block; @@ -95,6 +113,35 @@ enum dsp_mode display_mode; }; +struct gfs_sb { + /* Order is important; need to be able to read old superblocks + in order to support on-disk version upgrades */ + struct gfs2_meta_header sb_header; + + uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ + uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ + uint32_t sb_flags; /* ?? */ + + uint32_t sb_bsize; /* fundamental FS block size in bytes */ + uint32_t sb_bsize_shift; /* log2(sb_bsize) */ + uint32_t sb_seg_size; /* Journal segment size in FS blocks */ + + /* These special inodes do not appear in any on-disk directory. */ + struct gfs2_inum sb_jindex_di; /* journal index inode */ + struct gfs2_inum sb_rindex_di; /* resource group index inode */ + struct gfs2_inum sb_root_di; /* root directory inode */ + + /* Default inter-node locking protocol (lock module) and namespace */ + char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */ + char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */ + + /* More special inodes */ + struct gfs2_inum sb_quota_di; /* quota inode */ + struct gfs2_inum sb_license_di; /* license inode */ + + char sb_reserved[96]; +}; + EXTERN struct blkstack_info blockstack[BLOCK_STACK_SIZE]; EXTERN struct indirect_info indirect[512]; /* more than the most indirect pointers possible for any given