📄 fsckbmap.c
字号:
bitmask = bitmask >> 1; /* advance to the next bit */ } } } return (bdpr_rc);}/***************************************************************************** * NAME: dmap_pmap_verify * * FUNCTION: Verify the pmap in the current block map dmap page. * * PARAMETERS: * pmap_freeblks - input - pointer to a variable in which the number * of free blocks described by the dmap page * will be returned. * * RETURNS: * success: FSCK_OK * failure: something else */int dmap_pmap_verify(uint32_t * pmap_freeblks){ int bdpv_rc = FSCK_OK; uint32_t bitmask; int64_t wsp_pagenum; uint32_t wsp_byteoffset; struct fsck_blk_map_page *wsp_page; uint32_t *wsp_bits = NULL; int32_t map_wordidx, word_bitidx; int8_t max_buddy; uint32_t unmarked_range_first_ordno = 0; int32_t unmarked_range_wordidx = 0; int32_t unmarked_range_bitidx = 0; int64_t size_of_unmarked_range = 0; uint32_t marked_range_first_ordno = 0; int32_t marked_range_wordidx = 0; int32_t marked_range_bitidx = 0; int64_t size_of_marked_range = 0; /* * locate the section of the workspace bit map which corresponds * to this dmap's pmap */ bdpv_rc = blkmap_find_bit(bmap_recptr->dmap_1stblk, &wsp_pagenum, &wsp_byteoffset, &bitmask); if (bdpv_rc == FSCK_OK) { bdpv_rc = blkmap_get_page(wsp_pagenum, &wsp_page); if (bdpv_rc == FSCK_OK) { /* got the page */ wsp_bits = (uint32_t *) ((char *) wsp_page + wsp_byteoffset); } } *pmap_freeblks = 0; if (bdpv_rc != FSCK_OK) goto bdpv_exit; for (map_wordidx = 0; (map_wordidx < LPERDMAP); map_wordidx++) { max_buddy = ujfs_maxbuddy((char *) &(wsp_bits[map_wordidx])); bmap_recptr->dmap_wsp_sleafs[map_wordidx] = max_buddy; bitmask = 0x80000000u; for (word_bitidx = 0; (word_bitidx < DBWORD); word_bitidx++) { if (wsp_bits[map_wordidx] & bitmask) { agg_recptr->blocks_used_in_aggregate++; if (!(bmap_recptr->dmap_bufptr-> pmap[map_wordidx] & bitmask)) { /* pmap says not */ bmap_recptr->dmap_pmap_error = -1; if (size_of_unmarked_range == 0) { if (size_of_marked_range != 0) { fsck_send_msg (fsck_PMAPSBOFF, (long long) size_of_marked_range, marked_range_first_ordno, marked_range_wordidx, marked_range_bitidx); size_of_marked_range = 0; } unmarked_range_first_ordno = bmap_recptr->dmappg_ordno; unmarked_range_wordidx = map_wordidx; unmarked_range_bitidx = word_bitidx; size_of_unmarked_range = 1; } else { /* not the first in the range */ size_of_unmarked_range++; } } else { /* pmap agrees */ if (size_of_marked_range != 0) { /* marked range ended */ fsck_send_msg(fsck_PMAPSBOFF, (long long) size_of_marked_range, marked_range_first_ordno, marked_range_wordidx, marked_range_bitidx); size_of_marked_range = 0; } if (size_of_unmarked_range != 0) { /* unmarked range ended */ fsck_send_msg(fsck_PMAPSBON, (long long) size_of_unmarked_range, unmarked_range_first_ordno, unmarked_range_wordidx, unmarked_range_bitidx); size_of_unmarked_range = 0; } } } else { /* fsck says not allocated */ (*pmap_freeblks)++; agg_recptr->free_blocks_in_aggregate++; if ((bmap_recptr->dmap_bufptr->pmap[map_wordidx] & bitmask)) { /* pmap says yes */ bmap_recptr->dmap_pmap_error = -1; if (size_of_marked_range == 0) { if (size_of_unmarked_range != 0) { fsck_send_msg (fsck_PMAPSBON, (long long) size_of_unmarked_range, unmarked_range_first_ordno, unmarked_range_wordidx, unmarked_range_bitidx); size_of_unmarked_range = 0; } marked_range_first_ordno = bmap_recptr->dmappg_ordno; marked_range_wordidx = map_wordidx; marked_range_bitidx = word_bitidx; size_of_marked_range = 1; } else { /* not the first in the range */ size_of_marked_range++; } } else { /* pmap agrees */ if (size_of_marked_range != 0) { fsck_send_msg(fsck_PMAPSBOFF, (long long) size_of_marked_range, marked_range_first_ordno, marked_range_wordidx, marked_range_bitidx); size_of_marked_range = 0; } if (size_of_unmarked_range != 0) { /* unmarked range ended */ fsck_send_msg(fsck_PMAPSBON, (long long) size_of_unmarked_range, unmarked_range_first_ordno, unmarked_range_wordidx, unmarked_range_bitidx); size_of_unmarked_range = 0; } } } /* advance to the next bit */ bitmask = bitmask >> 1; } } if (size_of_marked_range != 0) { /* marked range ended */ fsck_send_msg(fsck_PMAPSBOFF,(long long)size_of_marked_range, marked_range_first_ordno,marked_range_wordidx, marked_range_bitidx); size_of_marked_range = 0; } if (size_of_unmarked_range != 0) { /* unmarked range ended */ fsck_send_msg(fsck_PMAPSBON,(long long)size_of_unmarked_range, unmarked_range_first_ordno,unmarked_range_wordidx, unmarked_range_bitidx); size_of_unmarked_range = 0; } bdpv_exit: return (bdpv_rc);}/***************************************************************************** * NAME: dmap_tree_rebuild * * FUNCTION: Rebuild the tree in the current block map dmap page. * * PARAMETERS: * root_data - input - pointer to a variable in which the data value * stored in the root of the tree will be returned. * * RETURNS: * success: FSCK_OK * failure: something else */int dmap_tree_rebuild(int8_t * root_data){ int bdsr_rc = FSCK_OK; struct fsck_stree_proc_parms stree_proc_parms; struct fsck_stree_proc_parms *prms_ptr; prms_ptr = &stree_proc_parms;#define ppbt prms_ptr->buf_tree ppbt = (dmtree_t *) & (bmap_recptr->dmap_bufptr->tree); ppbt->dmt_nleafs = prms_ptr->nleafs = LPERDMAP; ppbt->dmt_l2nleafs = prms_ptr->l2nleafs = L2LPERDMAP; ppbt->dmt_leafidx = prms_ptr->leafidx = LEAFIND; ppbt->dmt_height = 4; ppbt->dmt_budmin = prms_ptr->budmin = BUDMIN; prms_ptr->buf_stree = &(ppbt->dmt_stree[0]); prms_ptr->wsp_stree = bmap_recptr->dmap_wsp_stree; bdsr_rc = stree_rebuild(prms_ptr, root_data); return (bdsr_rc);}/***************************************************************************** * NAME: dmap_tree_verify * * FUNCTION: Verify the tree in the current block map dmap page. * * PARAMETERS: * root_data - input - pointer to a variable in which the data value * which should be stored in the root of the tree * will be returned. * * RETURNS: * success: FSCK_OK * failure: something else */int dmap_tree_verify(int8_t * root_data){ int bdsv_rc = FSCK_OK; int8_t tree_spec_errors = 0; struct fsck_stree_proc_parms stree_proc_parms; struct fsck_stree_proc_parms *prms_ptr; prms_ptr = &stree_proc_parms; prms_ptr->buf_tree = (dmtree_t *) & (bmap_recptr->dmap_bufptr->tree); if (prms_ptr->buf_tree->dmt_nleafs != LPERDMAP) { /* wrong number of leafs */ bmap_recptr->dmap_other_error = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADNLF, fsck_ref_msg(fsck_dmap), bmap_recptr->dmappg_ordno); } if (prms_ptr->buf_tree->dmt_l2nleafs != L2LPERDMAP) { /* wrong log2(nleafs) */ bmap_recptr->dmap_other_error = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADL2NLF, fsck_ref_msg(fsck_dmap), bmap_recptr->dmappg_ordno); } if (prms_ptr->buf_tree->dmt_leafidx != LEAFIND) { /* wrong 1st leaf index */ bmap_recptr->dmap_other_error = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADLFI, fsck_ref_msg(fsck_dmap), bmap_recptr->dmappg_ordno); } if (prms_ptr->buf_tree->dmt_height != 4) { /* wrong stree height */ bmap_recptr->dmap_other_error = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADHT, fsck_ref_msg(fsck_dmap), bmap_recptr->dmappg_ordno); } if (prms_ptr->buf_tree->dmt_budmin != BUDMIN) { /* wrong min buddy value */ bmap_recptr->dmap_other_error = -1; tree_spec_errors = -1; fsck_send_msg(fsck_BMAPBADBMN, fsck_ref_msg(fsck_dmap), bmap_recptr->dmappg_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->wsp_stree = bmap_recptr->dmap_wsp_stree; prms_ptr->nleafs = LPERDMAP; prms_ptr->l2nleafs = L2LPERDMAP; prms_ptr->leafidx = LEAFIND; prms_ptr->budmin = BUDMIN; prms_ptr->page_level = fsck_dmap; prms_ptr->page_ordno = bmap_recptr->dmappg_ordno; prms_ptr->lfval_error = &(bmap_recptr->dmap_slfv_error); prms_ptr->intval_error = &(bmap_recptr->dmap_slnv_error); bdsv_rc = stree_verify(prms_ptr, root_data); } return (bdsv_rc);}/***************************************************************************** * NAME: dmappg_rebuild * * FUNCTION: Rebuild the current dmap page. * * PARAMETERS: * stree_root_data - input - pointer to a variable in which to return * the the data value in the root of the * tree of the rebuilt page. * * RETURNS: * success: FSCK_OK * failure: something else */int dmappg_rebuild(int8_t * stree_root_data){ int bdmpr_rc = FSCK_OK; uint32_t nblocks; uint32_t dmap_freeblks; uint32_t ag_num; /* * get the page to verify into the I/O buffer */ bdmpr_rc = blktbl_dmap_get(bmap_recptr->dmap_1stblk, &(bmap_recptr->dmap_bufptr)); if (bdmpr_rc == FSCK_OK) { /* the page is in the buffer */ bmap_recptr->dmap_bufptr->start = bmap_recptr->dmap_1stblk; nblocks = MIN(BPERDMAP, (bmap_recptr->total_blocks - bmap_recptr->dmap_1stblk)); bmap_recptr->dmap_bufptr->nblocks = nblocks; bdmpr_rc = dmap_pwmap_rebuild(&dmap_freeblks); /* * subtract out any blocks which don't really exist but are * described by a dmap (phantom blocks always appear to be in use) */ agg_recptr->blocks_used_in_aggregate = agg_recptr->blocks_used_in_aggregate - (BPERDMAP - nblocks); if (bdmpr_rc == FSCK_OK) { /* nothing strange during pmap rebld */ bmap_recptr->free_blocks += dmap_freeblks; ag_num = bmap_recptr->dmap_1stblk >> agg_recptr->log2_blksperag; bmap_recptr->AGFree_tbl[ag_num] += dmap_freeblks; if (dmap_freeblks != nblocks) { /* not all of them are free */ bmap_recptr->AGActive[ag_num] = -1; } bmap_recptr->dmap_bufptr->nfree = dmap_freeblks; bdmpr_rc = dmap_tree_rebuild(stree_root_data); /* * write the page back to the device */ if (bdmpr_rc == FSCK_OK) { bdmpr_rc = blktbl_dmap_put(bmap_recptr->dmap_bufptr); } } } return (bdmpr_rc);}/***************************************************************************** * NAME: dmappg_verify * * FUNCTION: Validate the current dmap page. * * PARAMETERS: * stree_root_data - input - pointer to a variable in which to return * the the data value which should be stored * in the root of the tree of the page being * validated (and may also be the one stored * in the root of that tree) * * RETURNS: * success: FSCK_OK * failure: something else */int dmappg_verify(int8_t * stree_root_data){ int bdmpv_rc = FSCK_OK; uint32_t nblocks; uint32_t dmap_freeblks; uint32_t ag_num; /* * get the page to verify into the I/O buffer */ bdmpv_rc = blktbl_dmap_get(bmap_recptr->dmap_1stblk, &(bmap_recptr->dmap_bufptr)); if (bdmpv_rc == FSCK_OK) { /* the page is in the buffer */ if (bmap_recptr->dmap_bufptr->start != bmap_recptr->dmap_1stblk) { /* bad starting block */ bmap_recptr->dmap_other_error = -1; fsck_send_msg(fsck_DMAPBADSTRT, bmap_recptr->dmappg_ordno); } nblocks = MIN(BPERDMAP, (bmap_recptr->total_blocks - bmap_recptr->dmap_1stblk)); if (bmap_recptr->dmap_bufptr->nblocks != nblocks) { /* bad number of blocks */ bmap_recptr->dmap_other_error = -1; fsck_send_msg(fsck_DMAPBADNBLK, bmap_recptr->dmappg_ordno); } bdmpv_rc = dmap_pmap_verify(&dmap_freeblks); /* * subtract out any blocks which don't really exist but are * described by a dmap (phantom blocks always appear to be in use) */ agg_recptr->blocks_used_in_aggregate = agg_recptr->blocks_used_in_aggregate - (BPERDMAP - nblocks); if (bdmpv_rc == FSCK_OK) { /* nothing strange during pmap ver */ bmap_recptr->free_blocks += dmap_freeblks; ag_num = bmap_recptr->dmap_1stblk >> agg_recptr->log2_blksperag; bmap_recptr->AGFree_tbl[ag_num] += dmap_freeblks; if (dmap_freeblks != nblocks) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -