📄 fsckwsp.c
字号:
/* successful IAG allocation */ eiob_rc = alloc_wrksp(INODE_IO_BUFSIZE, dynstg_iobufs, I_am_logredo, (void **) &(agg_recptr->ino_buf_ptr)); } if (eiob_rc == FSCK_OK) { /* successful inode allocation */ agg_recptr->ino_buf_length = INODE_IO_BUFSIZE; agg_recptr->ino_buf_data_len = 0; agg_recptr->ino_buf_agg_offset = 0; agg_recptr->ino_buf_write = 0; eiob_rc = alloc_wrksp(NODE_IO_BUFSIZE, dynstg_iobufs, I_am_logredo, (void **) &(agg_recptr->node_buf_ptr)); } if (eiob_rc == FSCK_OK) { /* successful node allocation */ agg_recptr->node_buf_length = NODE_IO_BUFSIZE; agg_recptr->node_buf_data_len = 0; agg_recptr->node_agg_offset = 0; agg_recptr->node_buf_write = 0; eiob_rc = alloc_wrksp(NODE_IO_BUFSIZE, dynstg_iobufs, I_am_logredo, (void **) &(agg_recptr->dnode_buf_ptr)); } if (eiob_rc == FSCK_OK) { /* successful dnode allocation */ agg_recptr->dnode_buf_length = NODE_IO_BUFSIZE; agg_recptr->dnode_buf_data_len = 0; agg_recptr->dnode_agg_offset = 0; agg_recptr->dnode_buf_write = 0; eiob_rc = alloc_wrksp(MAPLEAF_IO_BUFSIZE, dynstg_iobufs, I_am_logredo, (void **) &(agg_recptr->mapleaf_buf_ptr)); } if (eiob_rc == FSCK_OK) { /* successful mapleaf allocation */ agg_recptr->mapleaf_buf_length = MAPLEAF_IO_BUFSIZE; agg_recptr->mapleaf_buf_data_len = 0; agg_recptr->mapleaf_agg_offset = 0; agg_recptr->mapleaf_buf_write = 0; eiob_rc = alloc_wrksp(MAPCTL_IO_BUFSIZE, dynstg_iobufs, I_am_logredo, (void **) &(agg_recptr->mapctl_buf_ptr)); } if (eiob_rc == FSCK_OK) { /* successful map control allocation */ agg_recptr->mapctl_buf_length = MAPCTL_IO_BUFSIZE; agg_recptr->mapctl_buf_data_len = 0; agg_recptr->mapctl_agg_offset = 0; agg_recptr->mapctl_buf_write = 0; eiob_rc = alloc_wrksp(BMAPLV_IO_BUFSIZE, dynstg_iobufs, I_am_logredo, (void **) &(agg_recptr->bmaplv_buf_ptr)); } if (eiob_rc == FSCK_OK) { /* successful map level allocation */ agg_recptr->bmaplv_buf_length = BMAPLV_IO_BUFSIZE; agg_recptr->bmaplv_buf_data_len = 0; agg_recptr->bmaplv_agg_offset = 0; agg_recptr->bmaplv_buf_write = 0; } return (eiob_rc);}/**************************************************************************** * NAME: establish_wsp_block_map * * FUNCTION: If the in-aggregate fsck workspace is available for use, * initialize it as the fsck workspace block map. * * Otherwise, obtain and initialize dynamic storage for the fsck * workspace block map. * * PARAMETERS: none * * NOTES: The fsck workspace block map is described in the aggregate record. * * If the in-aggregate fsck workspace is used, the aggregate record * fields describe the dedicated I/O buffer used for the fsck workspace * block map. Otherwise, they describe the entire workspace block * map in dynamic storage. * * RETURNS: * success: FSCK_OK * failure: something else */int establish_wsp_block_map(){ int ewbm_rc = FSCK_OK; int32_t blkmap_size_bytes; int32_t blkmap_size_in_pages; int32_t idx; int64_t this_device_offset; int I_am_logredo = 0; ewbm_rc = establish_wsp_block_map_ctl(); if (ewbm_rc != FSCK_OK) goto ewbm_exit; /* allocated and initialized blk map ctl page */ blkmap_size_bytes = agg_recptr->ondev_wsp_byte_length; agg_recptr->blkmp_pagecount = blkmap_size_bytes / BYTESPERPAGE; /* * whether or not we actually write to the on-disk * fsck workspace, this buffer represents it logically. */ agg_recptr->blkmp_agg_offset = agg_recptr->ondev_wsp_byte_offset + BYTESPERPAGE; agg_recptr->blkmp_blkmp_offset = 0; agg_recptr->blkmp_buf_data_len = 0; agg_recptr->blkmp_buf_write = 0; agg_recptr->blkmp_blkmp_offset = 0; agg_recptr->blkmp_buf_data_len = 0; agg_recptr->blkmp_buf_write = 0; if (agg_recptr->processing_readonly) { /* can't touch the aggregate */ ewbm_rc = alloc_wrksp(blkmap_size_bytes, dynstg_blkmap, I_am_logredo, (void **) &(agg_recptr->blkmp_buf_ptr)); if (ewbm_rc == FSCK_OK) { /* allocated and initialized block map */ wsp_dynstg_object = 0; wsp_dynstg_action = 0; agg_recptr->blkmp_buf_length = blkmap_size_bytes; agg_recptr->blkmp_buf_data_len = agg_recptr->blkmp_buf_length; } goto ewbm_exit; } /* use storage reserved for fsck in the aggregate */ ewbm_rc = alloc_wrksp(BLKMP_IO_BUFSIZE, dynstg_blkmap_buf, I_am_logredo, (void **) &(agg_recptr->blkmp_buf_ptr)); if (ewbm_rc != FSCK_OK) goto ewbm_exit; /* allocated and initialized block map */ agg_recptr->blkmp_buf_length = BLKMP_IO_BUFSIZE; agg_recptr->blkmp_buf_data_len = agg_recptr->blkmp_buf_length; ewbm_rc = blkmap_put_ctl_page(agg_recptr->blkmp_ctlptr); if (ewbm_rc != FSCK_OK) goto ewbm_exit; /* successful write to Block Map Control Page */ /* this is guaranteed (by mkfs) to be an even number */ blkmap_size_in_pages = blkmap_size_bytes / BYTESPERPAGE; /* Swap to little-endian */ ujfs_swap_fsck_blk_map_page(agg_recptr->blkmp_buf_ptr); for (idx = 1; ((idx < blkmap_size_in_pages) && (ewbm_rc == FSCK_OK)); idx++) { /* for each map page (after the control page) */ this_device_offset = agg_recptr->ondev_wsp_byte_offset + (idx * BYTESPERPAGE); /* * write the initialized buffer page to * the map page on disk */ ewbm_rc = ujfs_rw_diskblocks(Dev_IOPort, this_device_offset, BYTESPERPAGE, (void *) agg_recptr->blkmp_buf_ptr, PUT); if (ewbm_rc != FSCK_OK) { /* I/O failure */ /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 1); /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, ewbm_rc, ewbm_rc, fsck_WRITE, (long long)this_device_offset, BYTESPERPAGE, -1); } } /* Swap back to cpu-endian */ ujfs_swap_fsck_blk_map_page(agg_recptr->blkmp_buf_ptr); ewbm_exit: return (ewbm_rc);}/**************************************************************************** * NAME: establish_wsp_block_map_ctl * * FUNCTION: If the in-aggregate fsck workspace is available for use, * initialize the first page as the fsck workspace block map control * page. * * Otherwise, obtain and initialize dynamic storage for the fsck * workspace block map control page. * * PARAMETERS: none * * NOTES: The fsck workspace block map is described in the aggregate record. * * If the in-aggregate fsck workspace is used, the aggregate record * fields describe the dedicated I/O buffer used for the fsck workspace * block map. Otherwise, they describe the entire workspace block * map in dynamic storage. * * RETURNS: * success: FSCK_OK * failure: something else */int establish_wsp_block_map_ctl(){ int ewbmc_rc = FSCK_OK; time_t Current_Time; int64_t this_device_offset = 0; int I_am_logredo = 0; ewbmc_rc = alloc_wrksp(sizeof (struct fsck_blk_map_hdr), dynstg_blkmap_hdr, I_am_logredo, (void **) &(agg_recptr->blkmp_ctlptr)); if (ewbmc_rc == FSCK_OK) { /* allocated and initialized blk map ctl page */ /* fill eyecatcher */ strncpy(agg_recptr->blkmp_ctlptr->hdr.eyecatcher, fbmh_eyecatcher_string, strlen(fbmh_eyecatcher_string)); agg_recptr->blkmp_ctlptr->hdr.super_buff_addr = (char *) sb_ptr; agg_recptr->blkmp_ctlptr->hdr.agg_record_addr = (char *) agg_recptr; agg_recptr->blkmp_ctlptr->hdr.bmap_record_addr = (char *) bmap_recptr; agg_recptr->blkmp_ctlptr->hdr.fscklog_full = agg_recptr->fscklog_full; agg_recptr->blkmp_ctlptr->hdr.fscklog_buf_allocated = agg_recptr->fscklog_buf_allocated; agg_recptr->blkmp_ctlptr->hdr.fscklog_buf_alloc_err = agg_recptr->fscklog_buf_alloc_err; agg_recptr->blkmp_ctlptr->hdr.fscklog_agg_offset = agg_recptr->ondev_fscklog_byte_offset; Current_Time = time(NULL); fsck_DateTime = localtime(&Current_Time); sprintf(&(agg_recptr->blkmp_ctlptr->hdr.start_time[0]), "%d/%d/%d %d:%02d:%02d", fsck_DateTime->tm_mon + 1, fsck_DateTime->tm_mday, (fsck_DateTime->tm_year + 1900), fsck_DateTime->tm_hour, fsck_DateTime->tm_min, fsck_DateTime->tm_sec); if (!(agg_recptr->processing_readonly)) { /* * use storage reserved for fsck in the * aggregate */ ewbmc_rc = blkmap_put_ctl_page(agg_recptr->blkmp_ctlptr); if (ewbmc_rc != FSCK_OK) { /* I/O failure */ /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 1); /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, ewbmc_rc, ewbmc_rc, fsck_WRITE, (long long) this_device_offset, BYTESPERPAGE, -1); } } } return (ewbmc_rc);}/***************************************************************************** * NAME: extent_1stref_chk * * FUNCTION: Determine whether the given extent contains the first reference * to a multiply-allocated block. If it does, perform duplicate * allocation processing on the owning inode. * * PARAMETERS: * first_block - input - ordinal number of the first block in the extent * to check * last_block - input - ordinal number of the last block in the extent * to check * is_EA - input - !0 => the extent contains an inode's EA * 0 => the extent contains something else * msg_info_ptr - input - pointer to a data area containing information * needed to issue messages for this extent * ino_recptr - input - pointer to the fsck inode record describing the * inode to which this extent is allocated * * NOTES: As fsck scans the inodes sequentially, recording the blocks * allocated, it doesn't know a particular block is multiply-allocated * until the second reference is detected. At that time the first * reference to the block is unresolved since no list of owners is * built (only a count of owners, in which a 1 in the bit map * represents a count of 1). * * After all inodes have been scanned and their block allocations * recorded, if any multiply-allocated blocks have been detected, the * inodes are scanned sequentially again until all first references to * multiply-allocated blocks are resolved. This routine is invoked * during that rescan. * * RETURNS: * success: FSCK_OK * failure: something else */int extent_1stref_chk(int64_t first_block, int64_t last_block, int8_t is_EA, int8_t is_ACL, struct fsck_ino_msg_info *msg_info_ptr, struct fsck_inode_record *ino_recptr){ int eq_rc = FSCK_OK; uint32_t size_of_dup_range = 0; int dups_detected = 0; struct dupall_blkrec *blkrec; while (agg_recptr->unresolved_1stref_count) { blkrec = dupall_find_blkrec(first_block, last_block); if (!blkrec) break; if (blkrec->first_ref_resolved) { if (blkrec->last_blk <= last_block) { first_block = blkrec->last_blk + 1; continue; } break; } /* * If the record goes outside this extent, we need to split * it, since we are only interested in the intersection of * the record and this extent */ if ((blkrec->first_blk < first_block) || (blkrec->last_blk > last_block)) { eq_rc = blkall_split_blkrec(blkrec, first_block, last_block); if (eq_rc) return eq_rc; /* * Check if the split caused the current record to * precede the extent we are processing */ if (blkrec->first_blk < first_block) continue; } dups_detected = 1; blkrec->first_ref_resolved = 1; agg_recptr->unresolved_1stref_count--; if (msg_info_ptr) { size_of_dup_range = blkrec->last_blk - blkrec->first_blk + 1; fsck_send_msg(fsck_DUPBLKREF, size_of_dup_range, (long long) blkrec->first_blk, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } if (dups_detected && msg_info_ptr) { ino_recptr->involved_in_dups = 1; fsck_send_msg(fsck_DUPBLKREFS, fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); if (!(inode_is_metadata(ino_recptr))) { agg_recptr->corrections_needed = 1; if (is_EA) ino_recptr->clr_ea_fld = 1; else if (is_ACL) ino_recptr->clr_acl_fld = 1; else ino_recptr->selected_to_rls = 1; } } return (FSCK_OK);}/**************************************************************************** * NAME: blkall_ref_check * * FUNCTION: Determine whether the given blocks are multiply-allocated and, if * so, whether the first reference to it is unresolved. (In this * case, the current reference must be the first reference.) * * PARAMETERS: * first_block - input - ordinal number of the first filesystem block to * be checked * last_block - input - ordinal number of the last filesystem block to * be checked * * RETURNS: * success: FSCK_OK * failure: something else */int blkall_ref_check(int64_t first_block, int64_t last_block){ return extent_1stref_chk(first_block, last_block, 0, 0, 0, 0);}/***************************************************************************** * NAME: extent_record_dupchk * * FUNCTION: Validate that the block number in the given extent are valid * within the range valid for the aggregate (after the reserved * space and fixed metadata and before the fsck workspace), * record that the blocks are allocated, determine whether any * prior allocations of the blocks have been recorded and, if * so, perform duplicate allocation processing on the owning inode. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -