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

📄 fsckpfs.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 5 页
字号:
		 * invalid data in an inode.  Let the caller handle		 * the consequences.		 */		dnodg_rc = FSCK_BADREADTARGET;	} else if ((dnode_start_byte >= agg_recptr->dnode_agg_offset)		   && (dnode_end_byte <=		       (agg_recptr->dnode_agg_offset +			agg_recptr->dnode_buf_data_len))) {		/*		 * the target dir node is already in		 * the buffer		 */		dtp = *addr_dtpage_ptr = (dtpage_t *)		    (agg_recptr->dnode_buf_ptr + dnode_start_byte -		     agg_recptr->dnode_agg_offset);		/* swap if on big endian machine */		if (!(dtp->header.flag & BT_SWAPPED)) {			ujfs_swap_dtpage_t(dtp, sb_ptr->s_flag);			dtp->header.flag |= BT_SWAPPED;		}	} else {		/* else we'll have to read it from the disk */		agg_recptr->dnode_agg_offset = dnode_start_byte;		dnodg_rc = readwrite_device(agg_recptr->dnode_agg_offset,					    agg_recptr->dnode_buf_length,					    &(agg_recptr->dnode_buf_data_len),					    (void *) agg_recptr->dnode_buf_ptr,					    fsck_READ);		if (dnodg_rc == FSCK_OK) {			/* read appears successful */			if (agg_recptr->dnode_buf_data_len >= dnode_length) {				/*				 * we may not have gotten all we asked for,				 * but we got enough to cover the dir node				 * we were after				 */				dtp = *addr_dtpage_ptr =				    (dtpage_t *) agg_recptr->dnode_buf_ptr;				/* swap if on big endian machine */				ujfs_swap_dtpage_t(dtp, sb_ptr->s_flag);				dtp->header.flag |= BT_SWAPPED;			} 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_DNODE,					      dnodg_rc, fsck_READ,					      (long long) agg_recptr->dnode_agg_offset,					      agg_recptr->dnode_buf_length,					      agg_recptr->dnode_buf_data_len);				dnodg_rc = FSCK_FAILED_BADREAD_DNODE;			}		} 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_DNODE,				      dnodg_rc, fsck_READ,				      (long long) agg_recptr->dnode_agg_offset,				      agg_recptr->dnode_buf_length,				      agg_recptr->dnode_buf_data_len);			dnodg_rc = FSCK_FAILED_READ_DNODE;		}	}	return (dnodg_rc);}/***************************************************************************** * NAME: ea_get * * FUNCTION: Read the specified Extended Attributes data (ea) into *           the specified buffer. * * PARAMETERS: *      ea_fsblk_offset  - input - offset, in aggregate blocks, into the *                                    aggregate of the ea to read *      ea_byte_length   - input - length, in bytes, of the ea to read *      eabuf_ptr        - input - the address (in dynamic storage) of the *                                 buffer into which to read the ea *      eabuf_length     - input - pointer to a variable in which contains *                                 the length of the buffer at eabuf_ptr *      ea_data_length   - input - pointer to a variable in which to return *                                 the number of bytes actually read from the *                                 device *      ea_agg_offset    - input - pointer to a variable in which to return *                                 the offset, in bytes, into the aggregate *                                 of the ea to read * * RETURNS: *      success: FSCK_OK *      failure: something else */int ea_get(int64_t ea_fsblk_offset,	   uint32_t ea_byte_length,	   char *eabuf_ptr,	   uint32_t * eabuf_length,	   uint32_t * ea_data_length, int64_t * ea_agg_offset){	int ea_rc = FSCK_OK;	int64_t start_byte;	start_byte = ea_fsblk_offset * sb_ptr->s_bsize;	ea_rc = readwrite_device(start_byte, ea_byte_length, ea_data_length,				 (void *) eabuf_ptr, fsck_READ);	/* swap if on big endian machine, currently unused */	if (ea_rc == FSCK_OK) {	/* read appears successful */		*ea_agg_offset = start_byte;		if ((*ea_data_length) < ea_byte_length) {			/* we didn't get enough */			*ea_agg_offset = 0;			*ea_data_length = 0;			ea_rc = FSCK_BADEADESCRIPTOR;		}	} else {		/* bad return code from read */		ea_rc = FSCK_CANTREADEA;	}	return (ea_rc);}/***************************************************************************** * NAME: fscklog_put_buffer * * FUNCTION:  If the current fsck session has write access to the aggregate, *            and if the in-aggregate fsck log is not full, write the *            contents of the current fscklog buffer into the in-aggregate *            fsck log. * * PARAMETERS:  none * * NOTES:  o Unlike most _put_ routines in this module, _buffer *           actually writes to the device.  This is done because the fsck *           log contains information which provides crucial serviceability *           should the fsck session be interrupted. * *         o Errors here are recorded in the control page of the fsck *           in-aggregate workspace but never affect other fsck processing. * * RETURNS: *      success: FSCK_OK *      failure: something else */int fscklog_put_buffer(){	int flpb_rc = FSCK_OK;	int io_rc = FSCK_OK;	uint32_t bytes_written = 0;	uint32_t log_bytes_left;	int32_t num_log_errors;	struct fscklog_error *log_error_recptr;	if ((!agg_recptr->fscklog_full) && (agg_recptr->processing_readwrite)) {		/* have write access */		/* swap if on big endian machine in proper format */		io_rc = readwrite_device(agg_recptr->fscklog_agg_offset,					 agg_recptr->fscklog_buf_length,					 &bytes_written,					 (void *) agg_recptr->fscklog_buf_ptr,					 fsck_WRITE);		if ((io_rc != FSCK_OK)		    || (bytes_written !=			(uint32_t) agg_recptr->fscklog_buf_length)) {			/*			 * write failed or didn't write correct			 * number of bytes			 */			/* This prevents infinite recursion */			agg_recptr->fscklog_full = 1;			if (agg_recptr->blkmp_ctlptr) {				num_log_errors =				    agg_recptr->blkmp_ctlptr->hdr.				    num_logwrite_errors;				if (num_log_errors < 120) {					log_error_recptr =					    &(agg_recptr->blkmp_ctlptr->hdr.					      logerr[num_log_errors]);					log_error_recptr->err_offset =					    agg_recptr->fscklog_agg_offset;					log_error_recptr->bytes_written =					    bytes_written;					log_error_recptr->io_retcode = io_rc;				}				agg_recptr->blkmp_ctlptr->hdr.				    num_logwrite_errors += 1;			}			/*			 * message to debugger			 *			 * N.B. This is NOT a fatal condition!			 */			fsck_send_msg(fsck_ERRONLOG, FSCK_BADWRITE_FSCKLOG,				      io_rc, fsck_WRITE,				      (long long) agg_recptr->fscklog_agg_offset,				      agg_recptr->fscklog_buf_length,				      bytes_written);		}	}	/*	   * We want to reset the buffer no matter what.	   * It is useful to refill the buffer even if logging is not	   * active because it may provide diagnostic information in	   * a dump.	 */	agg_recptr->fscklog_agg_offset += agg_recptr->fscklog_buf_length;	agg_recptr->fscklog_log_offset += agg_recptr->fscklog_buf_length;	agg_recptr->fscklog_buf_data_len = 0;	log_bytes_left = (agg_recptr->ondev_fscklog_byte_length / 2) -	    agg_recptr->fscklog_log_offset;	if (log_bytes_left < agg_recptr->fscklog_buf_length) {		/*		 * can't fit another buffer full		 * into the log		 */		if (!agg_recptr->initializing_fscklog) {			/* this is a false			 * condition if doing log initialization			 */			agg_recptr->fscklog_full = -1;			agg_recptr->blkmp_ctlptr->hdr.fscklog_full = -1;		}	}	return (flpb_rc);}/***************************************************************************** * NAME: iag_get * * FUNCTION: Read the requested iag into and/or locate the requested iag *           in the fsck iag buffer. * * PARAMETERS: *      is_aggregate  - input -  0 => the iag is owned by the fileset *                              !0 => the iag is owned by the aggregate *      which_it      - input - ordinal number of the aggregate inode *                              representing the inode table to which the *                              iag belongs. *      which_ait     - input - the aggregate inode table { fsck_primary | *                              fsck_secondary } containing the version of *                              which_it to use for this operation *      iag_num       - input - ordinal number of the iag needed *      addr_iag_ptr  - input - pointer to a variable in which to return *                              the address, in an fsck buffer, of the *                              requested iag. * * RETURNS: *      success: FSCK_OK *      failure: something else */int iag_get(int is_aggregate, int which_it, int which_ait, int32_t iag_num,	    struct iag **addr_iag_ptr){	int iagg_rc = FSCK_OK;	int64_t imap_logical_block, extent_offset;	int64_t offset_in_extent = 0;	struct dinode *imap_inoptr;	xad_t *xad_ptr;	int8_t offset_found;	int which_agg_inode = 0;	*addr_iag_ptr = NULL;	if ((agg_recptr->iag_buf_1st_inode == (iag_num << L2INOSPERIAG)) &&	    (agg_recptr->iag_for_aggregate == is_aggregate) &&	    (agg_recptr->iag_which_it == which_it)) {		/*		 * the target iag is already in the buffer		 */		*addr_iag_ptr = (struct iag *) agg_recptr->iag_buf_ptr;		goto iagg_exit;	}	/* need to get the iag */	/* perform any pending writes */	iagg_rc = iags_flush();	if (iagg_rc != FSCK_OK)		goto iagg_exit;	/* flush worked ok */	if (is_aggregate) {		/* this is an IAG describing aggregate inodes */		if (iag_num < agg_recptr->agg_imap.num_iags) {			/* in bounds */			which_agg_inode = AGGREGATE_I;			iagg_rc = ait_special_read_ext1(which_ait);			if (iagg_rc != FSCK_OK) {				/* read ait failed */				report_readait_error(iagg_rc,						     FSCK_FAILED_CANTREADAITEXTH,						     which_ait);				iagg_rc = FSCK_FAILED_CANTREADAITEXTH;			}		} else {			/* invalid request */			iagg_rc = FSCK_IAGNOOOAGGBOUNDS;		}	} else {		/* an IAG describing fileset inodes */		if (iag_num < agg_recptr->fset_imap.num_iags) {			/* in bounds */			which_agg_inode = FILESYSTEM_I;			iagg_rc = ait_special_read_ext1(which_ait);			if (iagg_rc != FSCK_OK) {				/* read ait failed */				report_readait_error(iagg_rc,						     FSCK_FAILED_CANTREADAITEXTK,						     which_ait);				iagg_rc = FSCK_FAILED_CANTREADAITEXTK;			}		} else {			/* invalid request */			iagg_rc = FSCK_IAGNOOOFSETBOUNDS;		}	}	if (iagg_rc != FSCK_OK)		goto iagg_exit;	/* got the extent */	imap_inoptr = (struct dinode *)(agg_recptr->ino_buf_ptr +	     (which_agg_inode * sizeof (struct dinode)));	imap_logical_block = IAGTOLBLK(iag_num, agg_recptr->log2_blksperpg);	iagg_rc = xTree_search(imap_inoptr, imap_logical_block, &xad_ptr,			       &offset_found);	if (iagg_rc != FSCK_OK)		goto iagg_exit;	/* nothing extraordinary happened */	if (!offset_found) {		iagg_rc = FSCK_INTERNAL_ERROR_50;	} else {		/* we have the xad which describes the iag */		extent_offset = offsetXAD(xad_ptr);		if (extent_offset != imap_logical_block) {			offset_in_extent = imap_logical_block - extent_offset;		}		agg_recptr->iag_agg_offset = sb_ptr->s_bsize *		    (addressXAD(xad_ptr) + offset_in_extent);		iagg_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 (iagg_rc == FSCK_OK) {			/* got the iag */			/* swap if on big endian machine */			ujfs_swap_iag((struct iag *)agg_recptr->iag_buf_ptr);			agg_recptr->iag_buf_1st_inode = iag_num << L2INOSPERIAG;			agg_recptr->iag_fsnum = imap_inoptr->di_fileset;			agg_recptr->iag_for_aggregate = is_aggregate;			agg_recptr->iag_which_it = which_it;			*addr_iag_ptr = (struct iag *)agg_recptr->iag_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_IAG,				      iagg_rc, fsck_READ,				      (long long)agg_recptr->iag_agg_offset,				      agg_recptr->iag_buf_length,				      agg_recptr->iag_buf_data_len);			iagg_rc = FSCK_FAILED_READ_IAG;		}	}      iagg_exit:	return (iagg_rc);}/***************************************************************************** * NAME: iag_get_first * * FUNCTION: Read the first iag in the specified inode table into and/or *           locate the first iag in the specified inode table in the *           fsck iag buffer.  Set up for sequential access on the iag's *           in this table. * * PARAMETERS: *      is_aggregate  - input -  0 => the iag is owned by the fileset *                              !0 => the iag is owned by the aggregate *      which_it      - input - ordinal number of the aggregate inode *                              representing the inode table to which the *                              iag belongs. *      which_ait     - input - the aggregate inode table { fsck_primary | *                              fsck_secondary } containing the version of *                              which_it to use for this operation *      addr_iag_ptr  - input - pointer to a variable in which to return * * RETURNS: *      success: FSCK_OK *      failure: something else */int iag_get_first(int is_aggregate, int it_number, int which_ait,		  struct iag **addr_iag_ptr){	int iaggf_rc = FSCK_OK;	struct dinode *imap_inoptr;	xad_t *xadptr;	int it_tbl_is_agg_owned = -1;	/* the table may not describe the					 * aggregate inodes, but the inode					 * describing the table is ALWAYS					 * an aggregate inode					 */	agg_recptr->fais.this_iagnum = 0;	agg_recptr->fais.this_inoidx = 0;	/* assume it's not a rootleaf */

⌨️ 快捷键说明

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