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

📄 mke2fs.c

📁 busybox最新版的源码:学习和应用的好东东,多的不说了,大家看后再说吧
💻 C
📖 第 1 页 / 共 3 页
字号:
/* vi: set sw=4 ts=4: *//* * mke2fs.c - Make a ext2fs filesystem. * * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, *	2003, 2004, 2005 by Theodore Ts'o. * * This file may be redistributed under the terms of the GNU Public * License. *//* Usage: mke2fs [options] device * * The device may be a block device or a image of one, but this isn't * enforced (but it's not much fun on a character device :-). */#include <stdio.h>#include <string.h>#include <fcntl.h>#include <ctype.h>#include <time.h>#include <getopt.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <mntent.h>#include <sys/ioctl.h>#include <sys/types.h>#include "e2fsbb.h"#include "ext2fs/ext2_fs.h"#include "uuid/uuid.h"#include "e2p/e2p.h"#include "ext2fs/ext2fs.h"#include "util.h"#define STRIDE_LENGTH 8#ifndef __sparc__#define ZAP_BOOTBLOCK#endifstatic const char * device_name;/* Command line options */static int	cflag;static int	quiet;static int	super_only;static int	force;static int	noaction;static int	journal_size;static int	journal_flags;static const char *bad_blocks_filename;static __u32	fs_stride;static struct ext2_super_block param;static char *creator_os;static char *volume_label;static char *mount_dir;static char *journal_device = NULL;static int   sync_kludge; /* Set using the MKE2FS_SYNC env. option */static int sys_page_size = 4096;static int linux_version_code = 0;static int int_log2(int arg){	int l = 0;	arg >>= 1;	while (arg) {		l++;		arg >>= 1;	}	return l;}static int int_log10(unsigned int arg){	int	l;	for (l = 0; arg; l++)		arg = arg / 10;	return l;}/* * This function sets the default parameters for a filesystem * * The type is specified by the user.  The size is the maximum size * (in megabytes) for which a set of parameters applies, with a size * of zero meaning that it is the default parameter for the type. * Note that order is important in the table below. */#define DEF_MAX_BLOCKSIZE -1static const char default_str[] = "default";struct mke2fs_defaults {	const char	*type;	int		size;	int		blocksize;	int		inode_ratio;};static const struct mke2fs_defaults settings[] = {	{ default_str,	 0, 4096, 8192 },	{ default_str, 512, 1024, 4096 },	{ default_str,	 3, 1024, 8192 },	{ "journal",	 0, 4096, 8192 },	{ "news",	 0, 4096, 4096 },	{ "largefile",	 0, 4096, 1024 * 1024 },	{ "largefile4",  0, 4096, 4096 * 1024 },	{ 0,		 0,    0, 0},};static void set_fs_defaults(const char *fs_type,			    struct ext2_super_block *super,			    int blocksize, int sector_size,			    int *inode_ratio){	int	megs;	int	ratio = 0;	const struct mke2fs_defaults *p;	int	use_bsize = 1024;	megs = super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / 1024;	if (inode_ratio)		ratio = *inode_ratio;	if (!fs_type)		fs_type = default_str;	for (p = settings; p->type; p++) {		if ((strcmp(p->type, fs_type) != 0) &&		    (strcmp(p->type, default_str) != 0))			continue;		if ((p->size != 0) && (megs > p->size))			continue;		if (ratio == 0)			*inode_ratio = p->inode_ratio < blocksize ?				blocksize : p->inode_ratio;		use_bsize = p->blocksize;	}	if (blocksize <= 0) {		if (use_bsize == DEF_MAX_BLOCKSIZE) {			use_bsize = sys_page_size;			if ((linux_version_code < (2*65536 + 6*256)) &&			    (use_bsize > 4096))				use_bsize = 4096;		}		if (sector_size && use_bsize < sector_size)			use_bsize = sector_size;		if ((blocksize < 0) && (use_bsize < (-blocksize)))			use_bsize = -blocksize;		blocksize = use_bsize;		super->s_blocks_count /= blocksize / 1024;	}	super->s_log_frag_size = super->s_log_block_size =		int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);}/* * Helper function for read_bb_file and test_disk */static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk){	bb_error_msg("Bad block %u out of range; ignored", blk);}/* * Busybox stuff */static void mke2fs_error_msg_and_die(int retval, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));static void mke2fs_error_msg_and_die(int retval, const char *fmt, ...){	va_list ap;	if (retval) {		va_start(ap, fmt);		fprintf(stderr,"\nCould not ");		vfprintf(stderr, fmt, ap);		fprintf(stderr, "\n");		va_end(ap);		exit(EXIT_FAILURE);	}}static void mke2fs_verbose(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));static void mke2fs_verbose(const char *fmt, ...){	va_list ap;	if (!quiet) {		va_start(ap, fmt);		vfprintf(stdout, fmt, ap);		fflush(stdout);		va_end(ap);	}}static void mke2fs_verbose_done(void){	mke2fs_verbose("done\n");}static void mke2fs_warning_msg(int retval, char *fmt, ... ) __attribute__ ((format (printf, 2, 3)));static void mke2fs_warning_msg(int retval, char *fmt, ... ){	va_list ap;	if (retval) {		va_start(ap, fmt);		fprintf(stderr,"\nWarning: ");		vfprintf(stderr, fmt, ap);		fprintf(stderr, "\n");		va_end(ap);	}}/* * Reads the bad blocks list from a file */static void read_bb_file(ext2_filsys fs, badblocks_list *bb_list,			 const char *bad_blocks_file){	FILE		*f;	errcode_t	retval;	f = xfopen(bad_blocks_file, "r");	retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block);	fclose (f);	mke2fs_error_msg_and_die(retval, "read bad blocks from list");}/* * Runs the badblocks program to test the disk */static void test_disk(ext2_filsys fs, badblocks_list *bb_list){	FILE		*f;	errcode_t	retval;	char		buf[1024];	sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,		quiet ? "" : "-s ", (cflag > 1) ? "-w " : "",		fs->device_name, fs->super->s_blocks_count);	mke2fs_verbose("Running command: %s\n", buf);	f = popen(buf, "r");	if (!f) {		bb_perror_msg_and_die("cannot run '%s'", buf);	}	retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block);	pclose(f);	mke2fs_error_msg_and_die(retval, "read bad blocks from program");}static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list){	dgrp_t			i;	blk_t			j;	unsigned		must_be_good;	blk_t			blk;	badblocks_iterate	bb_iter;	errcode_t		retval;	blk_t			group_block;	int			group;	int			group_bad;	if (!bb_list)		return;	/*	 * The primary superblock and group descriptors *must* be	 * good; if not, abort.	 */	must_be_good = fs->super->s_first_data_block + 1 + fs->desc_blocks;	for (i = fs->super->s_first_data_block; i <= must_be_good; i++) {		if (ext2fs_badblocks_list_test(bb_list, i)) {			bb_error_msg_and_die(				"Block %d in primary superblock/group descriptor area bad\n"				"Blocks %d through %d must be good in order to build a filesystem\n"				"Aborting ...", i, fs->super->s_first_data_block, must_be_good);		}	}	/*	 * See if any of the bad blocks are showing up in the backup	 * superblocks and/or group descriptors.  If so, issue a	 * warning and adjust the block counts appropriately.	 */	group_block = fs->super->s_first_data_block +		fs->super->s_blocks_per_group;	for (i = 1; i < fs->group_desc_count; i++) {		group_bad = 0;		for (j=0; j < fs->desc_blocks+1; j++) {			if (ext2fs_badblocks_list_test(bb_list,						       group_block + j)) {				mke2fs_warning_msg(!group_bad,					"the backup superblock/group descriptors at block %d contain\n"					"bad blocks\n", group_block);				group_bad++;				group = ext2fs_group_of_blk(fs, group_block+j);				fs->group_desc[group].bg_free_blocks_count++;				fs->super->s_free_blocks_count++;			}		}		group_block += fs->super->s_blocks_per_group;	}	/*	 * Mark all the bad blocks as used...	 */	retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter);	mke2fs_error_msg_and_die(retval, "mark bad blocks as used");	while (ext2fs_badblocks_list_iterate(bb_iter, &blk))		ext2fs_mark_block_bitmap(fs->block_map, blk);	ext2fs_badblocks_list_iterate_end(bb_iter);}/* * These functions implement a generalized progress meter. */struct progress_struct {	char		format[20];	char		backup[80];	__u32		max;	int		skip_progress;};static void progress_init(struct progress_struct *progress,			  const char *label,__u32 max){	int	i;	memset(progress, 0, sizeof(struct progress_struct));	if (quiet)		return;	/*	 * Figure out how many digits we need	 */	i = int_log10(max);	sprintf(progress->format, "%%%dd/%%%dld", i, i);	memset(progress->backup, '\b', sizeof(progress->backup)-1);	progress->backup[sizeof(progress->backup)-1] = 0;	if ((2*i)+1 < (int) sizeof(progress->backup))		progress->backup[(2*i)+1] = 0;	progress->max = max;	progress->skip_progress = 0;	if (getenv("MKE2FS_SKIP_PROGRESS"))		progress->skip_progress++;	fputs(label, stdout);	fflush(stdout);}static void progress_update(struct progress_struct *progress, __u32 val){	if ((progress->format[0] == 0) || progress->skip_progress)		return;	printf(progress->format, val, progress->max);	fputs(progress->backup, stdout);}static void progress_close(struct progress_struct *progress){	if (progress->format[0] == 0)		return;	printf("%-28s\n", "done");}/* * Helper function which zeros out _num_ blocks starting at _blk_.  In * case of an error, the details of the error is returned via _ret_blk_ * and _ret_count_ if they are non-NULL pointers.  Returns 0 on * success, and an error code on an error. * * As a special case, if the first argument is NULL, then it will * attempt to free the static zeroizing buffer.  (This is to keep * programs that check for memory leaks happy.) */static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num,			     struct progress_struct *progress,			     blk_t *ret_blk, int *ret_count){	int		j, count, next_update, next_update_incr;	static char	*buf;	errcode_t	retval;	/* If fs is null, clean up the static buffer and return */	if (!fs) {		if (buf) {			free(buf);			buf = 0;		}		return 0;	}	/* Allocate the zeroizing buffer if necessary */	if (!buf) {		buf = xzalloc(fs->blocksize * STRIDE_LENGTH);	}	/* OK, do the write loop */	next_update = 0;	next_update_incr = num / 100;	if (next_update_incr < 1)		next_update_incr = 1;	for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {		count = num - j;		if (count > STRIDE_LENGTH)			count = STRIDE_LENGTH;		retval = io_channel_write_blk(fs->io, blk, count, buf);		if (retval) {			if (ret_count)				*ret_count = count;			if (ret_blk)				*ret_blk = blk;			return retval;		}		if (progress && j > next_update) {			next_update += num / 100;			progress_update(progress, blk);		}	}	return 0;}static void write_inode_tables(ext2_filsys fs){	errcode_t	retval;	blk_t		blk;	dgrp_t		i;	int		num;	struct progress_struct progress;	if (quiet)		memset(&progress, 0, sizeof(progress));	else		progress_init(&progress, "Writing inode tables: ",			      fs->group_desc_count);	for (i = 0; i < fs->group_desc_count; i++) {		progress_update(&progress, i);

⌨️ 快捷键说明

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