⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsckpfs.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *   Copyright (C) International Business Machines Corp., 2000-2004 * *   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 <fcntl.h>#include <string.h>#include <unistd.h>/* defines and includes common among the fsck.jfs modules */#include "xfsckint.h"#include "xchkdsk.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;/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV * * The following are internal to this file * */int imapleaf_get(int64_t, xtpage_t **);int open_device_read(const char *);int open_device_rw(const char *);uint32_t checksum(uint8_t *, uint32_t);/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV *//***************************************************************************** * NAME: ait_node_get * * FUNCTION:  Read the specified AIT xTree node into the specified buffer * * PARAMETERS: *      node_fsblk_offset  - input - offset, in aggregate blocks, into the *                                   aggregate, of the xTree node wanted *      xtpage_ptr            - input - pointer an fsck buffer into which the *                                   xTree node should be read. * * RETURNS: *      success: FSCK_OK *      failure: something else */int ait_node_get(int64_t node_fsblk_offset, xtpage_t * xtpage_ptr){	int anodg_rc = FSCK_OK;	int64_t node_start_byte;	uint32_t bytes_read;	node_start_byte = node_fsblk_offset * sb_ptr->s_bsize;	if ((agg_recptr->ondev_wsp_fsblk_offset != 0)	    && (node_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		 * invalid data in an inode.  Let the caller handle		 * the consequences.		 */		anodg_rc = FSCK_BADREADTARGET2;	} else {		anodg_rc = readwrite_device(node_start_byte,					    XTPAGE_SIZE,					    &(bytes_read), (void *) xtpage_ptr,					    fsck_READ);		if (anodg_rc == FSCK_OK) {			/* read appears successful */			if (bytes_read < XTPAGE_SIZE) {				/* didn't get the minimum number of bytes */				/*				 * 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_NODE1,					      anodg_rc, fsck_READ, (long long) node_start_byte,					      XTPAGE_SIZE, bytes_read);				anodg_rc = FSCK_FAILED_BADREAD_NODE1;			} else {				/* swap if on big endian machine */				ujfs_swap_xtpage_t(xtpage_ptr);			}		} else {			/* bad return code from read */			/*			 * 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_NODE, anodg_rc,				      fsck_READ, (long long) node_start_byte,				      XTPAGE_SIZE, bytes_read);			anodg_rc = FSCK_FAILED_READ_NODE;		}	}	return (anodg_rc);}/***************************************************************************** * NAME: ait_node_put * * FUNCTION:  Write the specified buffer into the specified AIT xTree node * * PARAMETERS: *      node_fsblk_offset  - input - offset, in aggregate blocks, to which *                                           the buffer is to be written *      xtpage_ptr         - input - pointer to the buffer to write * * RETURNS: *      success: FSCK_OK *      failure: something else */int ait_node_put(int64_t node_fsblk_offset, xtpage_t * xtpage_ptr){	int anodp_rc = FSCK_OK;	int64_t node_start_byte;	uint32_t bytes_written;	node_start_byte = node_fsblk_offset * sb_ptr->s_bsize;	ujfs_swap_xtpage_t(xtpage_ptr);	anodp_rc = readwrite_device(node_start_byte, PSIZE,				    &bytes_written, (void *) xtpage_ptr,				    fsck_WRITE);	ujfs_swap_xtpage_t(xtpage_ptr);	if (anodp_rc == FSCK_OK) {		if (bytes_written != PSIZE) {			/* didn't write correct number of bytes */			/*			 * message to user			 */			fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata),				      Vol_Label, 2);			/*			 * message to debugger			 */			fsck_send_msg(fsck_ERRONAGG, FSCK_BADWRITE_FBLKMP, anodp_rc,				      fsck_WRITE, (long long) node_start_byte,				      PSIZE, bytes_written);			anodp_rc = FSCK_BADWRITE_FBLKMP;		}	} else {		/*		 * message to user		 */		fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata),			      Vol_Label, 3);		/*		 * message to debugger		 */		fsck_send_msg(fsck_ERRONAGG, FSCK_BADWRITE_FBLKMP, anodp_rc,			      fsck_WRITE, (long long) node_start_byte,			      PSIZE, bytes_written);		anodp_rc = FSCK_BADWRITE_FBLKMP;	}			/* end else the write was not successful */	return (anodp_rc);}/***************************************************************************** * NAME: ait_special_read_ext1 * * FUNCTION:  Reads the first extent of either the Primary or Secondary *            Aggregate Inode Table into the fsck inode buffer. * * PARAMETERS: *      which_ait  - input - { fsck_primary | fsck_secondary } * * NOTES:  This routine is used during the early stages of fsck processing *         when the normal mechanisms for reading inodes have not yet been *         established. * *         This routine may also be used later in fsck processing as a fast *         read routine for the inodes in the first extent of the AIT. * * RETURNS: *      success: FSCK_OK *      failure: something else */int ait_special_read_ext1(int which_ait){	int aree_rc = FSCK_OK;	int intermed_rc = FSCK_OK;	int64_t offset_1stext;	aree_rc = inodes_flush();	/*	 * calculate the byte offset of the first extent	 */	if ((which_ait == fsck_primary)) {		offset_1stext = AITBL_OFF;	} else {		/* must be secondary */		offset_1stext = addressPXD(&(sb_ptr->s_ait2)) * sb_ptr->s_bsize;	}	if (agg_recptr->ino_buf_agg_offset != offset_1stext) {		/* we don't already have the one we want */		intermed_rc = readwrite_device(offset_1stext,					       INODE_IO_BUFSIZE,					       &(agg_recptr->ino_buf_data_len),					       (void *) agg_recptr->ino_buf_ptr,					       fsck_READ);		if (intermed_rc != FSCK_OK) {			/* didn't get anything */			aree_rc = FSCK_CANTREADAITEXT1;			fsck_send_msg(fsck_CANTREADAITEXT1, fsck_ref_msg(which_ait));		} else {			/* got something */			/* swap if on big endian machine */			ujfs_swap_inoext((struct dinode *) agg_recptr->					 ino_buf_ptr, GET, sb_ptr->s_flag);			agg_recptr->ino_for_aggregate = -1;			agg_recptr->ino_which_it = which_ait;			agg_recptr->ino_buf_1st_ino = 0;			agg_recptr->ino_fsnum = 0;			agg_recptr->ino_buf_agg_offset = offset_1stext;			PXDaddress(&(agg_recptr->ino_ixpxd),				   offset_1stext / sb_ptr->s_bsize);			PXDlength(&(agg_recptr->ino_ixpxd),				  INODE_EXTENT_SIZE / sb_ptr->s_bsize);			if (agg_recptr->ino_buf_data_len < INODE_EXTENT_SIZE) {				/* didn't get enough */				aree_rc = FSCK_CANTREADAITEXT1;				fsck_send_msg(fsck_CANTREADEAITEXT1,					      fsck_ref_msg(which_ait));			}		}	}	return (aree_rc);}/***************************************************************************** * NAME: blkmap_find_bit * * FUNCTION:  Calculate the position, in the fsck workspace block map, *            of the bit representing the given aggregate block. * * PARAMETERS: *      blk_number   - input - ordinal number of the aggregate block whose *                             bit is to be located *      page_number  - input - pointer to a variable in which to return *                             the ordinal number of the page, in the fsck *                             workspace block map, containing the bit *                             for the given block *      byte_offset  - input - pointer to a variable in which to return *                             the ordinal number of the byte, in page_number *                             page, containing the bit for the given block *      mask_ptr     - input - pointer to a variable in which to return *                             a mask to apply to the byte at byte_offset *                             in order to reference the bit for the given *                             block * * RETURNS: *      success: FSCK_OK *      failure: something else */int blkmap_find_bit(int64_t blk_number,		    int64_t * page_number,		    uint32_t * byte_offset, uint32_t * mask_ptr){	int bfb_rc = FSCK_OK;	uint64_t remainder;	uint32_t bit_position;	*page_number = blk_number >> log2BITSPERPAGE;	remainder = blk_number - ((*page_number) << log2BITSPERPAGE);	*byte_offset = (remainder >> log2BITSPERDWORD) * BYTESPERDWORD;	bit_position = remainder - ((*byte_offset) << log2BITSPERBYTE);	*mask_ptr = 0x80000000u >> bit_position;	return (bfb_rc);}/***************************************************************************** * NAME: blkmap_flush * * FUNCTION:  If the current fsck session has write access to the aggregate *            and the current block map 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 blkmap_flush(){	int bmpf_rc = FSCK_OK;	uint32_t bytes_written;	struct fsck_blk_map_page *fsck_bmpt_ptr;	if (agg_recptr->blkmp_buf_write) {		/* buffer has been updated since most recent write */		/* 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);		bmpf_rc = readwrite_device(agg_recptr->blkmp_agg_offset,					   agg_recptr->blkmp_buf_data_len,					   &bytes_written,					   (void *) agg_recptr->blkmp_buf_ptr,					   fsck_WRITE);		fsck_bmpt_ptr = agg_recptr->blkmp_buf_ptr;		swap_multiple(ujfs_swap_fsck_blk_map_page, fsck_bmpt_ptr, 4);		if (bmpf_rc == FSCK_OK) {			if (bytes_written == agg_recptr->blkmp_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.				 */				agg_recptr->blkmp_buf_write = 0;			} else {				/* didn't write correct number of bytes */				/*				 * message to user				 */				fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata),					      Vol_Label, 2);				/*				 * message to debugger				 */				fsck_send_msg(fsck_ERRONWSP, FSCK_FAILED_FBMAP_BADFLUSH,					      bmpf_rc, fsck_WRITE,					      (long long) agg_recptr->blkmp_agg_offset,					      agg_recptr->blkmp_buf_data_len,					      bytes_written);				bmpf_rc = FSCK_FAILED_FBMAP_BADFLUSH;			}		} else {			/*			 * message to user			 */			fsck_send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata),				      Vol_Label, 3);			/*			 * message to debugger			 */			fsck_send_msg(fsck_ERRONWSP, FSCK_FAILED_FBMAP_FLUSH,				      bmpf_rc, fsck_WRITE,				      (long long) agg_recptr->blkmp_agg_offset,				      agg_recptr->blkmp_buf_data_len,				      bytes_written);			bmpf_rc = FSCK_FAILED_FBMAP_FLUSH;		}	}	return (bmpf_rc);}/***************************************************************************** * NAME: blkmap_get_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 into the current fsck *                              workspace block map control page should be read. * * RETURNS: *      success: FSCK_OK *      failure: something else */int blkmap_get_ctl_page(struct fsck_blk_map_hdr *blk_ctlptr){	int bmgcp_rc = FSCK_OK;	uint32_t bytes_read;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -