📄 fsckpfs.c
字号:
if (agg_recptr->processing_readwrite) { /* have write access */ bmgcp_rc = readwrite_device(agg_recptr->ondev_wsp_byte_offset, BYTESPERPAGE, &bytes_read, (void *) agg_recptr->blkmp_ctlptr, fsck_READ); if (bmgcp_rc == FSCK_OK) { /* swap if on big endian machine */ ujfs_swap_fsck_blk_map_hdr(agg_recptr->blkmp_ctlptr); if (bytes_read != (uint32_t) BYTESPERPAGE) { /* didn't read correct number of bytes */ /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, FSCK_BADREAD_FBLKMP, bmgcp_rc, fsck_READ, (long long) agg_recptr->ondev_wsp_byte_offset, BYTESPERPAGE, bytes_read); bmgcp_rc = FSCK_BADREAD_FBLKMP; } } else { /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, FSCK_BADREAD_FBLKMP, bmgcp_rc, fsck_READ, (long long) agg_recptr->ondev_wsp_byte_offset, BYTESPERPAGE, bytes_read); bmgcp_rc = FSCK_BADREAD_FBLKMP; } } return (bmgcp_rc);}/***************************************************************************** * NAME: blkmap_get_page * * FUNCTION: Read the requested fsck workspace block map page into and/or * locate the requested fsck workspace block map page in the * fsck block map buffer. * * PARAMETERS: * page_num - input - ordinal number of the fsck workspace * block map page which is needed * addr_page_ptr - input - pointer to a variable in which to return * the address of the page in an fsck buffer * * RETURNS: * success: FSCK_OK * failure: something else */int blkmap_get_page(int64_t page_num, struct fsck_blk_map_page **addr_page_ptr){ int bgp_rc = FSCK_OK; int64_t page_start_byte, page_end_byte; struct fsck_blk_map_page *fsck_bmpt_ptr; page_start_byte = page_num * BYTESPERPAGE; page_end_byte = page_start_byte + BYTESPERPAGE - 1; if ((page_start_byte >= agg_recptr->blkmp_blkmp_offset) && (page_end_byte <= (agg_recptr->blkmp_blkmp_offset + agg_recptr->blkmp_buf_data_len))) { /* the desired page is already in the buffer */ *addr_page_ptr = (struct fsck_blk_map_page *) ((char *) agg_recptr-> blkmp_buf_ptr + (page_start_byte - agg_recptr-> blkmp_blkmp_offset)); } else { /* else need to read it in from dasd */ if (!agg_recptr->processing_readwrite) { /* this isn't supposed * to happen. If we don't have write access * to the aggregate then we're always supposed * to get a hit in the buffer! */ bgp_rc = FSCK_INTERNAL_ERROR_6; } else { /* we have read/write access */ /* if the buffer has been modified, write it to dasd */ bgp_rc = blkmap_flush(); if (bgp_rc == FSCK_OK) { /* successful write */ agg_recptr->blkmp_blkmp_offset = page_start_byte; /* * The byte offset in the fsck block map plus * one page of control information plus the * aggregate bytes which precede the on-dasd * fsck workspace */ agg_recptr->blkmp_agg_offset = page_start_byte + (BYTESPERPAGE * 1) + agg_recptr->ondev_wsp_byte_offset; bgp_rc = readwrite_device(agg_recptr-> blkmp_agg_offset, agg_recptr-> blkmp_buf_length, &(agg_recptr-> blkmp_buf_data_len), (void *) agg_recptr-> blkmp_buf_ptr, fsck_READ); if (bgp_rc == FSCK_OK) { /* successful read */ /* swap if on big endian machine */ fsck_bmpt_ptr = agg_recptr->blkmp_buf_ptr; swap_multiple (ujfs_swap_fsck_blk_map_page, fsck_bmpt_ptr, 4); if (agg_recptr->blkmp_buf_data_len >= BYTESPERPAGE) { *addr_page_ptr = agg_recptr->blkmp_buf_ptr; } else { /* but didn't get enough to continue */ /* * message to user */ fsck_send_msg(fsck_URCVREAD, fsck_ref_msg(fsck_metadata), Vol_Label); /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, FSCK_FAILED_BADREAD_FBLKMP, bgp_rc, fsck_READ, (long long)agg_recptr->blkmp_agg_offset, agg_recptr->blkmp_buf_length, agg_recptr->blkmp_buf_data_len); bgp_rc = FSCK_FAILED_BADREAD_FBLKMP; } } else { /* read failed */ /* * message to user */ fsck_send_msg(fsck_URCVREAD, fsck_ref_msg(fsck_metadata), Vol_Label); /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, FSCK_FAILED_READ_FBLKMP, bgp_rc, fsck_READ, (long long)agg_recptr->blkmp_agg_offset, agg_recptr->blkmp_buf_length, agg_recptr->blkmp_buf_data_len); bgp_rc = FSCK_FAILED_READ_FBLKMP; } } } } return (bgp_rc);}/***************************************************************************** * NAME: blkmap_put_ctl_page * * FUNCTION: If the current fsck session has write access to the aggregate, * write the contents of the given buffer over the current fsck * fsck workspace block map control page on the device. * * PARAMETERS: * blk_ctlptr - input - pointer to the buffer which should be written * over the current fsck workspace block map * control page. * * NOTES: Unlike most _put_ routines in this module, blkmap_put_ctl_page * actually writes to the device. This is done because the block * map control page contains state and footprint information which * provide crucial serviceability should the fsck session be * interrupted. * * RETURNS: * success: FSCK_OK * failure: something else */int blkmap_put_ctl_page(struct fsck_blk_map_hdr *blk_ctlptr){ int bmpcp_rc = FSCK_OK; uint32_t bytes_written; if (agg_recptr->processing_readwrite) { /* have write access */ /* swap if on big endian machine */ ujfs_swap_fsck_blk_map_hdr(agg_recptr->blkmp_ctlptr); bmpcp_rc = readwrite_device(agg_recptr->ondev_wsp_byte_offset, BYTESPERPAGE, &bytes_written, (void *) agg_recptr->blkmp_ctlptr, fsck_WRITE); ujfs_swap_fsck_blk_map_hdr(agg_recptr->blkmp_ctlptr); if (bmpcp_rc == FSCK_OK) { if (bytes_written != (uint32_t) BYTESPERPAGE) { /* didn't write correct number of bytes */ /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 4); /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, FSCK_FAILED_BADWRITE_FBLKMP, bmpcp_rc, fsck_WRITE, (long long)agg_recptr->ondev_wsp_byte_offset, BYTESPERPAGE, bytes_written); bmpcp_rc = FSCK_FAILED_BADWRITE_FBLKMP; } } else { /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 5); /* * message to debugger */ fsck_send_msg(fsck_ERRONWSP, FSCK_FAILED_WRITE_FBLKMP, bmpcp_rc, fsck_WRITE, (long long)agg_recptr->ondev_wsp_byte_offset, BYTESPERPAGE, bytes_written); bmpcp_rc = FSCK_FAILED_WRITE_FBLKMP; } /* end else the write was not successful */ } return (bmpcp_rc);}/***************************************************************************** * NAME: blkmap_put_page * * FUNCTION: If the current fsck session has write access to the aggregate, * note, in the fsck workspace, that the current fsck workspace * block map buffer has been modified and should be written to * the device in the next flush operation on this buffer. * * PARAMETERS: * page_num - input - ordinal number of the page in the fsck workspace * block map to write from the buffer to the device * * RETURNS: * success: FSCK_OK * failure: something else */int blkmap_put_page(int64_t page_num){ int bpp_rc = FSCK_OK; if (agg_recptr->processing_readwrite) { agg_recptr->blkmp_buf_write = 1; } return (bpp_rc);}/***************************************************************************** * NAME: blktbl_ctl_page_put * * FUNCTION: If the current fsck session has write access to the aggregate, * note, in the fsck workspace, that the current JFS Block Map * control page buffer has been modified and should be written * to the device in the next flush operation on this buffer. * * PARAMETERS: * ctlpage_ptr - input - the address, in an fsck buffer, of the page * which has been modified. * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_ctl_page_put(struct dbmap *ctlpage_ptr){ int bcpp_rc = FSCK_OK; if (agg_recptr->processing_readwrite) { /* swap if on big endian machine */ ujfs_swap_dbmap(ctlpage_ptr); bcpp_rc = mapctl_put((void *) ctlpage_ptr); } return (bcpp_rc);}/***************************************************************************** * NAME: blktbl_dmap_get * * FUNCTION: Read the JFS Block Table dmap page describing the specified * aggregate block into and/or locate the JFS Block Table dmap * locate the requested page describing the specified * aggregate block in the fsck dmap buffer. * * PARAMETERS: * for_block - input - ordinal number of the aggregate block * whose dmap page is needed * addr_dmap_page_ptr - input - pointer to a variable in which to return * the address of the found dmap page in * an fsck buffer * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_dmap_get(int64_t for_block, struct dmap **addr_dmap_page_ptr){ int bdg_rc = FSCK_OK; int64_t dmp_logical_fsblk_offset; int64_t dmp_logical_byte_offset; int64_t ext_logical_byte_offset; int64_t ext_byte_offset; int64_t last_in_buffer; struct dinode *bmap_inoptr; xad_t *xad_ptr; int8_t offset_found; int which_it; uint32_t bytes_read, ext_bytes_left; int64_t ext_bytes, offset_into_extent; struct dmap *dmap_t_ptr; dmp_logical_fsblk_offset = BLKTODMAP(for_block, agg_recptr->log2_blksperpg); dmp_logical_byte_offset = dmp_logical_fsblk_offset * sb_ptr->s_bsize; *addr_dmap_page_ptr = NULL; if (dmp_logical_byte_offset >= agg_recptr->bmapdm_logical_offset) { last_in_buffer = agg_recptr->bmapdm_logical_offset + agg_recptr->bmapdm_buf_data_len - 1; if ((dmp_logical_byte_offset + (int64_t) sizeof (struct dmap) - 1) <= last_in_buffer) { /* * the one we want is already in the buffer */ *addr_dmap_page_ptr = (struct dmap *) (agg_recptr->bmapdm_buf_ptr + dmp_logical_byte_offset - agg_recptr->bmapdm_logical_offset); } } if (*addr_dmap_page_ptr != NULL) goto bdg_exit; /* we have to read it in */ /* perform any pending writes */ bdg_rc = blktbl_dmaps_flush(); if (bdg_rc != FSCK_OK) goto bdg_exit; /* flush worked ok */ if (agg_recptr->primary_ait_4part1) { which_it = fsck_primary; } else { which_it = fsck_secondary; } bdg_rc = ait_special_read_ext1(which_it); if (bdg_rc != FSCK_OK) { report_readait_error(bdg_rc, FSCK_FAILED_CANTREADAITEXTF, which_it); bdg_rc = FSCK_FAILED_CANTREADAITEXTF; goto bdg_exit; } /* got the first agg extent */ bmap_inoptr = (struct dinode *)(agg_recptr->ino_buf_ptr + BMAP_I * sizeof (struct dinode)); bdg_rc = xTree_search(bmap_inoptr, dmp_logical_fsblk_offset, &xad_ptr, &offset_found); if (bdg_rc != FSCK_OK) goto bdg_exit; /* nothing extraordinary happened */ if (!offset_found) { bdg_rc = FSCK_INTERNAL_ERROR_51; goto bdg_exit; } /* we have the xad which describes the dmap */ ext_logical_byte_offset = offsetXAD(xad_ptr) * sb_ptr->s_bsize; ext_byte_offset = addressXAD(xad_ptr) * sb_ptr->s_bsize; agg_recptr->bmapdm_agg_offset = ext_byte_offset + dmp_logical_byte_offset - ext_logical_byte_offset; bdg_rc = readwrite_device(agg_recptr->bmapdm_agg_offset, agg_recptr->bmapdm_buf_length, &bytes_read, (void *) agg_recptr->bmapdm_buf_ptr, fsck_READ); if (bdg_rc == FSCK_OK) { /* swap if on big endian machine */ dmap_t_ptr = (struct dmap *)agg_recptr->bmapdm_buf_ptr; swap_multiple(ujfs_swap_dmap, dmap_t_ptr, 4); agg_recptr->bmapdm_logical_offset = dmp_logical_byte_offset; *addr_dmap_page_ptr = (struct dmap *)agg_recptr->bmapdm_buf_ptr; /* * we need to set the buffer data length to the number of * bytes with actual bmap data. That is, we may have read * beyond the end of the extent, and if so, we need to * ignore the tag-along data. */ ext_bytes = lengthXAD(xad_ptr) * sb_ptr->s_bsize; offset_into_extent = dmp_logical_byte_offset - ext_logical_byte_offset; ext_bytes_left = ext_bytes - offset_into_extent; agg_recptr->bmapdm_buf_data_len = MIN(bytes_read, ext_bytes_left); } else { /* * message to user */ fsck_send_msg(fsck_URCVREAD, fsck_ref_msg(fsck_metadata), Vol_Label); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -