📄 fsckbmap.c
字号:
/* not all of them are free */ bmap_recptr->AGActive[ag_num] = -1; } if (bmap_recptr->dmap_bufptr->nfree != dmap_freeblks) { /* bad number of free blocks */ bmap_recptr->dmap_other_error = -1; fsck_send_msg(fsck_DMAPBADNFREE, bmap_recptr->dmappg_ordno); } bdmpv_rc = dmap_tree_verify(stree_root_data); } } return (bdmpv_rc);}/***************************************************************************** * NAME: init_bmap_info * * FUNCTION: Initialize the bmap fsck global data area, pointed to by * bmap_recptr, used to control JFS bmap processing. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int init_bmap_info(){ int bii_rc = FSCK_OK; unsigned agidx; memset(bmap_recptr, 0, sizeof (struct fsck_bmap_record)); memcpy((void *) &(bmap_recptr->eyecatcher), (void *) "bmaprecd", 8); memcpy((void *) &(bmap_recptr->bmpctlinf_eyecatcher), (void *) "bmap ctl", 8); memcpy((void *) &(bmap_recptr->AGinf_eyecatcher), (void *) "AG info ", 8); memcpy((void *) &(bmap_recptr->dmapinf_eyecatcher), (void *) "dmapinfo", 8); memcpy((void *) &(bmap_recptr->L0inf_eyecatcher), (void *) "L0 info ", 8); memcpy((void *) &(bmap_recptr->L1inf_eyecatcher), (void *) "L1 info ", 8); memcpy((void *) &(bmap_recptr->L2inf_eyecatcher), (void *) "L2 info ", 8); bmap_recptr->bmpctl_bufptr = (struct dbmap *) agg_recptr->mapctl_buf_ptr; bmap_recptr->bmpctl_agg_fsblk_offset = BMAP_OFF / sb_ptr->s_bsize; bmap_recptr->AGFree_tbl = &(agg_recptr->blkmap_wsp.AG_free[0]); bmap_recptr->dmap_wsp_stree = &(agg_recptr->blkmap_wsp.dmap_wsp_tree[0]); bmap_recptr->dmap_wsp_sleafs = &(agg_recptr->blkmap_wsp.dmap_wsp_leafs[0]); bmap_recptr->L0_wsp_stree = &(agg_recptr->blkmap_wsp.L0_wsp_tree[0]); bmap_recptr->L0_wsp_sleafs = &(agg_recptr->blkmap_wsp.L0_wsp_leafs[0]); bmap_recptr->L0_bufptr = (struct dmapctl *) &(agg_recptr->bmaplv_buf_ptr); bmap_recptr->L1_wsp_stree = &(agg_recptr->blkmap_wsp.L1_wsp_tree[0]); bmap_recptr->L1_wsp_sleafs = &(agg_recptr->blkmap_wsp.L1_wsp_leafs[0]); bmap_recptr->L1_bufptr = (struct dmapctl *) &(agg_recptr->bmaplv_buf_ptr); bmap_recptr->L2_wsp_stree = &(agg_recptr->blkmap_wsp.L2_wsp_tree[0]); bmap_recptr->L2_wsp_sleafs = &(agg_recptr->blkmap_wsp.L2_wsp_leafs[0]); bmap_recptr->L2_bufptr = (struct dmapctl *) &(agg_recptr->bmaplv_buf_ptr); bmap_recptr->total_blocks = sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize; bmap_recptr->dmappg_count = (bmap_recptr->total_blocks + BPERDMAP - 1) / BPERDMAP; bmap_recptr->L0pg_count = (bmap_recptr->dmappg_count + LPERCTL - 1) / LPERCTL; if (bmap_recptr->L0pg_count > 1) { bmap_recptr->L1pg_count = (bmap_recptr->L0pg_count + LPERCTL - 1) / LPERCTL; if (bmap_recptr->L1pg_count > 1) { bmap_recptr->L2pg_count = (bmap_recptr->L1pg_count + LPERCTL - 1) / LPERCTL; } else { bmap_recptr->L2pg_count = 0; } } else { bmap_recptr->L1pg_count = 0; } bmap_recptr->free_blocks = 0; bmap_recptr->ctl_fctl_error = 0; bmap_recptr->ctl_other_error = 0; for (agidx = 0; (agidx < MAXAG); agidx++) { bmap_recptr->AGActive[agidx] = 0; } bmap_recptr->dmappg_ordno = bmap_recptr->L0pg_ordno = 0; bmap_recptr->L1pg_ordno = bmap_recptr->L2pg_1stblk = 0; bmap_recptr->dmappg_idx = bmap_recptr->L0pg_idx = 0; bmap_recptr->L1pg_idx = 0; bmap_recptr->dmap_1stblk = bmap_recptr->L0pg_1stblk = 0; bmap_recptr->L1pg_1stblk = bmap_recptr->L2pg_1stblk = 0; bmap_recptr->dmap_pmap_error = 0; bmap_recptr->dmap_slfv_error = bmap_recptr->L0pg_slfv_error = 0; bmap_recptr->L1pg_slfv_error = bmap_recptr->L2pg_slfv_error = 0; bmap_recptr->dmap_slnv_error = bmap_recptr->L0pg_slnv_error = 0; bmap_recptr->L1pg_slnv_error = bmap_recptr->L2pg_slnv_error = 0; bmap_recptr->dmap_other_error = bmap_recptr->L0pg_other_error = 0; bmap_recptr->L1pg_other_error = bmap_recptr->L2pg_other_error = 0; return (bii_rc);}/***************************************************************************** * NAME: Ln_tree_rebuild * * FUNCTION: Rebuild the tree in the current summary page. * * PARAMETERS: * level - input - Summary level of the bmap summary page * containing the tree to rebuild * first_blk - input - First aggregate block described by the bmap * summary page containing the tree to rebuild * addr_buf_ptr - input - pointer to a variable in which to return the * address of the buffer in which the page has * been rebuilt (and then written to the * aggregate) * root_data - input - pointer to a variable in which to return the * data value in the root of the rebuilt tree. * * RETURNS: * success: FSCK_OK * failure: something else */int Ln_tree_rebuild(int level, int64_t first_blk, struct dmapctl **addr_buf_ptr, int8_t * root_data){ int blsr_rc = FSCK_OK; struct fsck_stree_proc_parms stree_proc_parms; struct fsck_stree_proc_parms *prms_ptr; /* * get the page to verify into the I/O buffer */ blsr_rc = blktbl_Ln_page_get(level, first_blk, addr_buf_ptr); if (blsr_rc == FSCK_OK) { /* the page is in the buffer */ prms_ptr = &stree_proc_parms; /* these are just big trees */ prms_ptr->buf_tree = (dmtree_t *) * addr_buf_ptr; switch (level) { case 0:{ prms_ptr->wsp_stree = bmap_recptr->L0_wsp_stree; break; } case 1:{ prms_ptr->wsp_stree = bmap_recptr->L1_wsp_stree; break; } default:{ prms_ptr->wsp_stree = bmap_recptr->L2_wsp_stree; break; } } prms_ptr->buf_tree->dmt_nleafs = prms_ptr->nleafs = LPERCTL; prms_ptr->buf_tree->dmt_l2nleafs = prms_ptr->l2nleafs = L2LPERCTL; prms_ptr->buf_tree->dmt_leafidx = prms_ptr->leafidx = CTLLEAFIND; prms_ptr->buf_tree->dmt_height = 5; prms_ptr->buf_tree->dmt_budmin = L2BPERDMAP + level * L2LPERCTL; prms_ptr->budmin = prms_ptr->buf_tree->dmt_budmin; prms_ptr->buf_stree = &(prms_ptr->buf_tree->dmt_stree[0]); blsr_rc = stree_rebuild(prms_ptr, root_data); /* * put the page back into the file */ if (blsr_rc == FSCK_OK) { blsr_rc = blktbl_Ln_page_put(*addr_buf_ptr); } } return (blsr_rc);}/***************************************************************************** * NAME: Ln_tree_verify * * FUNCTION: Verify the tree in the current summary page. * * PARAMETERS: * level - input - Summary level of the bmap summary page * containing the tree to verify * first_blk - input - First aggregate block described by the bmap * summary page containing the tree to verify * addr_buf_ptr - input - pointer to a variable in which to return the * address of the buffer into which the page has * been read so that its contents can be verified * root_data - input - pointer to a variable in which to return the * data value which should be in the root of the * tree....and may actually be stored there. * * RETURNS: * success: FSCK_OK * failure: something else */int Ln_tree_verify(int level, int64_t first_blk, struct dmapctl **addr_buf_ptr, int8_t * root_data){ int blsv_rc = FSCK_OK; int8_t *other_errors; int8_t tree_spec_errors = 0; struct fsck_stree_proc_parms stree_proc_parms; struct fsck_stree_proc_parms *prms_ptr; /* * get the page to verify into the I/O buffer */ blsv_rc = blktbl_Ln_page_get(level, first_blk, addr_buf_ptr); if (blsv_rc == FSCK_OK) { /* the page is in the buffer */ prms_ptr = &stree_proc_parms; /* these are just big trees */ prms_ptr->buf_tree = (dmtree_t *) * addr_buf_ptr; switch (level) { case 0:{ prms_ptr->wsp_stree = bmap_recptr->L0_wsp_stree; prms_ptr->page_ordno = bmap_recptr->L0pg_ordno; prms_ptr->lfval_error = &(bmap_recptr->L0pg_slfv_error); prms_ptr->intval_error = &(bmap_recptr->L0pg_slnv_error); prms_ptr->page_level = fsck_L0; other_errors = &(bmap_recptr->L0pg_other_error); break; } case 1:{ prms_ptr->wsp_stree = bmap_recptr->L1_wsp_stree; prms_ptr->page_ordno = bmap_recptr->L1pg_ordno; prms_ptr->lfval_error = &(bmap_recptr->L1pg_slfv_error); prms_ptr->intval_error = &(bmap_recptr->L1pg_slnv_error); prms_ptr->page_level = fsck_L1; other_errors = &(bmap_recptr->L1pg_other_error); break; } default:{ prms_ptr->wsp_stree = bmap_recptr->L2_wsp_stree; prms_ptr->page_ordno = 0; prms_ptr->lfval_error = &(bmap_recptr->L2pg_slfv_error); prms_ptr->intval_error = &(bmap_recptr->L2pg_slnv_error); prms_ptr->page_level = fsck_L2; other_errors = &(bmap_recptr->L2pg_other_error); break; } } if (prms_ptr->buf_tree->dmt_nleafs != LPERCTL) { /* wrong number of leafs */ *other_errors = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADNLF, fsck_ref_msg(prms_ptr->page_level), prms_ptr->page_ordno); } if (prms_ptr->buf_tree->dmt_l2nleafs != L2LPERCTL) { /* wrong log2(nleafs) */ *other_errors = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADL2NLF, fsck_ref_msg(prms_ptr->page_level), prms_ptr->page_ordno); } if (prms_ptr->buf_tree->dmt_leafidx != CTLLEAFIND) { /* wrong 1st leaf index */ *other_errors = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADLFI, fsck_ref_msg(prms_ptr->page_level), prms_ptr->page_ordno); } if (prms_ptr->buf_tree->dmt_height != 5) { /* wrong stree height */ *other_errors = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADHT, fsck_ref_msg(prms_ptr->page_level), prms_ptr->page_ordno); } if (prms_ptr->buf_tree->dmt_budmin != (L2BPERDMAP + level * L2LPERCTL)) { /* wrong min buddy value */ *other_errors = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADBMN, fsck_ref_msg(prms_ptr->page_level), prms_ptr->page_ordno); } /* * if we found errors in the fields which specify the summary * tree then we won't take the time to verify the tree itself. * * (The errors already detected would corrupt the summary tree, * so info about the bad tree would only be noise at this point.) */ if (!tree_spec_errors) { /* tree specification fields are ok */ prms_ptr->buf_stree = &(prms_ptr->buf_tree->dmt_stree[0]); prms_ptr->nleafs = LPERCTL; prms_ptr->budmin = (L2BPERDMAP + level * L2LPERCTL); prms_ptr->l2nleafs = L2LPERCTL; prms_ptr->leafidx = CTLLEAFIND; blsv_rc = stree_verify(prms_ptr, root_data); } } return (blsv_rc);}/***************************************************************************** * NAME: rebuild_blkall_map * * FUNCTION: Rebuild the JFS Aggregate Block Map in the aggregate. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int rebuild_blkall_map(){ int rbam_rc = FSCK_OK; int8_t sumtree_root_data; uint32_t leafidx;#define MAXIDX (LPERCTL - 1) rbam_rc = init_bmap_info(); /* * since the dmap I/O buffer is really the same storage as the * IAG I/O buffer, flush out any pending writes that may remain * from IAG processing. */ rbam_rc = iags_flush(); /* * rebuild the dmap pages. Rebuild each L0 and L1 page * if and when the information for is complete. */ while ((rbam_rc == FSCK_OK) && (bmap_recptr->dmappg_ordno < bmap_recptr->dmappg_count)) { rbam_rc = dmappg_rebuild(&sumtree_root_data); if (rbam_rc != FSCK_OK) continue; /* * the data in the dmap summary tree root goes into a leaf of * the current L0 page */ bmap_recptr->L0_wsp_sleafs[bmap_recptr->dmappg_idx] = sumtree_root_data; /* move to next dmap page */ bmap_recptr->dmappg_ordno++; bmap_recptr->dmap_1stblk += BPERDMAP; if (bmap_recptr->dmappg_idx < MAXIDX) { /* still gathering info about this L0 page */ bmap_recptr->dmappg_idx++; continue; } /* we have all the info needed for the current L0 page */ bmap_recptr->dmappg_idx = 0; rbam_rc = Ln_tree_rebuild(0, bmap_recptr->L0pg_1stblk, &(bmap_recptr->L0_bufptr), &sumtree_root_data); if (rbam_rc == FSCK_OK) { /* * the data in the L0 summary tree root goes into * a leaf of the current L1 page */ bmap_recptr->L1_wsp_sleafs[bmap_recptr-> L0pg_idx] = sumtree_root_data; /* move to the next L0 page */ bmap_recptr->L0pg_ordno++; bmap_recptr->L0pg_1stblk = bmap_recptr->dmap_1stblk; if (bmap_recptr->L0pg_idx < MAXIDX) { /* still gathering info about this L1 page */ bmap_recptr->L0pg_idx++; } else { /* we have all the info needed for the current L1 page */ bmap_recptr->L0pg_idx = 0; rbam_rc = Ln_tree_rebuild(1, bmap_recptr-> L1pg_1stblk, & (bmap_recptr-> L1_bufptr), &sumtree_root_data); if (rbam_rc == FSCK_OK) { /* * the data in the L1 summary tree root goes into * a leaf of the current L2 page */ bmap_recptr-> L2_wsp_sleafs [bmap_recptr-> L1pg_idx] = sumtree_root_data; /* move to the next L1 page */ bmap_recptr->L1pg_ordno++; bmap_recptr-> L1pg_1stblk = bmap_recptr->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -