📄 fsckimap.c
字号:
/* * Copyright (c) International Business Machines Corp., 2000-2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <config.h>#include <errno.h>#include <string.h>/* defines and includes common among the fsck.jfs modules */#include "xfsckint.h"#include "jfs_byteorder.h"#include "devices.h"#include "utilsubs.h" /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * superblock buffer pointer * * defined in xchkdsk.c */extern struct superblock *sb_ptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * fsck aggregate info structure pointer * * defined in xchkdsk.c */extern struct fsck_agg_record *agg_recptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * For message processing * * defined in xchkdsk.c */extern char *Vol_Label;/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV * * The following are internal to this file * */struct fsck_iag_info { struct iag *iagptr; struct dinomap *iamctlptr; struct fsck_iam_record *iamrecptr; struct fsck_iag_record *iagtbl; struct fsck_ag_record *agtbl; int8_t agg_inotbl; struct fsck_imap_msg_info *msg_info_ptr;};struct xtree_buf { struct xtree_buf *down; /* next rightmost child */ struct xtree_buf *up; /* parent */ xtpage_t *page;};static struct xtree_buf *fsim_node_pages;/* --------------------------------------------------------------*/int agfrext_lists_scan(int, int, int, struct fsck_iag_info *, int *, struct fsck_imap_msg_info *);int agfrext_lists_validation(int, int, struct fsck_ag_record *, int *, struct fsck_imap_msg_info *);int agfrino_lists_scan(int, int, int, struct fsck_iag_info *, int *, struct fsck_imap_msg_info *);int agfrino_lists_validation(int, int, struct fsck_ag_record *, int *, struct fsck_imap_msg_info *);int AIM_check(xtpage_t *, char *, int *);int AIM_replication(int8_t, xtpage_t *, char *, int8_t *);int AIS_inode_check(struct dinode *, struct dinode *, int32_t, int32_t, int *);int AIS_inode_replication(int8_t, struct dinode *, struct dinode *);int first_refchk_inoexts(int, int, struct fsck_inode_record *, struct fsck_ino_msg_info *);int FSIM_add_extents(xtpage_t *, struct dinode *, int8_t *);int FSIM_check(struct dinode *, struct dinode *, int *);int FSIM_replication(int8_t, struct dinode *, struct dinode *, int8_t *);int iag_alloc_rebuild(int32_t, struct fsck_iag_info *);int iag_alloc_scan(int32_t *, int32_t *, struct fsck_iag_info *, struct fsck_imap_msg_info *);int iag_alloc_ver(int *, int, int32_t, struct fsck_iag_info *, struct fsck_imap_msg_info *);int iagfr_list_scan(int, int, int, struct fsck_iag_info *, int *, struct fsck_imap_msg_info *);int iagfr_list_validation(int *, struct fsck_iam_record *, struct fsck_imap_msg_info *);int iags_finish_lists(int, int, int, struct fsck_iag_info *);int iags_rebuild(int, int, int, struct fsck_iag_info *, struct fsck_imap_msg_info *);int iags_validation(int, int, int, int *, struct fsck_iag_info *, struct fsck_imap_msg_info *);int iamap_rebuild(int, int, int, struct fsck_iag_info *, struct fsck_imap_msg_info *);int iamap_validation(int, int, int, struct fsck_iag_info *, struct fsck_imap_msg_info *);int IM_compare_leaf(xtpage_t *, xtpage_t *, int *);int record_dupchk_inoexts(int, int, int32_t *, struct fsck_inode_record *, struct fsck_ino_msg_info *);int record_imap_info(void);int xtAppend(struct dinode *, int64_t, int64_t, int32_t, struct xtree_buf *);int xtSplitPage(struct dinode *, struct xtree_buf *, int64_t, int32_t, int64_t);int xtSplitRoot(struct dinode *, struct xtree_buf *, int64_t, int32_t, int64_t);/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV *//**************************************************************** * NAME: agfrext_lists_scan * * FUNCTION: Scan the Allocation Group free extent lists for the given * inode allocation table. Count the number of iags on each * list. Validate the list structure. * * PARAMETERS: * is_aggregate - input - !0 => aggregate owned * 0 => fileset owned * which_it - input - ordinal number of the aggregate inode * describing the inode table * which_ait - input - the aggregate inode table from which * the it inode should be read * { fsck_primary | fsck_secondary } * iagiptr - input - pointer to a data area describing the * current iag * errors_detected - input - pointer to a variable in which to return * !0 if errors are detected * 0 if no errors are detected * msg_info_ptr - input - pointer to data needed to issue messages * about the current inode allocation map * * NOTES: This routine does NOT attempt to determine whether the iags * on the list belong on the list. It only verifies that the * list is structurally correct, i.e., that the forward and * backward pointers are consistent. * * RETURNS: * success: FSCK_OK * failure: something else */int agfrext_lists_scan(int is_aggregate, int which_it, int which_ait, struct fsck_iag_info *iagiptr, int *errors_detected, struct fsck_imap_msg_info *msg_info_ptr){ int intermed_rc = FSCK_OK; uint32_t agidx; struct iagctl *agg_agrec; struct fsck_ag_record *wsp_agrec; int end_of_list = -1; int32_t this_iagno, prev_iagno; for (agidx = 0; agidx < MAXAG; agidx++) { agg_agrec = &(iagiptr->iamctlptr->in_agctl[agidx]); wsp_agrec = &(iagiptr->agtbl[agidx]); /* in case list is empty... */ wsp_agrec->frext_list_last = end_of_list; wsp_agrec->frext_list_first = agg_agrec->extfree; wsp_agrec->frext_list_len = 0; prev_iagno = end_of_list; this_iagno = wsp_agrec->frext_list_first; while ((this_iagno != end_of_list) && (!wsp_agrec->frext_list_bad)) { intermed_rc = iag_get(is_aggregate, which_it, which_ait, this_iagno, &(iagiptr->iagptr)); /* * we consider an error here to be an error in the * chain. If it's really something more serious it * will come up again when we go through all allocated * iag's sequentially. */ if (intermed_rc != FSCK_OK) { wsp_agrec->frext_list_bad = -1; break; } /* got the iag */ if (iagiptr->iagptr->extfreeback != prev_iagno) { /* bad back chain */ wsp_agrec->frext_list_bad = -1; break; } /* back chain is correct */ prev_iagno = this_iagno; this_iagno = iagiptr->iagptr->extfreefwd; wsp_agrec->frext_list_len++; } if (wsp_agrec->frext_list_bad) { /* found a problem */ agg_recptr->ag_dirty = 1; *errors_detected = -1; fsck_send_msg(fsck_BADAGFELIST, fsck_ref_msg(msg_info_ptr->msg_mapowner), agidx, "1"); } else { wsp_agrec->frext_list_last = prev_iagno; } } return FSCK_OK;}/**************************************************************** * NAME: agfrext_lists_validation * * FUNCTION: Compare the results of the Allocation Group free extent lists * scan with the results of validating the iags. If the number * of iags seen on a list during the list scan does not equal * the number of iags which appear to be on the list (i.e., which * have non-initialized values for forward and back pointers) * as seen during iag validation, then the list is not structurally * consistent. * * PARAMETERS: * is_aggregate - input - !0 => aggregate owned * 0 => fileset owned * which_it - input - ordinal number of the aggregate inode * describing the inode table * agtbl - input - pointer to the fsck workspace allocation * group table for the specified inode * table * errors_detected - input - pointer to a variable in which to return * !0 if errors are detected * 0 if no errors are detected * msg_info_ptr - input - pointer to data needed to issue messages * about the current inode allocation map * * NOTES: o This routine is only called in the read-only path. * * o This routine is NOT called if any structural errors have * already been detected in the list. * * RETURNS: * success: FSCK_OK * failure: something else */int agfrext_lists_validation(int is_aggregate, int which_it, struct fsck_ag_record *agtbl, int *errors_detected, struct fsck_imap_msg_info *msg_info_ptr){ uint32_t agidx; struct fsck_ag_record *wsp_agrec; for (agidx = 0; agidx < MAXAG; agidx++) { wsp_agrec = &(agtbl[agidx]); if (!wsp_agrec->frino_list_bad) { /* the list itself looked ok */ if (wsp_agrec->frext_list_len > 0) { /* * fsck observed fewer iag's which belong on * this list than it counted when it scanned * the list. (fsck has already issued messages * about these iag's) */ *errors_detected = -1; agg_recptr->ag_dirty = 1; } else if (wsp_agrec->frext_list_len < 0) { /* * fsck observed more iag's which belong on * this list and which appear to be on the list * than it counted when it scanned the list. * So the chain has somehow lost some of its * links. */ *errors_detected = -1; agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_BADAGFELIST1, fsck_ref_msg(msg_info_ptr->msg_mapowner), agidx); } } } return (FSCK_OK);}/**************************************************************** * NAME: agfrino_lists_scan * * FUNCTION: Scan the Allocation Group free inode lists for the given * inode allocation table. Count the number of iags on each * list. Validate the list structure. * * PARAMETERS: * is_aggregate - input - !0 => aggregate owned * 0 => fileset owned * which_it - input - ordinal number of the aggregate inode * describing the inode table * which_ait - input - the aggregate inode table from which * the it inode should be read * { fsck_primary | fsck_secondary } * iagiptr - input - pointer to a data area describing the * current iag * errors_detected - input - pointer to a variable in which to return * !0 if errors are detected * 0 if no errors are detected * msg_info_ptr - input - pointer to data needed to issue messages * about the current inode allocation map * * NOTES: This routine does NOT attempt to determine whether the iags * on the list belong on the list. It only verifies that the * list is structurally correct, i.e., that the forward and * backward pointers are consistent. * * RETURNS: * success: FSCK_OK * failure: something else */int agfrino_lists_scan(int is_aggregate, int which_it, int which_ait, struct fsck_iag_info *iagiptr, int *errors_detected, struct fsck_imap_msg_info *msg_info_ptr){ int intermed_rc = FSCK_OK; uint32_t agidx; struct iagctl *agg_agrec; struct fsck_ag_record *wsp_agrec; int end_of_list = -1; int32_t this_iagno, prev_iagno; for (agidx = 0; agidx < MAXAG; agidx++) { agg_agrec = &(iagiptr->iamctlptr->in_agctl[agidx]); wsp_agrec = &(iagiptr->agtbl[agidx]); /* in case list is empty... */ wsp_agrec->frino_list_last = end_of_list; wsp_agrec->frino_list_first = agg_agrec->inofree; wsp_agrec->frino_list_len = 0; prev_iagno = end_of_list; this_iagno = wsp_agrec->frino_list_first; while ((this_iagno != end_of_list) && (!wsp_agrec->frino_list_bad)) { intermed_rc = iag_get(is_aggregate, which_it, which_ait, this_iagno, &(iagiptr->iagptr)); /* * we consider an error here to be an error in the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -