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

📄 mkfs.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   Copyright (C) International Business Machines Corp., 2000-2005 * *   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 <unistd.h>#include <sys/stat.h>#if HAVE_SYS_SYSMACROS_H#include <sys/sysmacros.h>#endif#include <jfs_types.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <ctype.h>#include "jfs_endian.h"#include "jfs_filsys.h"#include "jfs_dinode.h"#include "jfs_superblock.h"#include "initmap.h"#include "inodes.h"#include "inode.h"#include "inodemap.h"#include "super.h"#include "logform.h"#include "jfs_dmap.h"#include "message.h"#include "debug.h"#include "jfs_version.h"#include "utilsubs.h"unsigned type_jfs;char *program_name;extern int LogOpenMode;FILE *open_by_label(uuid_t, int, int, char *, int *);static int AGsize;/* Define a parameter array for messages */#define MAXPARMS        9#define MAXSTR          128char *msg_parms[MAXPARMS];char msgstr[MAXSTR];#define L2MEGABYTE      20#define MEGABYTE        (1 << L2MEGABYTE)#define MEGABYTE32     (MEGABYTE << 5)#define MAX_LOG_PERCENTAGE  10	/* Log can be at most 10% of disk */#define create_journal_only  1#define use_existing_journal 2/* * The following macro defines the initial number of aggregate inodes which * are initialized when a new aggregate is created.  This does not include * any fileset inodes as those are initialized separately. */#define INIT_NUM_AGGR_INODES    (BADBLOCK_I + 1)static struct dinode aggr_inodes[INIT_NUM_AGGR_INODES];void mkfs_usage(void){	printf("\nUsage:  %s [-cOqV] [-j log_device] [-J options] "	       "[-L vol_label] [-s log_size] device [ blocks ]\n",	       program_name);	printf("\nEmergency help:\n"	       " -c            Check device for bad blocks before building file system.\n"	       " -O            Provide case-insensitive support for OS/2 compatability.\n"	       " -q            Quiet execution.\n"	       " -V            Print version information only.\n"	       " -j log_device Set external journal device.\n"	       " -J options    Set external journal options.\n"	       " -L vol_label  Set volume label for the file system.\n"	       " -s log_size   Set log size (in megabytes).\n\n"	       "NOTE: -j and -J cannot be used at the same time.\n");	return;}/*-------------------------------------------------------------------- * NAME: create_fileset * * FUNCTION: Do all work to create a fileset in an aggregate * * PARAMETERS: *      dev_ptr         - open port of device to write to *      aggr_block_size - block size for aggregate *      start_block     - Number of blocks used by aggregate metadata, indicates *                        first block available for writing fileset metadata. *                        All fileset writes will be offsets from this. *      inostamp        - Inode stamp value to be used. * * RETURNS: *      success: 0 *      failure: any other value */static int create_fileset(FILE *dev_ptr, int aggr_block_size,			  int64_t start_block, unsigned inostamp){	int rc;	int64_t inode_table_loc, inode_map_loc;	int inode_table_size, inode_map_size;	/*	 * Find space for the inode allocation map page	 *	 * Also find the fileset inode map location on disk (inode_map_loc).	 * We need to know this in order to initialize the fileset inodes	 * with the proper iag value.	 *	 * Since we only have one fileset per aggregate in the first release,	 * we always know where the inode map will start.  Therefore, currently	 * we use a hard-coded value.  When we add multiple filesets per	 * aggregate this will need to be modified to find the space for the	 * inode map by looking in the block allocation map for available space.	 */	inode_map_size = SIZE_OF_MAP_PAGE << 1;#ifdef ONE_FILESET_PER_AGGR	/*	 * The first extent of the fileset inode allocation map follows the	 * first extent of the first extent of the fileset inodes at the	 * beginning of the fileset	 */	inode_map_loc = start_block + INODE_EXTENT_SIZE / aggr_block_size;#else	inode_map_loc = get_space(inode_map_size);#endif	/*	 * Allocate Aggregate Inodes for Fileset	 */	rc = init_fileset_inodes(aggr_block_size, dev_ptr, inode_map_loc,				 inode_map_size, start_block, inostamp);	if (rc != 0)		return (rc);	/*	 * Create Fileset Inode Table - first extent	 */	rc = init_fileset_inode_table(aggr_block_size, dev_ptr,				      &inode_table_loc, &inode_table_size,				      start_block, inode_map_loc, inostamp);	if (rc != 0)		return (rc);	/*	 * Create Fileset Inode Allocation Map - first extent	 */	rc = init_inode_map(aggr_block_size, dev_ptr, inode_table_loc,			    inode_table_size, inode_map_loc, inode_map_size,			    (ACL_I + 1), AGsize, FILESYSTEM_I);	return rc;}/*-------------------------------------------------------------------- * NAME: create_aggregate * * FUNCTION: Do all work to create an aggregate * * PARAMETERS: *      dev_ptr                 - open port of device to write to *      volume_label            - label for volume *      number_of_blocks        - number of blocks for aggregate *      aggr_block_size         - block size for aggregate *      phys_block_size         - physical block size of device *      type_jfs                - JFS type to create *      verify_blocks           - indicates if we should verify every block *      log_uuid                - uuid of log device * * NOTES: The superblocks are the last things written to disk.  In the event *        of a system crash during mkfs this device will not appear to have *        a real JFS filesystem.  This should prevent us from attempting to *        mount a partially initialized filesystem. * * RETURNS: *      success: 0 *      failure: any other value */static int create_aggregate(FILE *dev_ptr,			    char *volume_label,			    int64_t number_of_blocks,			    int aggr_block_size,			    int phys_block_size,			    unsigned type_jfs,			    char *logdev,			    int64_t logloc,			    int logsize,			    bool verify_blocks,			    uuid_t log_uuid){	struct superblock aggr_superblock;	void *buffer;	int rc;	int64_t index;	int64_t first_block, last_block;	int64_t reserved_size;	int64_t aggr_inode_map_loc;	int aggr_inode_map_sz;	xad_t inode_map_dscr;	int64_t secondary_ait_address, secondary_aimap_address;	int64_t secondary_ait_end;	int64_t fsck_wspace_address, num_bits;	int fsck_wspace_length, fsck_svclog_length, npages;	unsigned inostamp;	struct dinode fileset_inode;	/*	 * Find where fsck working space will live on disk and mark those	 * blocks.  The fsck working space is always at the very end of the	 * aggregate so once we know how big it is we can back up from the	 * end to determine where it needs to start.	 *	 * Need enough 4k pages to cover:	 *  - 1 bit per block in aggregate rounded up to BPERDMAP boundary	 *  - 1 extra 4k page to handle control page, intermediate level pages	 *  - 50 extra 4k pages for the chkdsk service log	 */	num_bits =	    ((number_of_blocks + BPERDMAP - 1) >> L2BPERDMAP) << L2BPERDMAP;	npages = ((num_bits + (BITSPERPAGE - 1)) / BITSPERPAGE) + 1 + 50;	fsck_wspace_length = (npages << L2PSIZE) / aggr_block_size;	fsck_wspace_address = number_of_blocks - fsck_wspace_length;	fsck_svclog_length = (50 << L2PSIZE) / aggr_block_size;	/*	 * Now we want the fsck working space to be ignored as actually being	 * part of the filesystem	 */	number_of_blocks -= fsck_wspace_length;	/*	 * Initialize disk block map, so blocks can be marked as they are used	 * Blocks used for fsck working space will be marked here since we	 * don't want those blocks to be accounted for when maxag is set	 */	inostamp = (unsigned) time(NULL);	rc = calc_map_size(number_of_blocks, aggr_inodes, aggr_block_size,			   &AGsize, inostamp);	if (rc != 0)		return rc;	/*	 * Initialize and clear reserved disk blocks	 */	reserved_size = AGGR_RSVD_BYTES;	buffer = calloc(reserved_size, sizeof (char));	if (buffer == NULL) {		message_user(MSG_OSO_INSUFF_MEMORY, NULL, 0, OSO_MSG);		return (ENOMEM);	}	rc = ujfs_rw_diskblocks(dev_ptr, 0, reserved_size, buffer, PUT);	if (rc != 0)		return rc;	for (index = 0;	     ((index < reserved_size / aggr_block_size) && (rc == 0));	     index++) {		rc = markit(index, ALLOC);	}	if (rc != 0)		return rc;	/*	 * In case mkfs does not complete, but we have an old superblock	 * already on this device, we will zero the superblock disk blocks at	 * the beginning and then write the real superblock to disk last.	 * (This keeps the device from appearing to have a complete filesystem	 * when initialization is not complete.)	 */	rc = ujfs_rw_diskblocks(dev_ptr, SUPER1_OFF, SIZE_OF_SUPER, buffer,				PUT);	if (rc != 0) {		free(buffer);		return rc;	}	rc = ujfs_rw_diskblocks(dev_ptr, SUPER2_OFF, SIZE_OF_SUPER, buffer,				PUT);	if (rc != 0) {		free(buffer);		return rc;	}	free(buffer);	/* Mark blocks allocated for superblocks. */	first_block = SUPER1_OFF / aggr_block_size;	last_block = first_block + (SIZE_OF_SUPER / aggr_block_size);	for (index = first_block; ((index < last_block) && (rc == 0)); index++) {		rc = markit(index, ALLOC);	}	if (rc != 0)		return rc;	first_block = SUPER2_OFF / aggr_block_size;	last_block = first_block + (SIZE_OF_SUPER / aggr_block_size);	for (index = first_block; ((index < last_block) && (rc == 0)); index++) {		rc = markit(index, ALLOC);	}	if (rc != 0)		return rc;	/*	 * Initialize First Extent of Aggregate Inode Allocation Map	 */	aggr_inode_map_loc = AIMAP_OFF;	aggr_inode_map_sz = SIZE_OF_MAP_PAGE << 1;	rc = init_inode_map(aggr_block_size, dev_ptr, AITBL_OFF,			    INODE_EXTENT_SIZE,			    aggr_inode_map_loc / aggr_block_size,			    aggr_inode_map_sz, INIT_NUM_AGGR_INODES + 1, AGsize,			    AGGREGATE_I);	if (rc != 0)		return rc;	/*	 * Initialize first inode extent of Aggregate Inode Table	 */	rc = init_aggr_inode_table(aggr_block_size, dev_ptr, aggr_inodes,				   INIT_NUM_AGGR_INODES, AITBL_OFF,				   aggr_inode_map_loc / aggr_block_size,				   aggr_inode_map_sz, inostamp);	if (rc != 0)		return rc;	/*	 * Now initialize the secondary aggregate inode table and map	 *	 * We can use the same aggr_inodes we already initialized except for	 * the aggregate self inode.  This will be updated by the call to	 * init_aggr_inode_table() to point to the secondary table instead of	 * the primary table.	 *	 * First we need to determine the location; it will follow the block	 * map.  Since the block map might be sparse we need to use the number	 * of blocks instead of the length of the extents.  This works since	 * the extents are in the inode for mkfs	 */	inode_map_dscr =	    ((xtpage_t *) & (aggr_inodes[BMAP_I].di_DASD))->xad[XTENTRYSTART];	secondary_aimap_address =	    addressXAD(&inode_map_dscr) + aggr_inodes[BMAP_I].di_nblocks;	secondary_ait_address =	    (secondary_aimap_address * aggr_block_size) +	    (SIZE_OF_MAP_PAGE << 1);	secondary_ait_end =	    (secondary_ait_address + INODE_EXTENT_SIZE) / aggr_block_size;

⌨️ 快捷键说明

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