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

📄 super.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/fs/ufs/super.c * * Copyright (C) 1998 * Daniel Pirkl <daniel.pirkl@email.cz> * Charles University, Faculty of Mathematics and Physics *//* Derived from * *  linux/fs/ext2/super.c * * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * *  from * *  linux/fs/minix/inode.c * *  Copyright (C) 1991, 1992  Linus Torvalds * *  Big-endian to little-endian byte-swapping/bitmaps by *        David S. Miller (davem@caip.rutgers.edu), 1995 */ /* * Inspired by * *  linux/fs/ufs/super.c * * Copyright (C) 1996 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu) * Laboratory for Computer Science Research Computing Facility * Rutgers, The State University of New Jersey * * Copyright (C) 1996  Eddie C. Dost  (ecd@skynet.be) * * Kernel module support added on 96/04/26 by * Stefan Reinauer <stepan@home.culture.mipt.ru> * * Module usage counts added on 96/04/29 by * Gertjan van Wingerde <gertjan@cs.vu.nl> * * Clean swab support on 19970406 by * Francois-Rene Rideau <fare@tunes.org> * * 4.4BSD (FreeBSD) support added on February 1st 1998 by * Niels Kristian Bech Jensen <nkbj@image.dk> partially based * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>. * * NeXTstep support added on February 5th 1998 by * Niels Kristian Bech Jensen <nkbj@image.dk>. * * write support Daniel Pirkl <daniel.pirkl@email.cz> 1998 *  * HP/UX hfs filesystem support added by * Martin K. Petersen <mkp@mkp.net>, August 1999 * */#include <linux/config.h>#include <linux/module.h>#include <stdarg.h>#include <asm/bitops.h>#include <asm/uaccess.h>#include <asm/system.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/ufs_fs.h>#include <linux/slab.h>#include <linux/sched.h>#include <linux/stat.h>#include <linux/string.h>#include <linux/locks.h>#include <linux/blkdev.h>#include <linux/init.h>#include "swab.h"#include "util.h"#undef UFS_SUPER_DEBUG#undef UFS_SUPER_DEBUG_MORE#ifdef UFS_SUPER_DEBUG#define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;#else#define UFSD(x)#endif#ifdef UFS_SUPER_DEBUG_MORE/* * Print contents of ufs_super_block, useful for debugging */void ufs_print_super_stuff(struct super_block *sb,	struct ufs_super_block_first * usb1,	struct ufs_super_block_second * usb2, 	struct ufs_super_block_third * usb3){	printk("ufs_print_super_stuff\n");	printk("size of usb:     %u\n", sizeof(struct ufs_super_block));	printk("  magic:         0x%x\n", fs32_to_cpu(sb, usb3->fs_magic));	printk("  sblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_sblkno));	printk("  cblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_cblkno));	printk("  iblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_iblkno));	printk("  dblkno:        %u\n", fs32_to_cpu(sb, usb1->fs_dblkno));	printk("  cgoffset:      %u\n", fs32_to_cpu(sb, usb1->fs_cgoffset));	printk("  ~cgmask:       0x%x\n", ~fs32_to_cpu(sb, usb1->fs_cgmask));	printk("  size:          %u\n", fs32_to_cpu(sb, usb1->fs_size));	printk("  dsize:         %u\n", fs32_to_cpu(sb, usb1->fs_dsize));	printk("  ncg:           %u\n", fs32_to_cpu(sb, usb1->fs_ncg));	printk("  bsize:         %u\n", fs32_to_cpu(sb, usb1->fs_bsize));	printk("  fsize:         %u\n", fs32_to_cpu(sb, usb1->fs_fsize));	printk("  frag:          %u\n", fs32_to_cpu(sb, usb1->fs_frag));	printk("  fragshift:     %u\n", fs32_to_cpu(sb, usb1->fs_fragshift));	printk("  ~fmask:        %u\n", ~fs32_to_cpu(sb, usb1->fs_fmask));	printk("  fshift:        %u\n", fs32_to_cpu(sb, usb1->fs_fshift));	printk("  sbsize:        %u\n", fs32_to_cpu(sb, usb1->fs_sbsize));	printk("  spc:           %u\n", fs32_to_cpu(sb, usb1->fs_spc));	printk("  cpg:           %u\n", fs32_to_cpu(sb, usb1->fs_cpg));	printk("  ipg:           %u\n", fs32_to_cpu(sb, usb1->fs_ipg));	printk("  fpg:           %u\n", fs32_to_cpu(sb, usb1->fs_fpg));	printk("  csaddr:        %u\n", fs32_to_cpu(sb, usb1->fs_csaddr));	printk("  cssize:        %u\n", fs32_to_cpu(sb, usb1->fs_cssize));	printk("  cgsize:        %u\n", fs32_to_cpu(sb, usb1->fs_cgsize));	printk("  fstodb:        %u\n", fs32_to_cpu(sb, usb1->fs_fsbtodb));	printk("  contigsumsize: %d\n", fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_contigsumsize));	printk("  postblformat:  %u\n", fs32_to_cpu(sb, usb3->fs_postblformat));	printk("  nrpos:         %u\n", fs32_to_cpu(sb, usb3->fs_nrpos));	printk("  ndir           %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir));	printk("  nifree         %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree));	printk("  nbfree         %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree));	printk("  nffree         %u\n", fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree));	printk("\n");}/* * Print contents of ufs_cylinder_group, useful for debugging */void ufs_print_cylinder_stuff(struct super_block *sb, struct ufs_cylinder_group *cg){	printk("\nufs_print_cylinder_stuff\n");	printk("size of ucg: %u\n", sizeof(struct ufs_cylinder_group));	printk("  magic:        %x\n", fs32_to_cpu(sb, cg->cg_magic));	printk("  time:         %u\n", fs32_to_cpu(sb, cg->cg_time));	printk("  cgx:          %u\n", fs32_to_cpu(sb, cg->cg_cgx));	printk("  ncyl:         %u\n", fs16_to_cpu(sb, cg->cg_ncyl));	printk("  niblk:        %u\n", fs16_to_cpu(sb, cg->cg_niblk));	printk("  ndblk:        %u\n", fs32_to_cpu(sb, cg->cg_ndblk));	printk("  cs_ndir:      %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_ndir));	printk("  cs_nbfree:    %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_nbfree));	printk("  cs_nifree:    %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_nifree));	printk("  cs_nffree:    %u\n", fs32_to_cpu(sb, cg->cg_cs.cs_nffree));	printk("  rotor:        %u\n", fs32_to_cpu(sb, cg->cg_rotor));	printk("  frotor:       %u\n", fs32_to_cpu(sb, cg->cg_frotor));	printk("  irotor:       %u\n", fs32_to_cpu(sb, cg->cg_irotor));	printk("  frsum:        %u, %u, %u, %u, %u, %u, %u, %u\n",	    fs32_to_cpu(sb, cg->cg_frsum[0]), fs32_to_cpu(sb, cg->cg_frsum[1]),	    fs32_to_cpu(sb, cg->cg_frsum[2]), fs32_to_cpu(sb, cg->cg_frsum[3]),	    fs32_to_cpu(sb, cg->cg_frsum[4]), fs32_to_cpu(sb, cg->cg_frsum[5]),	    fs32_to_cpu(sb, cg->cg_frsum[6]), fs32_to_cpu(sb, cg->cg_frsum[7]));	printk("  btotoff:      %u\n", fs32_to_cpu(sb, cg->cg_btotoff));	printk("  boff:         %u\n", fs32_to_cpu(sb, cg->cg_boff));	printk("  iuseoff:      %u\n", fs32_to_cpu(sb, cg->cg_iusedoff));	printk("  freeoff:      %u\n", fs32_to_cpu(sb, cg->cg_freeoff));	printk("  nextfreeoff:  %u\n", fs32_to_cpu(sb, cg->cg_nextfreeoff));	printk("  clustersumoff %u\n", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clustersumoff));	printk("  clusteroff    %u\n", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_clusteroff));	printk("  nclusterblks  %u\n", fs32_to_cpu(sb, cg->cg_u.cg_44.cg_nclusterblks));	printk("\n");}#endif /* UFS_SUPER_DEBUG_MORE */static struct super_operations ufs_super_ops;static char error_buf[1024];void ufs_error (struct super_block * sb, const char * function,	const char * fmt, ...){	struct ufs_sb_private_info * uspi;	struct ufs_super_block_first * usb1;	va_list args;	uspi = sb->u.ufs_sb.s_uspi;	usb1 = ubh_get_usb_first(USPI_UBH);		if (!(sb->s_flags & MS_RDONLY)) {		usb1->fs_clean = UFS_FSBAD;		ubh_mark_buffer_dirty(USPI_UBH);		sb->s_dirt = 1;		sb->s_flags |= MS_RDONLY;	}	va_start (args, fmt);	vsprintf (error_buf, fmt, args);	va_end (args);	switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_ONERROR) {	case UFS_MOUNT_ONERROR_PANIC:		panic ("UFS-fs panic (device %s): %s: %s\n", 			kdevname(sb->s_dev), function, error_buf);	case UFS_MOUNT_ONERROR_LOCK:	case UFS_MOUNT_ONERROR_UMOUNT:	case UFS_MOUNT_ONERROR_REPAIR:		printk (KERN_CRIT "UFS-fs error (device %s): %s: %s\n",			kdevname(sb->s_dev), function, error_buf);	}		}void ufs_panic (struct super_block * sb, const char * function,	const char * fmt, ...){	struct ufs_sb_private_info * uspi;	struct ufs_super_block_first * usb1;	va_list args;		uspi = sb->u.ufs_sb.s_uspi;	usb1 = ubh_get_usb_first(USPI_UBH);		if (!(sb->s_flags & MS_RDONLY)) {		usb1->fs_clean = UFS_FSBAD;		ubh_mark_buffer_dirty(USPI_UBH);		sb->s_dirt = 1;	}	va_start (args, fmt);	vsprintf (error_buf, fmt, args);	va_end (args);	sb->s_flags |= MS_RDONLY;	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n",		kdevname(sb->s_dev), function, error_buf);}void ufs_warning (struct super_block * sb, const char * function,	const char * fmt, ...){	va_list args;	va_start (args, fmt);	vsprintf (error_buf, fmt, args);	va_end (args);	printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n",		kdevname(sb->s_dev), function, error_buf);}static int ufs_parse_options (char * options, unsigned * mount_options){	char * this_char;	char * value;		UFSD(("ENTER\n"))		if (!options)		return 1;			for (this_char = strtok (options, ",");	     this_char != NULL;	     this_char = strtok (NULL, ",")) {	     		if ((value = strchr (this_char, '=')) != NULL)			*value++ = 0;		if (!strcmp (this_char, "ufstype")) {			ufs_clear_opt (*mount_options, UFSTYPE);			if (!strcmp (value, "old"))				ufs_set_opt (*mount_options, UFSTYPE_OLD);			else if (!strcmp (value, "sun"))				ufs_set_opt (*mount_options, UFSTYPE_SUN);			else if (!strcmp (value, "44bsd"))				ufs_set_opt (*mount_options, UFSTYPE_44BSD);			else if (!strcmp (value, "nextstep"))				ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);			else if (!strcmp (value, "nextstep-cd"))				ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);			else if (!strcmp (value, "openstep"))				ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);			else if (!strcmp (value, "sunx86"))				ufs_set_opt (*mount_options, UFSTYPE_SUNx86);			else if (!strcmp (value, "hp"))				ufs_set_opt (*mount_options, UFSTYPE_HP);			else {				printk ("UFS-fs: Invalid type option: %s\n", value);				return 0;			}		}		else if (!strcmp (this_char, "onerror")) {			ufs_clear_opt (*mount_options, ONERROR);			if (!strcmp (value, "panic"))				ufs_set_opt (*mount_options, ONERROR_PANIC);			else if (!strcmp (value, "lock"))				ufs_set_opt (*mount_options, ONERROR_LOCK);			else if (!strcmp (value, "umount"))				ufs_set_opt (*mount_options, ONERROR_UMOUNT);			else if (!strcmp (value, "repair")) {				printk("UFS-fs: Unable to do repair on error, "					"will lock lock instead \n");				ufs_set_opt (*mount_options, ONERROR_REPAIR);			}			else {				printk ("UFS-fs: Invalid action onerror: %s\n", value);				return 0;			}		}		else {			printk("UFS-fs: Invalid option: %s\n", this_char);			return 0;		}	}	return 1;}/* * Read on-disk structures associated with cylinder groups */int ufs_read_cylinder_structures (struct super_block * sb) {	struct ufs_sb_private_info * uspi;	struct ufs_buffer_head * ubh;	unsigned char * base, * space;	unsigned size, blks, i;		UFSD(("ENTER\n"))		uspi = sb->u.ufs_sb.s_uspi;		/*	 * Read cs structures from (usually) first data block	 * on the device. 	 */	size = uspi->s_cssize;	blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;	base = space = kmalloc(size, GFP_KERNEL);	if (!base)		goto failed; 	for (i = 0; i < blks; i += uspi->s_fpb) {		size = uspi->s_bsize;		if (i + uspi->s_fpb > blks)			size = (blks - i) * uspi->s_fsize;		ubh = ubh_bread(sb, uspi->s_csaddr + i, size);		if (!ubh)			goto failed;		ubh_ubhcpymem (space, ubh, size);		sb->u.ufs_sb.s_csp[ufs_fragstoblks(i)] = (struct ufs_csum *)space;		space += size;		ubh_brelse (ubh);		ubh = NULL;	}	/*	 * Read cylinder group (we read only first fragment from block	 * at this time) and prepare internal data structures for cg caching.	 */	if (!(sb->u.ufs_sb.s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_KERNEL)))		goto failed;	for (i = 0; i < uspi->s_ncg; i++) 		sb->u.ufs_sb.s_ucg[i] = NULL;	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {		sb->u.ufs_sb.s_ucpi[i] = NULL;		sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;	}	for (i = 0; i < uspi->s_ncg; i++) {		UFSD(("read cg %u\n", i))		if (!(sb->u.ufs_sb.s_ucg[i] = sb_bread(sb, ufs_cgcmin(i))))			goto failed;		if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data))			goto failed;#ifdef UFS_SUPER_DEBUG_MORE		ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sb->u.ufs_sb.s_ucg[i]->b_data);#endif	}	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {		if (!(sb->u.ufs_sb.s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL)))			goto failed;		sb->u.ufs_sb.s_cgno[i] = UFS_CGNO_EMPTY;	}	sb->u.ufs_sb.s_cg_loaded = 0;	UFSD(("EXIT\n"))	return 1;failed:	if (base) kfree (base);	if (sb->u.ufs_sb.s_ucg) {		for (i = 0; i < uspi->s_ncg; i++)			if (sb->u.ufs_sb.s_ucg[i]) brelse (sb->u.ufs_sb.s_ucg[i]);		kfree (sb->u.ufs_sb.s_ucg);		for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)			if (sb->u.ufs_sb.s_ucpi[i]) kfree (sb->u.ufs_sb.s_ucpi[i]);	}	UFSD(("EXIT (FAILED)\n"))	return 0;}/* * Put on-disk structures associated with cylinder groups and  * write them back to disk */void ufs_put_cylinder_structures (struct super_block * sb) {	struct ufs_sb_private_info * uspi;	struct ufs_buffer_head * ubh;	unsigned char * base, * space;	unsigned blks, size, i;		UFSD(("ENTER\n"))		uspi = sb->u.ufs_sb.s_uspi;	size = uspi->s_cssize;	blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;	base = space = (char*) sb->u.ufs_sb.s_csp[0];	for (i = 0; i < blks; i += uspi->s_fpb) {		size = uspi->s_bsize;		if (i + uspi->s_fpb > blks)			size = (blks - i) * uspi->s_fsize;		ubh = ubh_bread(sb, uspi->s_csaddr + i, size);		ubh_memcpyubh (ubh, space, size);		space += size;		ubh_mark_buffer_uptodate (ubh, 1);		ubh_mark_buffer_dirty (ubh);		ubh_brelse (ubh);	}	for (i = 0; i < sb->u.ufs_sb.s_cg_loaded; i++) {		ufs_put_cylinder (sb, i);		kfree (sb->u.ufs_sb.s_ucpi[i]);	}	for (; i < UFS_MAX_GROUP_LOADED; i++) 		kfree (sb->u.ufs_sb.s_ucpi[i]);	for (i = 0; i < uspi->s_ncg; i++) 		brelse (sb->u.ufs_sb.s_ucg[i]);	kfree (sb->u.ufs_sb.s_ucg);	kfree (base);	UFSD(("EXIT\n"))}struct super_block * ufs_read_super (struct super_block * sb, void * data,	int silent){	struct ufs_sb_private_info * uspi;	struct ufs_super_block_first * usb1;	struct ufs_super_block_second * usb2;	struct ufs_super_block_third * usb3;	struct ufs_buffer_head * ubh;		struct inode *inode;	unsigned block_size, super_block_size;	unsigned flags;	uspi = NULL;	ubh = NULL;	flags = 0;		UFSD(("ENTER\n"))			UFSD(("flag %u\n", (int)(sb->s_flags & MS_RDONLY)))	#ifndef CONFIG_UFS_FS_WRITE	if (!(sb->s_flags & MS_RDONLY)) {		printk("ufs was compiled with read-only support, "		"can't be mounted as read-write\n");		goto failed;	}#endif	/*	 * Set default mount options	 * Parse mount options	 */	sb->u.ufs_sb.s_mount_opt = 0;	ufs_set_opt (sb->u.ufs_sb.s_mount_opt, ONERROR_LOCK);	if (!ufs_parse_options ((char *) data, &sb->u.ufs_sb.s_mount_opt)) {		printk("wrong mount options\n");		goto failed;	}	if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) {		printk("You didn't specify the type of your ufs filesystem\n\n"		"mount -t ufs -o ufstype="		"sun|sunx86|44bsd|old|hp|nextstep|netxstep-cd|openstep ...\n\n"		">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "		"default is ufstype=old\n");		ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD);	}	sb->u.ufs_sb.s_uspi = uspi =		kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL);	if (!uspi)		goto failed;	/* Keep 2Gig file limit. Some UFS variants need to override 	   this but as I don't know which I'll let those in the know loosen	   the rules */	   	switch (sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) {	case UFS_MOUNT_UFSTYPE_44BSD:

⌨️ 快捷键说明

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