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

📄 mkfs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1980, 1989, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)mkfs.c	8.3 (Berkeley) 2/3/94";#endif /* not lint */#include <unistd.h>#include <sys/param.h>#include <sys/time.h>#include <sys/wait.h>#include <sys/resource.h>#include <ufs/ufs/dinode.h>#include <ufs/ufs/dir.h>#include <ufs/ffs/fs.h>#include <sys/disklabel.h>#ifndef STANDALONE#include <a.out.h>#include <stdio.h>#endif/* * make file system for cylinder-group style file systems *//* * We limit the size of the inode map to be no more than a * third of the cylinder group space, since we must leave at * least an equal amount of space for the block map. * * N.B.: MAXIPG must be a multiple of INOPB(fs). */#define MAXIPG(fs)	roundup((fs)->fs_bsize * NBBY / 3, INOPB(fs))#define UMASK		0755#define MAXINOPB	(MAXBSIZE / sizeof(struct dinode))#define POWEROF2(num)	(((num) & ((num) - 1)) == 0)/* * variables set up by front end. */extern int	mfs;		/* run as the memory based filesystem */extern int	Nflag;		/* run mkfs without writing file system */extern int	Oflag;		/* format as an 4.3BSD file system */extern int	fssize;		/* file system size */extern int	ntracks;	/* # tracks/cylinder */extern int	nsectors;	/* # sectors/track */extern int	nphyssectors;	/* # sectors/track including spares */extern int	secpercyl;	/* sectors per cylinder */extern int	sectorsize;	/* bytes/sector */extern int	rpm;		/* revolutions/minute of drive */extern int	interleave;	/* hardware sector interleave */extern int	trackskew;	/* sector 0 skew, per track */extern int	headswitch;	/* head switch time, usec */extern int	trackseek;	/* track-to-track seek, usec */extern int	fsize;		/* fragment size */extern int	bsize;		/* block size */extern int	cpg;		/* cylinders/cylinder group */extern int	cpgflg;		/* cylinders/cylinder group flag was given */extern int	minfree;	/* free space threshold */extern int	opt;		/* optimization preference (space or time) */extern int	density;	/* number of bytes per inode */extern int	maxcontig;	/* max contiguous blocks to allocate */extern int	rotdelay;	/* rotational delay between blocks */extern int	maxbpg;		/* maximum blocks per file in a cyl group */extern int	nrpos;		/* # of distinguished rotational positions */extern int	bbsize;		/* boot block size */extern int	sbsize;		/* superblock size */extern u_long	memleft;	/* virtual memory available */extern caddr_t	membase;	/* start address of memory based filesystem */extern caddr_t	malloc(), calloc();union {	struct fs fs;	char pad[SBSIZE];} fsun;#define	sblock	fsun.fsstruct	csum *fscs;union {	struct cg cg;	char pad[MAXBSIZE];} cgun;#define	acg	cgun.cgstruct dinode zino[MAXBSIZE / sizeof(struct dinode)];int	fsi, fso;daddr_t	alloc();mkfs(pp, fsys, fi, fo)	struct partition *pp;	char *fsys;	int fi, fo;{	register long i, mincpc, mincpg, inospercg;	long cylno, rpos, blk, j, warn = 0;	long used, mincpgcnt, bpcg;	long mapcramped, inodecramped;	long postblsize, rotblsize, totalsbsize;	int ppid, status;	time_t utime;	quad_t sizepb;	void started();#ifndef STANDALONE	time(&utime);#endif	if (mfs) {		ppid = getpid();		(void) signal(SIGUSR1, started);		if (i = fork()) {			if (i == -1) {				perror("mfs");				exit(10);			}			if (waitpid(i, &status, 0) != -1 && WIFEXITED(status))				exit(WEXITSTATUS(status));			exit(11);			/* NOTREACHED */		}		(void)malloc(0);		if (fssize * sectorsize > memleft)			fssize = (memleft - 16384) / sectorsize;		if ((membase = malloc(fssize * sectorsize)) == 0)			exit(12);	}	fsi = fi;	fso = fo;	if (Oflag) {		sblock.fs_inodefmt = FS_42INODEFMT;		sblock.fs_maxsymlinklen = 0;	} else {		sblock.fs_inodefmt = FS_44INODEFMT;		sblock.fs_maxsymlinklen = MAXSYMLINKLEN;	}	/*	 * Validate the given file system size.	 * Verify that its last block can actually be accessed.	 */	if (fssize <= 0)		printf("preposterous size %d\n", fssize), exit(13);	wtfs(fssize - 1, sectorsize, (char *)&sblock);	/*	 * collect and verify the sector and track info	 */	sblock.fs_nsect = nsectors;	sblock.fs_ntrak = ntracks;	if (sblock.fs_ntrak <= 0)		printf("preposterous ntrak %d\n", sblock.fs_ntrak), exit(14);	if (sblock.fs_nsect <= 0)		printf("preposterous nsect %d\n", sblock.fs_nsect), exit(15);	/*	 * collect and verify the block and fragment sizes	 */	sblock.fs_bsize = bsize;	sblock.fs_fsize = fsize;	if (!POWEROF2(sblock.fs_bsize)) {		printf("block size must be a power of 2, not %d\n",		    sblock.fs_bsize);		exit(16);	}	if (!POWEROF2(sblock.fs_fsize)) {		printf("fragment size must be a power of 2, not %d\n",		    sblock.fs_fsize);		exit(17);	}	if (sblock.fs_fsize < sectorsize) {		printf("fragment size %d is too small, minimum is %d\n",		    sblock.fs_fsize, sectorsize);		exit(18);	}	if (sblock.fs_bsize < MINBSIZE) {		printf("block size %d is too small, minimum is %d\n",		    sblock.fs_bsize, MINBSIZE);		exit(19);	}	if (sblock.fs_bsize < sblock.fs_fsize) {		printf("block size (%d) cannot be smaller than fragment size (%d)\n",		    sblock.fs_bsize, sblock.fs_fsize);		exit(20);	}	sblock.fs_bmask = ~(sblock.fs_bsize - 1);	sblock.fs_fmask = ~(sblock.fs_fsize - 1);	sblock.fs_qbmask = ~sblock.fs_bmask;	sblock.fs_qfmask = ~sblock.fs_fmask;	for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1)		sblock.fs_bshift++;	for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1)		sblock.fs_fshift++;	sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize);	for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1)		sblock.fs_fragshift++;	if (sblock.fs_frag > MAXFRAG) {		printf("fragment size %d is too small, minimum with block size %d is %d\n",		    sblock.fs_fsize, sblock.fs_bsize,		    sblock.fs_bsize / MAXFRAG);		exit(21);	}	sblock.fs_nrpos = nrpos;	sblock.fs_nindir = sblock.fs_bsize / sizeof(daddr_t);	sblock.fs_inopb = sblock.fs_bsize / sizeof(struct dinode);	sblock.fs_nspf = sblock.fs_fsize / sectorsize;	for (sblock.fs_fsbtodb = 0, i = NSPF(&sblock); i > 1; i >>= 1)		sblock.fs_fsbtodb++;	sblock.fs_sblkno =	    roundup(howmany(bbsize + sbsize, sblock.fs_fsize), sblock.fs_frag);	sblock.fs_cblkno = (daddr_t)(sblock.fs_sblkno +	    roundup(howmany(sbsize, sblock.fs_fsize), sblock.fs_frag));	sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag;	sblock.fs_cgoffset = roundup(	    howmany(sblock.fs_nsect, NSPF(&sblock)), sblock.fs_frag);	for (sblock.fs_cgmask = 0xffffffff, i = sblock.fs_ntrak; i > 1; i >>= 1)		sblock.fs_cgmask <<= 1;	if (!POWEROF2(sblock.fs_ntrak))		sblock.fs_cgmask <<= 1;	sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1;	for (sizepb = sblock.fs_bsize, i = 0; i < NIADDR; i++) {		sizepb *= NINDIR(&sblock);		sblock.fs_maxfilesize += sizepb;	}	/*	 * Validate specified/determined secpercyl	 * and calculate minimum cylinders per group.	 */	sblock.fs_spc = secpercyl;	for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc;	     sblock.fs_cpc > 1 && (i & 1) == 0;	     sblock.fs_cpc >>= 1, i >>= 1)		/* void */;	mincpc = sblock.fs_cpc;	bpcg = sblock.fs_spc * sectorsize;	inospercg = roundup(bpcg / sizeof(struct dinode), INOPB(&sblock));	if (inospercg > MAXIPG(&sblock))		inospercg = MAXIPG(&sblock);	used = (sblock.fs_iblkno + inospercg / INOPF(&sblock)) * NSPF(&sblock);	mincpgcnt = howmany(sblock.fs_cgoffset * (~sblock.fs_cgmask) + used,	    sblock.fs_spc);	mincpg = roundup(mincpgcnt, mincpc);	/*	 * Ensure that cylinder group with mincpg has enough space	 * for block maps.	 */	sblock.fs_cpg = mincpg;	sblock.fs_ipg = inospercg;	if (maxcontig > 1)		sblock.fs_contigsumsize = MIN(maxcontig, FS_MAXCONTIG);	mapcramped = 0;	while (CGSIZE(&sblock) > sblock.fs_bsize) {		mapcramped = 1;		if (sblock.fs_bsize < MAXBSIZE) {			sblock.fs_bsize <<= 1;			if ((i & 1) == 0) {				i >>= 1;			} else {				sblock.fs_cpc <<= 1;				mincpc <<= 1;				mincpg = roundup(mincpgcnt, mincpc);				sblock.fs_cpg = mincpg;			}			sblock.fs_frag <<= 1;			sblock.fs_fragshift += 1;			if (sblock.fs_frag <= MAXFRAG)				continue;		}		if (sblock.fs_fsize == sblock.fs_bsize) {			printf("There is no block size that");			printf(" can support this disk\n");			exit(22);		}		sblock.fs_frag >>= 1;		sblock.fs_fragshift -= 1;		sblock.fs_fsize <<= 1;		sblock.fs_nspf <<= 1;	}	/*	 * Ensure that cylinder group with mincpg has enough space for inodes.	 */	inodecramped = 0;	used *= sectorsize;	inospercg = roundup((mincpg * bpcg - used) / density, INOPB(&sblock));	sblock.fs_ipg = inospercg;	while (inospercg > MAXIPG(&sblock)) {		inodecramped = 1;		if (mincpc == 1 || sblock.fs_frag == 1 ||		    sblock.fs_bsize == MINBSIZE)			break;		printf("With a block size of %d %s %d\n", sblock.fs_bsize,		    "minimum bytes per inode is",		    (mincpg * bpcg - used) / MAXIPG(&sblock) + 1);		sblock.fs_bsize >>= 1;		sblock.fs_frag >>= 1;		sblock.fs_fragshift -= 1;		mincpc >>= 1;		sblock.fs_cpg = roundup(mincpgcnt, mincpc);		if (CGSIZE(&sblock) > sblock.fs_bsize) {			sblock.fs_bsize <<= 1;			break;		}		mincpg = sblock.fs_cpg;		inospercg =		    roundup((mincpg * bpcg - used) / density, INOPB(&sblock));		sblock.fs_ipg = inospercg;	}	if (inodecramped) {		if (inospercg > MAXIPG(&sblock)) {			printf("Minimum bytes per inode is %d\n",			    (mincpg * bpcg - used) / MAXIPG(&sblock) + 1);		} else if (!mapcramped) {			printf("With %d bytes per inode, ", density);			printf("minimum cylinders per group is %d\n", mincpg);		}	}	if (mapcramped) {		printf("With %d sectors per cylinder, ", sblock.fs_spc);		printf("minimum cylinders per group is %d\n", mincpg);	}	if (inodecramped || mapcramped) {		if (sblock.fs_bsize != bsize)			printf("%s to be changed from %d to %d\n",			    "This requires the block size",			    bsize, sblock.fs_bsize);		if (sblock.fs_fsize != fsize)			printf("\t%s to be changed from %d to %d\n",			    "and the fragment size",			    fsize, sblock.fs_fsize);		exit(23);	}	/* 	 * Calculate the number of cylinders per group	 */	sblock.fs_cpg = cpg;	if (sblock.fs_cpg % mincpc != 0) {		printf("%s groups must have a multiple of %d cylinders\n",			cpgflg ? "Cylinder" : "Warning: cylinder", mincpc);		sblock.fs_cpg = roundup(sblock.fs_cpg, mincpc);		if (!cpgflg)			cpg = sblock.fs_cpg;	}	/*	 * Must ensure there is enough space for inodes.	 */	sblock.fs_ipg = roundup((sblock.fs_cpg * bpcg - used) / density,		INOPB(&sblock));	while (sblock.fs_ipg > MAXIPG(&sblock)) {		inodecramped = 1;		sblock.fs_cpg -= mincpc;		sblock.fs_ipg = roundup((sblock.fs_cpg * bpcg - used) / density,			INOPB(&sblock));	}	/*	 * Must ensure there is enough space to hold block map.	 */	while (CGSIZE(&sblock) > sblock.fs_bsize) {		mapcramped = 1;		sblock.fs_cpg -= mincpc;		sblock.fs_ipg = roundup((sblock.fs_cpg * bpcg - used) / density,			INOPB(&sblock));	}	sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock);	if ((sblock.fs_cpg * sblock.fs_spc) % NSPB(&sblock) != 0) {		printf("panic (fs_cpg * fs_spc) % NSPF != 0");		exit(24);	}	if (sblock.fs_cpg < mincpg) {		printf("cylinder groups must have at least %d cylinders\n",			mincpg);		exit(25);	} else if (sblock.fs_cpg != cpg) {		if (!cpgflg)			printf("Warning: ");		else if (!mapcramped && !inodecramped)			exit(26);		if (mapcramped && inodecramped)			printf("Block size and bytes per inode restrict");		else if (mapcramped)			printf("Block size restricts");		else			printf("Bytes per inode restrict");

⌨️ 快捷键说明

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