📄 extract.c
字号:
if (Dev_IOPort == NULL) { send_msg(fsck_DEVOPENRDRC, ERROR_FILE_NOT_FOUND); return ERROR_FILE_NOT_FOUND; } Dev_blksize = Dev_SectorSize = PBSIZE; return 0;}/***************************************************************************** * NAME: open_outfile * * FUNCTION: Open the output file. * * PARAMETERS: * Device - input - the device specification * * RETURNS: * success: 0 * failure: something else */int open_outfile(){ int openof_rc = 0; if (!local_recptr->file_name_specified) { /* no output file name given */ if (local_recptr->which_log == NEWLOG) { /* most recent wanted */ memcpy((void *) file_name, (void *) default_logfile_new, default_logfile_name_len); } else { /* prior log wanted */ memcpy((void *) file_name, (void *) default_logfile_old, default_logfile_name_len); } } outfp = fopen(file_name, "w"); if (outfp == NULL) { /* output file open failed */ openof_rc = XCHKLOG_CANTOPENOUTFILE; send_msg(fsck_XCHKLOGOPNFAIL, file_name); } else { /* output file is open */ local_recptr->outfile_is_open = -1; /* * write the eyecatcher into the output buffer */ memcpy((void *) (local_recptr->outfile_buf_ptr), (void *) jfs_chklog_eyecatcher, 16); local_recptr->outfile_buf_data_len = 16; /* * announce the output file name */ if (local_recptr->which_log == NEWLOG) { /* most recent */ send_msg(fsck_XCHKLOGNEW, file_name); } else { /* previous */ send_msg(fsck_XCHKLOGOLD, file_name); } } return (openof_rc);}/***************************************************************************** * NAME: readwrite_device * * FUNCTION: Read data from or write data to the device on which the * aggregate resides. * * PARAMETERS: * dev_offset - input - the offset, in bytes, into the aggregate * of the data to read or to which to write * the data. * requested_data_size - input - the number of bytes requested * actual_data_size - input - pointer to a variable in which to return * the number of bytes actually read or * written * data_buffer - input - the address of the buffer in which to * put the data or from which to write * the data * mode - input - { fsck_READ | fsck_WRITE } * * NOTES: This routine also exists in fsck code. When there is time, * examine both copies for differences and put the combined * copy in libfs to eliminate extra code. * * RETURNS: * success: 0 * failure: something else */int readwrite_device(int64_t dev_offset, unsigned requested_data_size, unsigned *actual_data_size, void *data_buffer, int mode){ int rwdb_rc = 0; if ((dev_offset % Dev_SectorSize) || (requested_data_size % Dev_SectorSize)) { rwdb_rc = FSCK_FAILED_SEEK; } else { switch (mode) { case fsck_READ: rwdb_rc = ujfs_rw_diskblocks(Dev_IOPort, dev_offset, requested_data_size, data_buffer, GET); break; case fsck_WRITE: rwdb_rc = ujfs_rw_diskblocks(Dev_IOPort, dev_offset, requested_data_size, data_buffer, PUT); break; default: rwdb_rc = FSCK_INTERNAL_ERROR_3; break; } } if (rwdb_rc == 0) *actual_data_size = requested_data_size; else *actual_data_size = 0; return (rwdb_rc);}/***************************************************************************** * NAME: record_msg * * FUNCTION: Record an fsck service log message in the output file, * formatted for the common fsck service log display tool. * * PARAMETERS: * ? - input - * ? - returned - * * NOTES: Any message designated fsck_debug is english-only, and * is issued in english, even if it is sent to stdout. * * All other messages are local-language (in the nls context) * and, when sent to stdout or stderr, are issued in the * local language. * * Regardless of the language used to send a message to * stdout and stderr, messages are ALWAYS LOGGED IN ENGLISH. * * RETURNS: * nothing */void record_msg(char *msg_txt){ char *msg; char log_entry[4096]; int entry_length = sizeof (struct chklog_entry_hdr); struct chklog_entry_hdr *hdptr; int buffer_bytes_left; hdptr = (struct chklog_entry_hdr *) log_entry; msg = &log_entry[entry_length]; strcpy(msg, msg_txt); entry_length += strlen(msg_txt); /* add null terminator to string */ log_entry[entry_length++] = '\0'; /* * round the length up so the next entry will * start on a doubleword (4 byte) boundary */ entry_length = ((entry_length + 3) / 4) * 4; hdptr->entry_length = entry_length; buffer_bytes_left = local_recptr->outfile_buf_length - local_recptr->outfile_buf_data_len; if (buffer_bytes_left < entry_length) { /* won't fit */ local_recptr->last_msghdr->entry_length += buffer_bytes_left; fwrite((const void *) (local_recptr->outfile_buf_ptr), sizeof (char), local_recptr->outfile_buf_length, outfp); /* clear the buffer */ memset((void *) (local_recptr->outfile_buf_ptr), 0, local_recptr->outfile_buf_length); local_recptr->outfile_buf_data_len = 0; } local_recptr->last_msghdr = (struct fscklog_entry_hdr *) (local_recptr->outfile_buf_ptr + local_recptr->outfile_buf_data_len); memcpy((void *) local_recptr->last_msghdr, (void *) hdptr, entry_length); local_recptr->outfile_buf_data_len += entry_length; return;}/***************************************************************************** * NAME: validate_super * * FUNCTION: This routine validates the JFS superblock currently in the * buffer. If any problem is detected, the which_superblock * input parm is used to tailor the message issued to notify * the user. * * PARAMETERS: * which_super - input - specifies the superblock on which is in the * buffer { fsck_primary | fsck_secondary } * * NOTES: This routine also exists in fsck code. When there is time, * examine both copies for differences and put the combined * copy in libfs to eliminate extra code. * * RETURNS: * success: 0 * failure: something else */int validate_super(int which_super){ int vs_rc = 0; /* assume the superblock is ok */ int64_t bytes_on_device; int64_t agg_blks_in_aggreg = 0, agg_blks_on_device = 0, dev_blks_on_device; int64_t fsck_start_from_pxd, fsck_blkmap_start_blks; uint32_t fsck_length_from_pxd, fsck_blkmap_size_blks, fsck_blkmap_size_pages; int64_t jlog_start_from_pxd; uint32_t jlog_length_from_pxd; int agl2size; unsigned expected_flag = JFS_GROUPCOMMIT; unsigned agsize; int bad_bsize = 0; if (memcmp(sb_ptr->s_magic, JFS_MAGIC, sizeof (sb_ptr->s_magic)) != 0) { vs_rc = FSCK_BADSBMGC; send_msg(fsck_BADSBMGC, fsck_ref_msg(which_super)); } else if (sb_ptr->s_version > JFS_VERSION) { vs_rc = FSCK_BADSBVRSN; send_msg(fsck_BADSBVRSN, fsck_ref_msg(which_super)); } else { /* the magic number and version number are correct so it * probably is a JFS superblock with the format we are expecting */ /* get physical device size */ ujfs_get_dev_size(Dev_IOPort, &bytes_on_device); dev_blks_on_device = bytes_on_device / Dev_blksize; if (sb_ptr->s_pbsize != Dev_blksize) { vs_rc = FSCK_BADSBOTHR1; send_msg(fsck_BADSBOTHR, "1", fsck_ref_msg(which_super)); } if (sb_ptr->s_l2pbsize != log2shift(Dev_blksize)) { vs_rc = FSCK_BADSBOTHR2; send_msg(fsck_BADSBOTHR, "2", fsck_ref_msg(which_super)); } if (!inrange(sb_ptr->s_bsize, 512, 4096)) { bad_bsize = -1; vs_rc = FSCK_BADSBOTHR3; send_msg(fsck_BADSBBLSIZ, fsck_ref_msg(which_super)); } else { /* else the filesystem block size is a legal value */ if (sb_ptr->s_l2bsize != log2shift(sb_ptr->s_bsize)) { vs_rc = FSCK_BADSBOTHR4; send_msg(fsck_BADSBOTHR, "4", fsck_ref_msg(which_super)); } if (sb_ptr->s_l2bfactor != log2shift(sb_ptr->s_bsize / Dev_blksize)) { vs_rc = FSCK_BADSBOTHR5; send_msg(fsck_BADSBOTHR, "5", fsck_ref_msg(which_super)); } if (sb_ptr->s_bsize < Dev_blksize) { bad_bsize = -1; vs_rc = FSCK_BLSIZLTLVBLSIZ; send_msg(fsck_BLSIZLTLVBLSIZ, fsck_ref_msg(which_super)); } } if (!bad_bsize) { agg_blks_on_device = bytes_on_device / sb_ptr->s_bsize; } if (sb_ptr->s_size > dev_blks_on_device) { vs_rc = FSCK_BADSBFSSIZ; send_msg(fsck_BADSBFSSIZ, fsck_ref_msg(which_super)); }#ifdef _JFS_DFS_LFS s_size_inbytes = sb_ptr->s_size * Dev_blksize; sum_inbytes = (int64_t) (sb_ptr->totalUsable * 1024) + (int64_t) (sb_ptr->minFree * 1024); if ((sum_inbytes > s_size_inbytes) || ((s_size_inbytes - sum_inbytes) >= 1024)) { /* the sum is greater or the difference is at least 1K */ vs_rc = FSCK_BADBLKCTTTL; send_msg(fsck_BADBLKCTTTL, fsck_ref_msg(which_super)); }#endif /* must have JFS_OS2 or JFS_LINUX */ if (!(((sb_ptr->s_flag & JFS_OS2) == JFS_OS2) || ((sb_ptr->s_flag & JFS_LINUX) == JFS_LINUX))) { vs_rc = FSCK_BADSBOTHR6; send_msg(fsck_BADSBOTHR, "6", fsck_ref_msg(which_super)); } if ((sb_ptr->s_flag & expected_flag) != expected_flag) { vs_rc = FSCK_BADSBOTHR6; send_msg(fsck_BADSBOTHR, "6", fsck_ref_msg(which_super)); } if (sb_ptr->s_agsize < (1 << L2BPERDMAP)) { vs_rc = FSCK_BADSBAGSIZ; send_msg(fsck_BADSBAGSIZ, fsck_ref_msg(which_super)); } else { /* else the alloc group size is possibly correct */ agg_blks_in_aggreg = sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize; agl2size = ujfs_getagl2size(agg_blks_in_aggreg, sb_ptr->s_bsize); /* get the allocation group size */ agsize = (int64_t) 1 << agl2size; if (sb_ptr->s_agsize != agsize) { vs_rc = FSCK_BADAGFSSIZ; send_msg(fsck_BADSBAGSIZ, fsck_ref_msg(which_super)); } } if (!vs_rc) { /* * check out the fsck in-aggregate workspace */ fsck_length_from_pxd = lengthPXD(&(sb_ptr->s_fsckpxd)); fsck_start_from_pxd = addressPXD(&(sb_ptr->s_fsckpxd)); agg_blks_in_aggreg = fsck_length_from_pxd + (sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize); if (agg_blks_in_aggreg > agg_blks_on_device) { /* wsp length is bad */ vs_rc = FSCK_BADSBFWSL1; send_msg(fsck_BADSBFWSL1, fsck_ref_msg(which_super)); } else { fsck_blkmap_size_pages = ((agg_blks_in_aggreg + (BITSPERPAGE - 1)) / BITSPERPAGE) + 1 + 50; /* size in aggregate blocks */ fsck_blkmap_size_blks = (fsck_blkmap_size_pages << L2PSIZE) / sb_ptr->s_bsize; /* * aggregate block offset of the * fsck workspace in the aggregate. */ fsck_blkmap_start_blks = agg_blks_in_aggreg - fsck_blkmap_size_blks; if (fsck_length_from_pxd != fsck_blkmap_size_blks) { /* * length of fsck in-aggregate * workspace is incorrect */ vs_rc = FSCK_BADSBFWSL; send_msg(fsck_BADSBFWSL, fsck_ref_msg(which_super)); } if (fsck_start_from_pxd != fsck_blkmap_start_blks) { /* * address of fsck in-aggregate * workspace is incorrect */ vs_rc = FSCK_BADSBFWSA; send_msg(fsck_BADSBFWSA, fsck_ref_msg(which_super)); } } } if (!vs_rc) { /* * check out the in-aggregate journal log * * if there is one it starts at the end of the fsck * in-aggregate workspace. */ jlog_length_from_pxd = lengthPXD(&(sb_ptr->s_logpxd)); jlog_start_from_pxd = addressPXD(&(sb_ptr->s_logpxd)); if (jlog_start_from_pxd != 0) { /* there's one in there */ if (jlog_start_from_pxd != agg_blks_in_aggreg) { /* * address of in-aggregate * journal log is incorrect */ vs_rc = FSCK_BADSBFJLA; send_msg(fsck_BADSBFJLA, fsck_ref_msg(which_super)); } agg_blks_in_aggreg += jlog_length_from_pxd; if (agg_blks_in_aggreg > agg_blks_on_device) { /* log length is bad */ vs_rc = FSCK_BADSBFJLL; send_msg(fsck_BADSBFJLL, fsck_ref_msg(which_super)); } } } } return (vs_rc);}/***************************************************************************** * NAME: validate_superblock * * FUNCTION: Verify that the primary superblock is valid. * If not, verify that the secondary superblock is valid. * * PARAMETERS: none * * NOTES: If this routine returns 0 then the superblock * I/O buffer contains a valid superblock. * * This routine also exists in fsck code. When there is time, * examine both copies for differences and put the combined * copy in libfs to eliminate extra code. * * RETURNS: * success: 0 * failure: something else */int validate_superblock(){ int vsb_rc = 0; int primary_sb_bad = 1; int secondary_sb_bad = 1; int which_sb = 0; /* get primary */ vsb_rc = ujfs_get_superblk(Dev_IOPort, sb_ptr, 1); if (vsb_rc != 0) { /* if read primary fails */ send_msg(fsck_CNTRESUPP); } else { /* got primary superblock */ which_sb = fsck_primary; primary_sb_bad = validate_super(fsck_primary); } if (primary_sb_bad) { /* can't use the primary superblock */ send_msg(fsck_SBBADP); /* get 2ndary */ vsb_rc = ujfs_get_superblk(Dev_IOPort, sb_ptr, 0); if (vsb_rc != 0) { send_msg(fsck_CNTRESUPS); } else { /* got secondary superblock */ which_sb = fsck_secondary; secondary_sb_bad = validate_super(fsck_secondary); } if (!secondary_sb_bad) { /* secondary is ok */ vsb_rc = 0; } else { send_msg(fsck_SBBADS); } } if ((!primary_sb_bad) || (!secondary_sb_bad)) { /* the buffer holds a valid superblock */ /* aggregate block size */ local_recptr->ag_blk_size = sb_ptr->s_bsize; send_msg(fsck_XCHKLOGSBOK, fsck_ref_msg(which_sb)); } return (vsb_rc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -