📄 fsckpfs.c
字号:
agg_recptr->fais.rootleaf_imap = 0; /* * get the first leaf (xtpage) of the imap into the mapleaf buffer * * Note: if the imap B+ Tree has a root-leaf then the * first (and only) leaf is located in the dinode. */ /* * save inode_get from having to read an * iag as an intermediate step. */ iaggf_rc = ait_special_read_ext1(which_ait); if (iaggf_rc != FSCK_OK) { /* read ait failed */ report_readait_error(iaggf_rc, FSCK_FAILED_CANTREADAITEXTJ, which_ait); iaggf_rc = FSCK_FAILED_CANTREADAITEXTJ; } else { /* got the inode extent */ if (!is_aggregate) { /* after the fileset inode table */ if (agg_recptr->fset_imap.imap_is_rootleaf) { /* it's a root-leaf */ agg_recptr->fais.rootleaf_imap = -1; /* read the imap inode into the inode buffer */ iaggf_rc = inode_get(it_tbl_is_agg_owned, which_ait, it_number, &imap_inoptr); if (iaggf_rc != FSCK_OK) { /* something went wrong */ iaggf_rc = FSCK_FAILED_AGFS_READ5; } } } else { /* want the aggregate inode table */ if (agg_recptr->agg_imap.imap_is_rootleaf) { /* it's a rootleaf */ agg_recptr->fais.rootleaf_imap = -1; /* read the imap inode into the inode buffer */ iaggf_rc = inode_get(it_tbl_is_agg_owned, it_number, AGGREGATE_I, &imap_inoptr); if (iaggf_rc != FSCK_OK) { /* something went wrong */ iaggf_rc = FSCK_FAILED_AGFS_READ5; } } } } if ((iaggf_rc == FSCK_OK) && (agg_recptr->fais.rootleaf_imap)) { /* * root-leaf imap and we have the inode */ /* copy the inode into the imap leaf buf */ memcpy((void *) (agg_recptr->mapleaf_buf_ptr), (void *) imap_inoptr, sizeof (struct dinode)); agg_recptr->mapleaf_buf_data_len = 0; agg_recptr->mapleaf_agg_offset = 0; agg_recptr->mapleaf_for_aggregate = is_aggregate; agg_recptr->mapleaf_which_it = it_number; imap_inoptr = (struct dinode *) (agg_recptr->mapleaf_buf_ptr); agg_recptr->fais.this_mapleaf = (xtpage_t *) & (imap_inoptr->di_btroot); } if ((iaggf_rc == FSCK_OK) && (!agg_recptr->fais.rootleaf_imap)) { /* * something below the root */ if (!is_aggregate) { /* after the fileset inode table */ /* get the first leaf into the mapleaf buffer */ iaggf_rc = imapleaf_get(agg_recptr->fset_imap. first_leaf_offset, &(agg_recptr->fais.this_mapleaf)); } else { /* must want the aggregate inode table */ /* get the first leaf into the mapleaf buffer */ iaggf_rc = imapleaf_get(agg_recptr->agg_imap.first_leaf_offset, &(agg_recptr->fais.this_mapleaf)); } } if (iaggf_rc == FSCK_OK) { /* the first imap leaf is in the buf */ /* first in the leaf */ agg_recptr->fais.iagidx_now = XTENTRYSTART; agg_recptr->fais.iagidx_max = agg_recptr->fais.this_mapleaf->header.nextindex - 1; /* * get the first iag of the imap into the iag buffer */ iaggf_rc = iags_flush(); if (iaggf_rc == FSCK_OK) { /* flushed ok */ xadptr = &(agg_recptr->fais.this_mapleaf-> xad[agg_recptr->fais.iagidx_now]); /* * the first iag is preceded by the IT control page. */ agg_recptr->iag_agg_offset = (sb_ptr->s_bsize * addressXAD(xadptr)) + sizeof (struct dinomap); agg_recptr->iag_buf_1st_inode = agg_recptr->fais.this_inoidx; agg_recptr->iag_fsnum = it_number; agg_recptr->iag_for_aggregate = is_aggregate; agg_recptr->iag_fsnum = it_number; iaggf_rc = readwrite_device(agg_recptr->iag_agg_offset, agg_recptr->iag_buf_length, &(agg_recptr-> iag_buf_data_len), (void *) (agg_recptr-> iag_buf_ptr), fsck_READ); /* swap if on big endian machine */ ujfs_swap_iag((struct iag *) agg_recptr->iag_buf_ptr); } } if (iaggf_rc == FSCK_OK) { /* first iag is in iag buffer */ agg_recptr->fais.iagptr = (struct iag *) agg_recptr->iag_buf_ptr; agg_recptr->fais.extidx_now = 0; agg_recptr->fais.extidx_max = EXTSPERIAG - 1; *addr_iag_ptr = agg_recptr->fais.iagptr; } 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_BADREAD_IAG, iaggf_rc, fsck_READ, (long long) agg_recptr->iag_agg_offset, agg_recptr->iag_buf_length, agg_recptr->iag_buf_data_len); iaggf_rc = FSCK_FAILED_BADREAD_IAG; } return (iaggf_rc);}/***************************************************************************** * NAME: iag_get_next * * FUNCTION: Read the next iag in the specified inode table into and/or * locate the next iag in the specified inode table in the * fsck iag buffer. * * PARAMETERS: * addr_iag_ptr - input - pointer to a variable in which to return * the address, in an fsck buffer, of the next * iag in the aggregate inode table currently * being traversed. * * RETURNS: * success: FSCK_OK * failure: something else */int iag_get_next(struct iag **addr_iag_ptr){ int iaggn_rc = FSCK_OK; int8_t iag_found = 0; int8_t end_of_imap = 0; int64_t leaf_byteaddr; xad_t *xadptr; agg_recptr->fais.this_iagnum++; iaggn_rc = iags_flush(); if (iaggn_rc == FSCK_OK) { /* flushed the iags ok */ while ((!iag_found) && (!end_of_imap) && (iaggn_rc == FSCK_OK)) { agg_recptr->fais.iagidx_now++; if (agg_recptr->fais.iagidx_now <= agg_recptr->fais.iagidx_max) { /* * the imap leaf is in the buffer already */ xadptr = &(agg_recptr->fais.this_mapleaf-> xad[agg_recptr->fais.iagidx_now]); agg_recptr->iag_agg_offset = sb_ptr->s_bsize * addressXAD(xadptr); agg_recptr->iag_buf_1st_inode = agg_recptr->fais.this_inoidx; iaggn_rc = readwrite_device(agg_recptr->iag_agg_offset, agg_recptr->iag_buf_length, &(agg_recptr-> iag_buf_data_len), (void *) (agg_recptr-> iag_buf_ptr), fsck_READ); if (iaggn_rc == FSCK_OK) { /* got the iag */ /* swap if on big endian machine */ ujfs_swap_iag((struct iag *) agg_recptr->iag_buf_ptr); agg_recptr->fais.iagptr = (struct iag *) (agg_recptr-> iag_buf_ptr); agg_recptr->fais.extidx_now = 0; agg_recptr->fais.this_inoidx = agg_recptr->fais.this_iagnum * NUM_INODE_PER_IAG; agg_recptr->iag_buf_1st_inode = agg_recptr->fais.this_inoidx; agg_recptr->fais.extidx_max = EXTSPERIAG - 1; iag_found = -1; } 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_BADREAD1_IAG, iaggn_rc, fsck_READ, (long long) agg_recptr->iag_agg_offset, agg_recptr->iag_buf_length, agg_recptr->iag_buf_data_len); iaggn_rc = FSCK_FAILED_BADREAD1_IAG; } } else { /* we need to get the next imap leaf (if any) */ if (agg_recptr->fais.rootleaf_imap) { /* * there aren't any more imap leafs */ end_of_imap = -1; } else if (agg_recptr->fais.this_mapleaf-> header.next == ((int64_t) 0)) { /* * there aren't any more imap leafs */ end_of_imap = -1; } else { /* there is another leaf */ leaf_byteaddr = sb_ptr->s_bsize * agg_recptr->fais.this_mapleaf-> header.next; iaggn_rc = imapleaf_get(leaf_byteaddr, &(agg_recptr->fais. this_mapleaf)); if (iaggn_rc == FSCK_OK) { /* got the imap leaf */ agg_recptr->fais.iagidx_now = XTENTRYSTART - 1; agg_recptr->fais.iagidx_max = agg_recptr->fais. this_mapleaf->header. nextindex - 1; } } } } } if (end_of_imap) { /* there aren't any more iags */ agg_recptr->fais.iagptr = NULL; agg_recptr->fais.iagidx_now = -1; } if (iaggn_rc == FSCK_OK) { /* everything worked! */ *addr_iag_ptr = agg_recptr->fais.iagptr; } return (iaggn_rc);}/***************************************************************************** * NAME: iag_put * * FUNCTION: If the current fsck session has write access to the aggregate, * note, in the fsck workspace, that the current iag buffer * has been modified and should be written to the device in the * next flush operation on this buffer. * * PARAMETERS: * iagptr - input - pointer to the iag, in an fsck buffer, which has * been modified. * * RETURNS: * success: FSCK_OK * failure: something else */int iag_put(struct iag *iagptr){ int iagp_rc = FSCK_OK; if (agg_recptr->processing_readwrite) { /* we have write access */ agg_recptr->iag_buf_write = 1; } return (iagp_rc);}/***************************************************************************** * NAME: iags_flush * * FUNCTION: If the current fsck session has write access to the aggregate * and the current iag 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 iags_flush(){ int iagf_rc = FSCK_OK; uint32_t bytes_written; if (agg_recptr->iag_buf_write) { /* buffer has been updated since * most recent write */ /* swap if on big endian machine */ ujfs_swap_iag((struct iag *) agg_recptr->iag_buf_ptr); iagf_rc = readwrite_device(agg_recptr->iag_agg_offset, agg_recptr->iag_buf_data_len, &bytes_written, (void *) agg_recptr->iag_buf_ptr, fsck_WRITE); ujfs_swap_iag((struct iag *) agg_recptr->iag_buf_ptr); if (iagf_rc == FSCK_OK) { if (bytes_written == agg_recptr->iag_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->iag_buf_write = 0; } else { /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 10); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_IAG_BADFLUSH, iagf_rc, fsck_WRITE, (long long) agg_recptr->iag_agg_offset, agg_recptr->iag_buf_data_len, bytes_written); iagf_rc = FSCK_FAILED_IAG_BADFLUSH; } } else { /* * message to user */ fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label, 11); /* * message to debugger */ fsck_send_msg(fsck_ERRONAGG, FSCK_FAILED_IAG_FLUSH, iagf_rc, fsck_WRITE, (long long) agg_recptr->iag_agg_offset, agg_recptr->iag_buf_data_len, bytes_written); iagf_rc = FSCK_FAILED_IAG_FLUSH; } } return (iagf_rc);}/***************************************************************************** * NAME: imapleaf_get * * FUNCTION: Read the specified inode map leaf node into and/or * locate the specified inode map leaf node in the * fsck inode map leaf buffer. * * PARAMETERS: * leaf_start_byte - input - offset, in bytes, in the aggregate, of * the needed map leaf node. * addr_leaf_ptr - input - pointer to a variable in which to return * the address of the map leaf in an fsck * buffer. * * RETURNS: * success: FSCK_OK * failure: something else */int imapleaf_get(int64_t leaf_start_byte, xtpage_t ** addr_leaf_ptr){ int imlfg_rc = FSCK_OK; int64_t leaf_end_byte; xtpage_t *xtpage_t_ptr; leaf_end_byte = leaf_start_byte + sizeof (xtpage_t) - 1; if ((leaf_start_byte >= agg_recptr->mapleaf_agg_offset) && (leaf_end_byte <= (agg_recptr->mapleaf_agg_offset + agg_recptr->mapleaf_buf_data_len))) { /* * the target leaf is already in * the buffer */ *addr_leaf_ptr = (xtpage_t *) (agg_recptr->mapleaf_buf_ptr + leaf_start_byte - agg_recptr->mapleaf_agg_offset); } else { /* else we'll have to read it from the disk */ agg_recptr->mapleaf_agg_offset = leaf_start_byte; imlfg_rc = readwrite_device(agg_recptr->mapleaf_agg_offset, agg_recptr->mapleaf_buf_length, &(agg_recptr->mapleaf_buf_data_le
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -