📄 fsckpfs.c
字号:
* message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_READ_BMPDM, bdg_rc, fsck_READ, (long long)agg_recptr->bmapdm_agg_offset, agg_recptr->bmapdm_buf_length, agg_recptr->bmapdm_buf_data_len); bdg_rc = FSCK_FAILED_READ_BMPDM; } bdg_exit: return (bdg_rc);}/***************************************************************************** * NAME: blktbl_dmap_put * * FUNCTION: If the current fsck session has write access to the aggregate, * note, in the fsck workspace, that the current fsck dmap * buffer has been modified and should be written to the device * in the next flush operation on this buffer. * * PARAMETERS: * dmap_page_ptr - input - address of the dmap page, in the fsck buffer, * which has been modified. * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_dmap_put(struct dmap *dmap_page_ptr){ int bdp_rc = FSCK_OK; if (agg_recptr->processing_readwrite) { agg_recptr->bmapdm_buf_write = 1; } return (bdp_rc);}/***************************************************************************** * NAME: blktbl_dmaps_flush * * FUNCTION: If the current fsck session has write access to the aggregate * and the current dmap buffer has been updated since the most * recent read operation, write the buffer contents to the device. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_dmaps_flush(){ int bdf_rc = FSCK_OK; uint32_t bytes_written; struct dmap *dmap_t_ptr; if (agg_recptr->bmapdm_buf_write) { /* buffer has been updated since * most recent write */ /* 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); bdf_rc = readwrite_device(agg_recptr->bmapdm_agg_offset, agg_recptr->bmapdm_buf_data_len, &bytes_written, (void *) agg_recptr->bmapdm_buf_ptr, fsck_WRITE); dmap_t_ptr = (struct dmap *) agg_recptr->bmapdm_buf_ptr; swap_multiple(ujfs_swap_dmap, dmap_t_ptr, 4); if (bdf_rc == FSCK_OK) { if (bytes_written == agg_recptr->bmapdm_buf_data_len) { /* buffer has been written to * the device and won't need to be * written again unless/until the * buffer contents have been altered again. */ agg_recptr->bmapdm_buf_write = 0; } else { /* didn't write the correct number of bytes */ /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 6); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_BMPDM_BADFLUSH, bdf_rc, fsck_WRITE, (long long) agg_recptr->bmapdm_agg_offset, agg_recptr->bmapdm_buf_data_len, bytes_written); bdf_rc = FSCK_FAILED_BMPDM_BADFLUSH; } } else { /* else the write was not successful */ /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 7); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_BMPDM_FLUSH, bdf_rc, fsck_WRITE, (long long) agg_recptr->bmapdm_agg_offset, agg_recptr->bmapdm_buf_data_len, agg_recptr->bmapdm_buf_data_len, bytes_written); bdf_rc = FSCK_FAILED_BMPDM_FLUSH; } } return (bdf_rc);}/***************************************************************************** * NAME: blktbl_Ln_page_get * * FUNCTION: Read the JFS Block Map page describing the specified aggregate * block at the specified summary level into and/or locate the * locate the requested JFS Block Map page describing the specified * aggregate block at the specified summary level in the * fsck Level n page buffer. * * PARAMETERS: * level - input - Summary level of the page to get * for_block - input - ordinal number of the aggregate block * whose summary page is needed * addr_Ln_page_ptr - input - pointer to a variable in which to return * the address of the requested page in an * fsck buffer * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_Ln_page_get(int8_t level, int64_t for_block, struct dmapctl **addr_Ln_page_ptr){ int blpg_rc = FSCK_OK; int64_t Lnpg_logical_fsblk_offset; int64_t Lnpg_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; Lnpg_logical_fsblk_offset = BLKTOCTL(for_block, agg_recptr->log2_blksperpg, level); Lnpg_logical_byte_offset = Lnpg_logical_fsblk_offset * sb_ptr->s_bsize; *addr_Ln_page_ptr = NULL; if (Lnpg_logical_byte_offset >= agg_recptr->bmaplv_logical_offset) { last_in_buffer = agg_recptr->bmaplv_logical_offset + agg_recptr->bmaplv_buf_data_len; if ((Lnpg_logical_byte_offset + (int64_t) sizeof (struct dmapctl)) <= last_in_buffer) { /* * the one we want is already in the buffer */ *addr_Ln_page_ptr = (struct dmapctl *) (agg_recptr->bmaplv_buf_ptr + (Lnpg_logical_byte_offset - agg_recptr->bmaplv_logical_offset)); } } if (*addr_Ln_page_ptr != NULL) goto blpg_exit; /* we have to read it in */ /* perform any pending writes */ blpg_rc = blktbl_Ln_pages_flush(); if (blpg_rc != FSCK_OK) goto blpg_exit; /* flush worked ok */ if (agg_recptr->primary_ait_4part1) { which_it = fsck_primary; } else { which_it = fsck_secondary; } blpg_rc = ait_special_read_ext1(which_it); if (blpg_rc != FSCK_OK) { report_readait_error(blpg_rc, FSCK_FAILED_CANTREADAITEXTG, which_it); blpg_rc = FSCK_FAILED_CANTREADAITEXTG; goto blpg_exit; } /* got the first agg extent */ bmap_inoptr = (struct dinode *)(agg_recptr->ino_buf_ptr + BMAP_I * sizeof (struct dinode)); blpg_rc = xTree_search(bmap_inoptr, Lnpg_logical_fsblk_offset, &xad_ptr, &offset_found); if (blpg_rc != FSCK_OK) goto blpg_exit; /* nothing extraordinary happened */ if (!offset_found) { /* didn't find it! */ blpg_rc = FSCK_INTERNAL_ERROR_52; goto blpg_exit; } /* we have the xad which describes the page */ ext_logical_byte_offset = offsetXAD(xad_ptr) * sb_ptr->s_bsize; ext_byte_offset = addressXAD(xad_ptr) * sb_ptr->s_bsize; agg_recptr->bmaplv_agg_offset = ext_byte_offset + Lnpg_logical_byte_offset - ext_logical_byte_offset; blpg_rc = readwrite_device(agg_recptr->bmaplv_agg_offset, agg_recptr->bmaplv_buf_length, &(agg_recptr->bmaplv_buf_data_len), (void *) agg_recptr->bmaplv_buf_ptr, fsck_READ); if (blpg_rc == FSCK_OK) { /* got the page */ /* swap if on big endian machine */ ujfs_swap_dmapctl((struct dmapctl *)agg_recptr->bmaplv_buf_ptr); agg_recptr->bmaplv_current_level = level; agg_recptr->bmaplv_logical_offset = Lnpg_logical_byte_offset; *addr_Ln_page_ptr = (struct dmapctl *) agg_recptr->bmaplv_buf_ptr; } else { /* * message to user */ fsck_send_msg(fsck_URCVREAD, fsck_ref_msg(fsck_metadata), Vol_Label); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_READ_BMPLV, blpg_rc, fsck_READ, (long long)agg_recptr->bmaplv_agg_offset, agg_recptr->bmaplv_buf_length, agg_recptr->bmaplv_buf_data_len); blpg_rc = FSCK_FAILED_READ_BMPLV; } blpg_exit: return (blpg_rc);}/***************************************************************************** * NAME: blktbl_Ln_page_put * * FUNCTION: If the current fsck session has write access to the aggregate, * note, in the fsck workspace, that the current fsck Level n * buffer has been modified and should be written to the device * in the next flush operation on this buffer. * * PARAMETERS: * Ln_page_ptr - input - Address, in an fsck buffer, of the block map * summary page which has been modified. * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_Ln_page_put(struct dmapctl *Ln_page_ptr){ int blpp_rc = FSCK_OK; if (agg_recptr->processing_readwrite) { agg_recptr->bmaplv_buf_write = 1; } return (blpp_rc);}/***************************************************************************** * NAME: blktbl_Ln_pages_flush * * FUNCTION: If the current fsck session has write access to the aggregate * and the current Level n Page buffer has been updated since * the most recent read operation, write the buffer contents to * the device. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int blktbl_Ln_pages_flush(){ int blpf_rc = FSCK_OK; uint32_t bytes_written; if (!agg_recptr->bmaplv_buf_write) goto blpf_exit; /* buffer has been updated since * most recent write */ /* swap if on big endian machine */ ujfs_swap_dmapctl((struct dmapctl *) agg_recptr->bmaplv_buf_ptr); blpf_rc = readwrite_device(agg_recptr->bmaplv_agg_offset, agg_recptr->bmaplv_buf_data_len, &bytes_written, (void *) agg_recptr->bmaplv_buf_ptr, fsck_WRITE); ujfs_swap_dmapctl((struct dmapctl *) agg_recptr->bmaplv_buf_ptr); if (blpf_rc == FSCK_OK) { if (bytes_written == agg_recptr->bmaplv_buf_data_len) { /* buffer has been written to * the device and won't need to be * written again unless/until the * buffer contents have been altered again. */ agg_recptr->bmaplv_buf_write = 0; } else { /* didn't write the correct number of bytes */ /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 8); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_BMPLV_BADFLUSH, blpf_rc, fsck_WRITE, (long long) agg_recptr->bmaplv_agg_offset, agg_recptr->bmaplv_buf_data_len, bytes_written); blpf_rc = FSCK_FAILED_BMPLV_BADFLUSH; } } else { /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 9); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_BMPLV_FLUSH, blpf_rc, fsck_WRITE, (long long) agg_recptr->bmaplv_agg_offset, agg_recptr->bmaplv_buf_data_len, bytes_written); blpf_rc = FSCK_FAILED_BMPLV_FLUSH; } blpf_exit: return (blpf_rc);}/************************************************************************** * NAME: close_volume * * FUNCTION: Flush all data to disk and close the device containing the * aggregate. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int close_volume(){ int rc; rc = ujfs_flush_dev(Dev_IOPort); if (fclose(Dev_IOPort)) return ERROR_INVALID_HANDLE; return rc;}/***************************************************************************** * NAME: dnode_get * * FUNCTION: Read the requested dnode page into and/or locate the requested * dnode page in the fsck dnode buffer. * * PARAMETERS: * dnode_fsblk_offset - input - offset, in aggregate blocks, into the * aggregate of the dnode to read * dnode_length - input - number of bytes in the dnode * addr_dtpage_ptr - input - pointer to a variable in which to return * the address of the requested dnode in an * fsck buffer * * RETURNS: * success: FSCK_OK * failure: something else */int dnode_get(int64_t dnode_fsblk_offset, uint32_t dnode_length, dtpage_t ** addr_dtpage_ptr){ int dnodg_rc = FSCK_OK; int64_t dnode_start_byte, dnode_end_byte; dtpage_t *dtp; dnode_start_byte = dnode_fsblk_offset * sb_ptr->s_bsize; dnode_end_byte = dnode_start_byte + dnode_length - 1; if ((agg_recptr->ondev_wsp_fsblk_offset != 0) && (dnode_fsblk_offset > agg_recptr->ondev_wsp_fsblk_offset)) { /* * the offset is beyond the range * valid for fileset objects */ /* * This case is not caused by an I/O error, but by
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -