📄 dmap.c
字号:
/* * Copyright (c) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * dmap - display/modify disk map */#include <config.h>#include <stdlib.h>#include <string.h>#include "xpeek.h"#include "jfs_filsys.h"#include "jfs_dmap.h"#include "jfs_endian.h"#include "inode.h"#include "devices.h"/* ACTIONS */#define DMAP_EXIT 0#define DISPLAY_DBMAP 1#define DISPLAY_CPAGE 2#define DISPLAY_LEAF 3/* DMAP BLOCK TYPES */#define DMAP -1#define LEVEL0 0#define LEVEL1 1#define LEVEL2 2/* DMAP BLOCK CALCULATIONS */#define L0FACTOR (LPERCTL + 1)#define L1FACTOR ((L0FACTOR * LPERCTL) + 1)#define L1PAGE(l1) (2 + ((l1) * L1FACTOR))#define L0PAGE(l1, l0) (L1PAGE(l1) + 1 + ((l0) * L0FACTOR))#define DMAPPAGE(l1, l0, d) (L0PAGE(l1, l0) + 1 + (d))/* forward references */int decode_pagenum(int64_t page, int *l1, int *l0, int *dmap);int display_agfree(int64_t * agfree);int display_cpage(struct dinode *, int64_t *);int display_dbmap(struct dbmap *, int64_t *, int64_t);int display_leaf(struct dinode *, int64_t *);int display_tree(struct dmapctl *, int64_t *, int *);/* external references */int display_map(unsigned *, int); /* iag.c *//* Global Data */int dmap_level; /* Maximum level of dtree */int dmap_l2bpp; /* log 2 of blocks per page */extern unsigned type_jfs;void dmap(){ int action; int64_t address; struct dinode bmap_inode; int64_t cntl_addr; struct dbmap cntl_page; int64_t lblock; /* Logical block of BMAP to be displayed */ lblock = 0; action = DISPLAY_DBMAP; /* Read block allocation map Inode */ if (find_inode(BMAP_I, AGGREGATE_I, &address) || xRead(address, sizeof (struct dinode), (char *) &bmap_inode)) { fputs("dmap: Error reading block allocation map inode\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dinode(&bmap_inode, GET, type_jfs); /* Read overall control page for the map */ if (ujfs_rwdaddr(fp, &cntl_addr, &bmap_inode, (int64_t) 0, GET, bsize) || xRead(cntl_addr, sizeof (struct dbmap), (char *) &cntl_page)) { fputs("dmap: Error reading aggregate dmap control page\n", stderr); return; } /* swap if on big endian machine */ ujfs_swap_dbmap(&cntl_page); /* Useful stuff */ dmap_level = BMAPSZTOLEV(cntl_page.dn_mapsize); dmap_l2bpp = cntl_page.dn_l2nbperpage; while (action != DMAP_EXIT) { switch (action) { case DISPLAY_DBMAP: action = display_dbmap(&cntl_page, &lblock, cntl_addr); break; case DISPLAY_CPAGE: action = display_cpage(&bmap_inode, &lblock); break; case DISPLAY_LEAF: action = display_leaf(&bmap_inode, &lblock); break; default: fputs("dmap: Internal Error!\n", stderr); return; } } return;}/***************************************************************************** *********************** Sample output from display_dbmap()Block allocation map control page at block 128[1] dn_mapsize: 0x00000031fa0 [9] dn_agheigth: 0[2] dn_nfree: 0x00000030ed8 [10] dn_agwidth: 1[3] dn_l2nbperpage: 3 [11] dn_agstart: 341[4] dn_numag: 25 [12] dn_agl2size: 13[5] dn_maxlevel: 0 [13] dn_agfree: type 'f'[6] dn_maxag: 16 [14] dn_agsize: 8192[7] dn_agpref: 16 [15] pad: Not Displayed[8] dn_aglevel: 0*****************************************************************************/int display_dbmap(struct dbmap *hdr, int64_t *lblock, int64_t hdr_addr){ char cmdline[80]; int field; int rc; char *token; dbmap_redisplay: printf("\nBlock allocation map control page at block %lld\n\n", (long long) (hdr_addr >> l2bsize)); printf("[1] dn_mapsize:\t\t0x%011llx\t", (long long) hdr->dn_mapsize); printf("[9] dn_agheigth:\t%d\n", hdr->dn_agheigth); printf("[2] dn_nfree:\t\t0x%011llx\t", (long long) hdr->dn_nfree); printf("[10] dn_agwidth:\t%d\n", hdr->dn_agwidth); printf("[3] dn_l2nbperpage:\t%d\t\t", hdr->dn_l2nbperpage); printf("[11] dn_agstart:\t%d\n", hdr->dn_agstart); printf("[4] dn_numag:\t\t%d\t\t", hdr->dn_numag); printf("[12] dn_agl2size:\t%d\n", hdr->dn_agl2size); printf("[5] dn_maxlevel:\t%d\t\t", hdr->dn_maxlevel); printf("[13] dn_agfree:\t\ttype 'f'\n"); printf("[6] dn_maxag:\t\t%d\t\t", hdr->dn_maxag); printf("[14] dn_agsize:\t\t%lld\n", (long long) hdr->dn_agsize); printf("[7] dn_agpref:\t\t%d\t\t", hdr->dn_agpref); printf("[15] pad:\t\tNot Displayed\n"); printf("[8] dn_aglevel:\t\t%d\n", hdr->dn_aglevel); dbmap_retry: fputs("display_dbmap: [m]odify, [f]ree count, [t]ree, e[x]it > ", stdout); fgets(cmdline, 80, stdin); token = strtok(cmdline, " \n"); if ((token == 0) || (token[0] == 't')) { switch (dmap_level) { case 2: *lblock = 1; /* L2 page */ break; case 1: *lblock = 2; /* L1 page */ break; case 0: *lblock = 3; /* L0 page */ break; default: fprintf(stderr, "display_dbmap: dmap_level = %d\n", dmap_level); return DMAP_EXIT; } return DISPLAY_CPAGE; } if (token[0] == 'f') { rc = display_agfree(hdr->dn_agfree); /* swap if on big endian machine */ ujfs_swap_dbmap(hdr); if ((rc & XPEEK_CHANGED) && xWrite(hdr_addr, sizeof (struct dbmap), (char *) hdr)) { fputs("display_dbmap: error writing control header\n\n", stderr); /* swap if on big endian machine */ ujfs_swap_dbmap(hdr); return DMAP_EXIT; } /* swap if on big endian machine */ ujfs_swap_dbmap(hdr); if (rc & XPEEK_REDISPLAY) goto dbmap_redisplay; return DMAP_EXIT; } if (token[0] != 'm') { /* assume 'x' */ return DMAP_EXIT; } field = m_parse(cmdline, 14, &token); if (field == 0) goto dbmap_retry; switch (field) { case 1: hdr->dn_mapsize = strtoull(token, 0, 16); break; case 2: hdr->dn_nfree = strtoull(token, 0, 16); break; case 3: hdr->dn_l2nbperpage = strtoul(token, 0, 0); break; case 4: hdr->dn_numag = strtoul(token, 0, 0); break; case 5: hdr->dn_maxlevel = strtoul(token, 0, 0); break; case 6: hdr->dn_maxag = strtoul(token, 0, 0); break; case 7: hdr->dn_agpref = strtoul(token, 0, 0); break; case 8: hdr->dn_aglevel = strtoul(token, 0, 0); break; case 9: hdr->dn_agheigth = strtoul(token, 0, 0); break; case 10: hdr->dn_agwidth = strtoul(token, 0, 0); break; case 11: hdr->dn_agstart = strtoul(token, 0, 0); break; case 12: hdr->dn_agl2size = strtoul(token, 0, 0); break; case 13: fputs("display_dbmap: Can't change this field from here.\n", stderr); goto dbmap_retry; case 14: hdr->dn_agsize = strtoull(token, 0, 0); break; } /* swap if on big endian machine */ ujfs_swap_dbmap(hdr); if (xWrite(hdr_addr, sizeof (struct dbmap), (char *) hdr)) { fputs("display_dbmap: error writing control header\n\n", stderr); /* swap back if on big endian machine */ ujfs_swap_dbmap(hdr); return DMAP_EXIT; } /* swap back if on big endian machine */ ujfs_swap_dbmap(hdr); goto dbmap_redisplay;}/*************************************************************************** *********************** Example Output of display_cpage()Level 0 Control Page at block 136[1] nleafs: 1024 [5] budmin: 13[2] l2nleafs: 10 [6] stree: hit <enter>[3] leafidx: 341 [7] pad: Not Displayed[4] height: 5****************************************************************************/int display_cpage(struct dinode * bmap_inode, int64_t * lblock){ int64_t address; int changed = 0; char cmdline[80]; struct dmapctl ctl_page; int field; int rc; char *token; int dmap, l0, l1, type; type = decode_pagenum(*lblock, &l1, &l0, &dmap); if (ujfs_rwdaddr(fp, &address, bmap_inode, (*lblock) << dmap_l2bpp, GET, bsize) || xRead(address, sizeof (struct dmapctl), (char *) &ctl_page)) { fputs("display_cpage: Error reading control page!\n", stderr); return DMAP_EXIT; } /* swap if on big endian machine */ ujfs_swap_dmapctl(&ctl_page); cpage_redisplay: printf("\nLevel %d Control Page at block %lld\n\n", type, (long long) (address >> l2bsize)); printf("[1] nleafs:\t%d\t\t\t", ctl_page.nleafs); printf("[5] budmin:\t%d\n", ctl_page.budmin); printf("[2] l2nleafs:\t%d\t\t\t", ctl_page.l2nleafs); printf("[6] stree:\thit <enter>\n"); printf("[3] leafidx:\t%d\t\t\t", ctl_page.leafidx); printf("[7] pad:\tNot Displayed\n"); printf("[4] height:\t%d\n", ctl_page.height); cpage_retry: fputs("[m]odify, [u]p, [r]ight or [l]eft sibling, e[x]it, [s]tree > ", stdout); fgets(cmdline, 80, stdin); token = strtok(cmdline, " \n"); if ((token == 0) || (token[0] == 's')) { rc = display_tree(&ctl_page, lblock, &changed); /* swap if on big endian machine */ ujfs_swap_dmapctl(&ctl_page); if (changed && xWrite(address, sizeof (struct dmapctl), (char *) &ctl_page)) { fputs("display_cpage: Error writing control page!\n", stderr); /* swap back if on big endian machine */ ujfs_swap_dmapctl(&ctl_page); return DMAP_EXIT; } /* swap if on big endian machine */ ujfs_swap_dmapctl(&ctl_page); return rc; } if (token[0] == 'u') { if (type == LEVEL2) { *lblock = 0; return DISPLAY_DBMAP; } if (type == LEVEL1) { if (dmap_level > 1) { *lblock = 1; return DISPLAY_CPAGE; } else { *lblock = 0; return DISPLAY_DBMAP; } } if (type == LEVEL0) { if (dmap_level > 0) { *lblock = L1PAGE(l1); return DISPLAY_CPAGE; } else { *lblock = 0; return DISPLAY_DBMAP; } } } if ((token[0] == 'r') || (token[0] == 'l')) { if (type == LEVEL2) { fputs("Level 2 node has no siblings!\n", stderr); goto cpage_retry; } if (type == LEVEL1) { if (dmap_level < 2) { fputs("Level 1 node has no siblings!\n", stderr); goto cpage_retry; } if (token[0] == 'r') { if (l1 == LPERCTL - 1) { fputs("No right sibling!\n", stderr); goto cpage_retry; } l1++; } else { if (l1 == 0) { fputs("No left sibling!\n", stderr); goto cpage_retry; } l1--; } *lblock = L1PAGE(l1); return DISPLAY_CPAGE; } if (type == LEVEL0) { if (dmap_level < 1) { fputs("Level 0 node has no siblings!\n", stderr); goto cpage_retry; } if (token[0] == 'r') { if (l0 == LPERCTL - 1) { if ((dmap_level == 1) || (l1 == LPERCTL - 1)) { fputs("No right sibling!\n", stderr); goto cpage_retry; } l1++; l0 = 0; } else l0++; } else { if (l0 == 0) { if (l1 == 0) { fputs("No left sibling!\n", stderr); goto cpage_retry; } l1--; l0 = LPERCTL - 1; } else l0--; } *lblock = L0PAGE(l1, l0); return DISPLAY_CPAGE; } fprintf(stderr, "display_cpage: decode_pagenum returned type %d\n", type); return DMAP_EXIT; } if (token[0] == 'm') { field = m_parse(cmdline, 5, &token); if (field == 0) goto cpage_retry; switch (field) { case 1: ctl_page.nleafs = strtoul(token, 0, 0); break; case 2: ctl_page.l2nleafs = strtoul(token, 0, 0); break; case 3: ctl_page.leafidx = strtoul(token, 0, 0); break; case 4: ctl_page.height = strtoul(token, 0, 0); break; case 5: ctl_page.budmin = strtoul(token, 0, 0); break; } /* swap if on big endian machine */ ujfs_swap_dmapctl(&ctl_page); if (xWrite(address, sizeof (struct dmapctl), (char *) &ctl_page)) { fputs("display_cpage: Error writing control page!\n", stderr); /* swap back if on big endian machine */ ujfs_swap_dmapctl(&ctl_page); return DMAP_EXIT; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -