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

📄 fsckwsp.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 <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <errno.h>/* defines and includes common among the fsck.jfs modules */#include "xfsckint.h"#include "devices.h"#include "message.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;/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * fsck block map info structure and pointer * *      defined in xchkdsk.c */extern struct fsck_bmap_record *bmap_recptr;/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * For message processing * *      defined in xchkdsk.c */extern struct tm *fsck_DateTime;extern char *Vol_Label;extern UniChar uni_LSFN_NAME[];extern UniChar uni_lsfn_name[];/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * Unicode path strings information. * *     values are assigned when the fsck aggregate record is initialized. *     accessed via addresses in the fack aggregate record. */extern UniChar uni_LSFN_NAME[11];extern UniChar uni_lsfn_name[11];/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV * * The following are internal to this file * */int alloc_wsp_extent(uint32_t, int);void dupall_extract_blkrec(struct dupall_blkrec *);struct dupall_blkrec *dupall_find_blkrec(int64_t, int64_t);struct dupall_blkrec *dupall_get_blkrec(void);int dupall_insert_blkrec(int64_t, int64_t, struct dupall_blkrec **);int establish_wsp_block_map(void);int extent_1stref_chk(int64_t, int64_t, int8_t, int8_t,		      struct fsck_ino_msg_info *, struct fsck_inode_record *);int extent_record_dupchk(int64_t, int64_t, int8_t, int8_t, int8_t,			 struct fsck_ino_msg_info *,			 struct fsck_inode_record *);int fsblk_count_avail(uint32_t *, int32_t *, int32_t *, int32_t, int32_t *);int fsblk_next_avail(uint32_t *, int32_t, int32_t, int32_t *, int32_t *, int *);int inorec_agg_search(uint32_t, struct fsck_inode_record **);int inorec_agg_search_insert(uint32_t, struct fsck_inode_record **);int inorec_fs_search(uint32_t, struct fsck_inode_record **);int inorec_fs_search_insert(uint32_t, struct fsck_inode_record **);void locate_inode(uint32_t, int32_t *, int32_t *, int32_t *);/* * The following are used for reporting storage related errors */extern int wsp_dynstg_action;extern int wsp_dynstg_object;/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV *//**************************************************************************** * NAME: alloc_vlarge_buffer * * FUNCTION: Allocate the very large multi-use buffer * * * PARAMETERS:	none * * NOTES:	This must be called before logredo since the purpose *		is to ensure a buffer which has been obtained via *		malloc(), whether we're called from the command line *		or during autocheck. * * RETURNS: *      success: FSCK_OK *      failure: something else */int alloc_vlarge_buffer(){	int avb_rc = FSCK_OK;	if ((agg_recptr->vlarge_buf_ptr =	     (char *) malloc(VLARGE_BUFSIZE)) != NULL) {		agg_recptr->vlarge_buf_length = VLARGE_BUFSIZE;		agg_recptr->vlarge_current_use = NOT_CURRENTLY_USED;	} else {		avb_rc = ENOMEM;		fsck_send_msg(MSG_OSO_INSUFF_MEMORY);	}	return (avb_rc);}/**************************************************************************** * NAME: alloc_wrksp * * FUNCTION:  Allocates and initializes (to guarantee the storage is backed) *            dynamic storage for the caller. * * PARAMETERS: *      length         - input - the number of bytes of storage which are needed *      dynstg_object  - input - a constant (see xfsck.h) identifying the purpose *                               for which the storage is needed (Used in error *                               message if the request cannot be satisfied. *      addr_wrksp_ptr - input - the address of a variable in which this routine *                               will return the address of the dynamic storage *                               allocated for the caller * * RETURNS: *      success: FSCK_OK *      failure: something else */int alloc_wrksp(uint32_t length, int dynstg_object, int for_logredo,		void **addr_wrksp_ptr){	int awsp_rc = FSCK_OK;	char *wsp_ptr = NULL;	struct wsp_ext_rec *this_fer;	uint32_t bytes_avail;	uint32_t min_length;	*addr_wrksp_ptr = NULL;	/* round up to an 8 byte boundary */	min_length = ((length + 7) / 8) * 8;	while ((wsp_ptr == NULL) && (awsp_rc == FSCK_OK)) {		this_fer = agg_recptr->wsp_extent_list;		while ((this_fer != NULL) && (wsp_ptr == NULL)		       && (awsp_rc == FSCK_OK)) {			if ((for_logredo) && !(this_fer->for_logredo)) {				/*				 * requestor is logredo and				 * fer describes an allocation not for logredo				 */				this_fer = this_fer->next;			} else {				/* this fer describes an eligible allocation */				bytes_avail =				    this_fer->extent_length -				    this_fer->last_byte_used;				if (bytes_avail >= min_length) {					/* there's enough here */					wsp_ptr =					    this_fer->extent_addr +					    this_fer->last_byte_used + 1;					this_fer->last_byte_used += min_length;				} else {					/* try the next fer */					this_fer = this_fer->next;				}			}		}		if ((awsp_rc == FSCK_OK) && (wsp_ptr == NULL)) {			/*			 * nothing fatal but we didn't find the			 * storage yet			 */			/*			 * will allocate some number of memory segments			 *  and put the fer describing it on the beginning			 *  of the list.			 */			awsp_rc = alloc_wsp_extent(min_length, for_logredo);		}	}	if (awsp_rc == FSCK_OK) {		/* we allocated virtual storage */		/*		 * now initialize the storage		 */		memset((void *) wsp_ptr, 0, length);		/* set the return value */		*addr_wrksp_ptr = (void *) wsp_ptr;	}	return (awsp_rc);}/**************************************************************************** * NAME: alloc_wsp_extent * * FUNCTION: Extend the workspace * *           For optimum use of storage, we'll allocate a whole segment. *           Then the alloc_wrksp routine portions it out as needed. * * PARAMETERS: *      minimum_length - input - minimum number of bytes of contiguous storage *                               needed * * RETURNS: *      success: FSCK_OK *      failure: something else */int alloc_wsp_extent(uint32_t minimum_length, int for_logredo){	int awe_rc = FSCK_OK;	struct wsp_ext_rec *new_fer;	int32_t extent_length = MEMSEGSIZE;	char *extent_addr = NULL;	int8_t from_high_memory = 0;	/*	 * the user has specified the minimum needed.  We must allocate	 * at least 16 more than that because we're going to use 16 bytes	 * at the beginning to keep track of it.	 */	while (extent_length < (minimum_length + 16)) {		extent_length += MEMSEGSIZE;	}	wsp_dynstg_object = dynstg_iobufs;	wsp_dynstg_action = dynstg_allocation;	extent_addr = (char *) malloc(extent_length);	if (extent_addr == NULL) {		/* allocation failure */		awe_rc = FSCK_FAILED_DYNSTG_EXHAUST4;		if (!for_logredo) {			fsck_send_msg(fsck_EXHDYNSTG, wsp_dynstg_action,				      dynstg_wspext);		}	} else {		/* got the dynamic storage  */		/*		 * use the first 16 bytes of it to keep track of it		 */		new_fer = (struct wsp_ext_rec *) extent_addr;		new_fer->extent_length = extent_length;		new_fer->for_logredo = for_logredo;		new_fer->from_high_memory = from_high_memory;		new_fer->extent_addr = extent_addr;		new_fer->last_byte_used = sizeof (struct wsp_ext_rec) - 1;		new_fer->next = agg_recptr->wsp_extent_list;		agg_recptr->wsp_extent_list = new_fer;	}	return (awe_rc);}/**************************************************************************** * NAME: blkall_mark_free * * FUNCTION: Adjust the fsck workspace to show the indicated blocks are no *           longer used. * * PARAMETERS: *      first_block  - input - ordinal number of the first filesystem block *                             whose owner count is to be adjusted. *      last_block   - input - ordinal number of the last filesystem block *                             whose owner count is to be adjusted. * * RETURNS: *      success: FSCK_OK *      failure: something else * * NOTE: *	This could be written to be more efficient, but it's a big *	improvement over how it used to be. */int blkall_mark_free(int64_t first_block, int64_t last_block){	int64_t blk_num;	int ddo_rc = FSCK_OK;	int64_t page_num;	int64_t last_page_num = -1;	uint32_t word_offset;	uint32_t bit_mask;	struct fsck_blk_map_page *this_page;	uint32_t *this_word;	for (blk_num = first_block; blk_num <= last_block; blk_num++) {		blkmap_find_bit(blk_num, &page_num, &word_offset, &bit_mask);		if (page_num != last_page_num) {			if (last_page_num != -1)				blkmap_put_page(last_page_num);			ddo_rc = blkmap_get_page(page_num, &this_page);			if (ddo_rc)				return ddo_rc;			last_page_num = page_num;		}		this_word = (uint32_t *) ((char *) this_page + word_offset);		/* mark it not allocated */		(*this_word) &= ~bit_mask;	}	if (last_page_num != -1)		blkmap_put_page(last_page_num);	return (FSCK_OK);}/**************************************************************************** * NAME: blkall_increment_owners * * FUNCTION: Adjust the fsck workspace to show one more owner for the *           indicated block. * * PARAMETERS: *      first_block  - input - ordinal number of the first filesystem block *                             whose owner count is to be adjusted. *      last_block   - input - ordinal number of the first filesystem block *                             whose owner count is to be adjusted. *	msg_info_ptr - input - information needed to issue messages for this *                             extent.  If NULL, no messages will be issued * * RETURNS: *      success: 0, or 1 if multiply-allocated blocks found *      failure: something less than 0 */int blkall_increment_owners(int64_t first_block,			    int64_t last_block,			    struct fsck_ino_msg_info *msg_info_ptr){	int dio_rc;	int64_t blk_num;	int64_t page_num;	int64_t last_page_num = -1;	uint32_t word_offset;	uint32_t bit_mask;	struct fsck_blk_map_page *this_page;	uint32_t *this_word;	int is_a_dup = 0;	int64_t first_in_dup_range = 0;	int32_t size_of_dup_range = 0;	for (blk_num = first_block; blk_num <= last_block; blk_num++) {		blkmap_find_bit(blk_num, &page_num, &word_offset, &bit_mask);		if (page_num != last_page_num) {			if (last_page_num != -1)				blkmap_put_page(last_page_num);			dio_rc = blkmap_get_page(page_num, &this_page);			if (dio_rc)				return dio_rc;			last_page_num = page_num;		}		this_word = (uint32_t *) ((char *) this_page + word_offset);		if (((*this_word) & bit_mask) != bit_mask) {			/*			 * not allocated yet			 */			/* mark it allocated */			(*this_word) |= bit_mask;			/* Record previously found duplicate range */			if (size_of_dup_range) {				if (msg_info_ptr)				    fsck_send_msg(fsck_DUPBLKREF,					size_of_dup_range,					(long long) first_in_dup_range,					fsck_ref_msg(msg_info_ptr->msg_inotyp),

⌨️ 快捷键说明

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