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

📄 mkfs.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * EFS version of mkfs. * * $Revision: 1.2 $ */#include "efs.h"#include <sys/stat.h>#include <sys/dkio.h>#include <diskinfo.h>#include <sys/ustat.h>#include <sys/major.h>#define HP_DISK_MODEL#ifdef HP_DISK_MODEL#include "diskmodel.param"#include "diskdevices.h"#endifextern	char *malloc();extern	char *calloc();void cgsizepick();void efs_newregfile();#define GOOD_INODE_TOTAL(b) (b / 10 + (b > 20000 ? 1000 : b / 20))char	*progname;		/* name of this program *//* user supplied information */char	*special;		/* name of special device */char 	*rawpath;		/* equivalent raw device (may be the same) */long	fs_blocks;		/* total blocks in filesystem */long 	dev_blocks;		/* total blocks on device */ino_t	fs_isize = 0;		/* total minimum inodes in partition */short	fs_sectors;		/* # of sectors per track */int	user_inodes = 0;/* internally supplied information */long	cg_align;		/* alignment for cylinder groups */long	i_align;		/* alignment for inodes *//* random variables */long	firstcg;		/* block offset to first cg */long	cg_fsize = 0;		/* data size for a cylinder group */long	cg_isize;		/* inode size for a cylinder group */char	is_ittybitty;		/* non-zero for itty bitty filesystems */int	fs_fd;			/* fd to read/write on for special */long	ncg;			/* number of cylinder groups */struct	efs *fs;		/* pointer to sblock.fs */char	*bitmap;		/* base of incore copy of bitmap */long	bitmap_blocks;		/* number of bb's in bitmap */long	bitmap_bytes;		/* number of bytes in bitmap (exact) */char	*proto;			/* name of proto file */char	*charp;FILE	*fproto;		/* FILE proto is open on during reading */char	string[1000];		/* temp buffer for parsing proto */int 	end_blocks;		/* blocks used by replsb at end */int 	start_blocks;		/* blocks used by boot, superblock & bitmap 				 * (rounded up to a cg_align boundary) */int	cyl_align = 0;		/* in auto mode, align inodes and data to				 * cylinder boundaries */int    	debug = 0;/* * This union declares a single BB, assuming that the minimum for raw i/o * is at least a BB. */union {	struct	efs fs;	char	block[BBTOB(BTOBB(sizeof(struct efs)))];} sblock;void	getstr();void clear_other_sb();int quiet = 0;int interact = 0;int use_writeb = 0;int short_form = 1;int recover_option = 0;intgood_cg_size(blocks, iblocks, align)int	blocks, iblocks, align;{	int	size;	size = (blocks / 100) + 20000;	if (size < ((blocks + iblocks - 1) / iblocks) * align)		size = ((blocks + iblocks - 1) / iblocks) * align;	return size;}/* Given an (extended) dev_t, put it into the on-disk * union. If its components are within the range understood by earlier * kernels, use the old format; if not, put -1 in the old field & * store it in the new one. Duplicates logic in fs/efs/efs_inode.c * * XXXdh mkfs should really use the efs_putdev() in efs/cmd/nlib/libefs.a, * but that is missing several functions needed by the proto file stuff, * so until those are moved into nlib & tested, we have to use the old  * lib/libefs.a */static voidefs_putdev(dev_t dev, union di_addr *di){major_t maj;minor_t min;	if ( ((maj = (dev >> L_BITSMINOR)) > O_MAXMAJ) ||	     ((min = (dev & L_MAXMIN)) > O_MAXMIN)) {		di->di_dev.odev = -1;		di->di_dev.ndev = dev;	}	else		di->di_dev.odev = (maj << O_BITSMINOR) | min;}void main(argc, argv)	int argc;	char **argv;{	int cgblocks;	int iblocks;        int add_inodes = 0;	int i, nargs;	int fp;	char **ap;	progname = argv[0];	/*	The (-q) option is not really intended to be documented or used		by users.  It is here for use of programs like the		vadmin disk tool.  Olson, 10/88		Another change (daveh 10/26/88): the default is now to just		go ahead. If you want confirmation, give the -i flag.		(Note: ALL - flags MUST come before any other arguments,		for backward compatibility with any scripts which use the		long forms).	*/	nargs = (argc > 4) ? 4 : argc;	ap = argv;	for (i = 1; i < nargs; i++)	{		if (ap[i][0] != '-') break;		switch (ap[i][1])		{   	        case 'd' : debug = 1;                           break;		case 'q' : quiet++;			   break;		case 'i' : interact++;			   break;		case 'r' : recover_option++;			   break;		case 'a' : cyl_align++;			   break;		case 'n' : i++;			   user_inodes = atoi(ap[i]);			   argc--;			   argv++;			   break;		default  : userr();		}		argc--;		argv++;	}	/* If interactive use is specified, clobber 'quiet' so fs params	   get printed for the user. (-q -i is pretty stupid, but just	   in case...)	   */	if (interact) quiet = 0;	if (argc != 3) {	   fprintf(stderr, "Usage: mkfs diskname protofile\n");	   exit(-1);	}	proto = argv[2];	special = argv[1];	fproto = fopen(proto, "r");	if (!fproto) {	    fprintf(stderr, "%s: can't open proto file %s\n",		    progname, proto);	    exit(-1);	}	getstr();			/* ignore get boot image */	fs_blocks = getnum();	fs_isize = GOOD_INODE_TOTAL(fs_blocks);        add_inodes = (fs_blocks - 0x8000) / 4;        if (add_inodes < 0)           add_inodes = 0;        if (add_inodes > 4096)           add_inodes = 4096;        fs_isize += add_inodes;	fs_sectors = getnum();#ifdef HP_DISK_MODEL	fs_sectors = NSECTORS;#endif	cg_align = 1;		/* No alignment */	i_align = 1;		/* No alignment */	       	/* protect user against himself. sigh... */		if ((fs_blocks == 0)  ||	    (fs_isize == 0)   ||	    (fs_sectors == 0) ||	    (cg_align == 0)   ||	    (i_align == 0))  	    {		fprintf(stderr,"%s: Illegal zero numeric parameter.\n",			progname);		exit(-1);	    }	/* NOTE (daveh 12/13/89): if fs_blocks is greater than the 2 gig	 * limit, we must use the new writeb system call (and cannot	 * proceed if this is not present, ie on a 3.2 kernel).	 * This works only on a char device, so we need in that case to find	 * the equivalent char device even if invoked on block.	 * Also, the structure of efs extent descriptors imposes, for the	 * moment, an 8 gig absolute upper limit. (24 bit offsets).	 */	if (fs_blocks > 0xffffff)	{		fprintf(stderr,"%s: filesystems may not exceed 8 gigabytes!\n",			progname);		exit(-1);	}	if ((fs_fd = open(special, O_RDWR|O_CREAT, 0664)) < 0) 	    {		fprintf(stderr, "%s: can't open %s\n",			progname, special);		exit(-1);	    }	/* 	 * Now seek to the end of the file and then back.	 */	fp = lseek(fs_fd, (fs_blocks * 512) - 1, SEEK_SET);	if (fp != (fs_blocks * 512 -1)) {	   perror(progname);	   exit(-1);	}	if (write(fs_fd, "\000", 1) != 1) {	   perror(progname);	   exit(-1);	}	   	/*	 * Compute the number of blocks used by the bootblock, superblock	 * & bitmap, rounded up to a cg_align boundary. The first cylinder	 * group starts there.	 * The replicated superblock at the end effectively consumes cg_align 	 * blocks.	 */	bitmap_bytes = (fs_blocks + BITSPERBYTE - 1) / BITSPERBYTE;	bitmap_blocks = BTOBB(bitmap_bytes);	start_blocks = 2 + bitmap_blocks;		if (i = (start_blocks % cg_align))		start_blocks += (cg_align - i);	firstcg = start_blocks;	end_blocks = cg_align;	cgblocks = fs_blocks - (start_blocks + end_blocks);	iblocks = (fs_isize + EFS_INOPBB - 1) / EFS_INOPBB;	/*	 * If file system is itty bitty, handle it specially	 */	if (short_form &&	    fs_blocks < 2 * good_cg_size(cgblocks, iblocks, cg_align))	{		is_ittybitty = 1;		ncg = 1;		firstcg = start_blocks = 2 + bitmap_blocks;		end_blocks = 1;		cg_fsize = fs_blocks - (start_blocks + end_blocks);		cg_align = i_align = 1;		if (cg_fsize <= 0) 		{			fprintf(stderr,				"%s: not enough space to make filesystem\n",				progname);			exit(-1);		}		cg_isize = (fs_isize + EFS_INOPBB - 1) / EFS_INOPBB;		if (cg_isize >= cg_fsize) 		{			fprintf(stderr,		"%s: invalid filesystem size - inodes larger than partition\n",			        progname);			exit(-1);		}		buildfs();		exit(0);	}	/*	 * If size of cylinder groups not yet specified, compute a good	 * size to efficiently fit the available space.	 * Compute number of cylinder groups and blocks of inodes per cylinder 	 * group.	 */	if (!cg_fsize)	{		if (cyl_align)			cgsizepick(cgblocks, iblocks, cg_align,				   &ncg, &cg_fsize, &cg_isize);		else		{			cg_fsize = good_cg_size(cgblocks, iblocks, cg_align);			ncg = cgblocks / cg_fsize;			cg_fsize = cgblocks / ncg;			cg_isize = cg_fsize / (cgblocks / iblocks);		}	}	else	{		/* round cg_fsize down to a cg_align multiple. Sanity check:		 * if given cg_fsize is < align, complain & exit */		if (cg_fsize < cg_align)		{			fprintf(stderr,		"%s: invalid cgsize - smaller than specified alignment.\n",			progname);			exit(-1);		}		cg_fsize -= cg_fsize % cg_align; 		if (cg_fsize > cgblocks)		{			fprintf(stderr,		"%s: invalid cgsize - larger than available space.\n",			progname);			exit(-1);		}		ncg = cgblocks / cg_fsize;		/* Now the inode computations:		 * Adjust cg_isize to be a multiple of i_align.  Round up or		 * down, whichever is closest, unless this would make it zero!		 */		cg_isize = (iblocks + ncg - 1) / ncg;		if (i = (cg_isize % i_align))		{			if (cg_isize < i_align)				cg_isize = i_align;			else if (i < (i_align / 2))				cg_isize -= i;			else				cg_isize += (i_align - i);		}	}	if (cg_isize >= cg_fsize)	{		fprintf(stderr,	"%s: Ridiculous number of inodes; no space for data.\n",		progname);		exit(-1);	}	fs_isize = cg_isize * ncg * EFS_INOPBB;	buildfs();        fprintf(stderr, "%s: SUCCESSFUL COMPLETION\n", progname);	exit(0);}	/* * Get info about device size & geometry. */getdevinfo(){	int	heads;	int	add_inodes = 0;	if ((dev_blocks = findsize(special)) <= 0)	{		fprintf(stderr,"Can't determine size of %s\n", special);		blather();		exit(-1);	}	fs_blocks = dev_blocks;    /* by default, use whole device */	if ((fs_sectors = findtrksize(special)) <= 0)	{		fprintf(stderr,"Can't determine tracksize of %s\n", special);		blather();		exit(-1);	}	if ((heads = findnumhead(special)) <= 0)	{		fprintf(stderr,"Can't get number of heads on %s\n", special);		blather();		exit(-1);	}	fs_isize = GOOD_INODE_TOTAL(fs_blocks); 	/*	 * On root partitions > 16MB, add 512 inodes for each additional MB.	 */	if (is_rootpart(special))	{		add_inodes = (fs_blocks - 0x8000) / 4;		if (add_inodes < 0)			add_inodes = 0;		if (add_inodes > 4096)			add_inodes = 4096;	}	fs_isize += add_inodes;	if (user_inodes)	{		if (user_inodes < fs_isize)			fprintf(stderr,"Warning: specified number of inodes %d is smaller than normal default %d\n", user_inodes, fs_isize);		fs_isize = user_inodes;	}	if (cyl_align)	{		cg_align = fs_sectors * heads;		i_align = fs_sectors * heads;	}	else	{		cg_align = 1;		i_align = 1;	}}blather(){	fprintf(stderr,"Check that device exists and is writeable.\n");	fprintf(stderr,"(Note that it is possible for a special file\n");	fprintf(stderr,"to exist and have writeable permissions, but\n");	fprintf(stderr,"for there to be no real device corresponding\n");	fprintf(stderr,"to it).\n");}/* * cgsizepick() chooses cylinder group size, inodes per cylinder group, * and number of cylinder groups for a filesystem.  It holds inodes per * cylinder group to a constant and varies the data blocks per cylinder * group by up to 20 percent either way, looking for the least amount * of space wastage.  This algorithm is optimized for large align values. */voidcgsizepick(blocks, iblocks, align, addr_ncg, addr_cg_fsize, addr_cg_isize)int blocks, iblocks, align;long *addr_ncg, *addr_cg_fsize, *addr_cg_isize;{	int cgs, cguess, i, waste;	int savecgs, savecgsize, savecgisize;	int prevwaste = blocks;	int mincgsize, mult;	mult = (blocks + iblocks - 1) / iblocks;

⌨️ 快捷键说明

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