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

📄 super.c

📁 UnixBSD、SunOs、FreeBSD、NetBSD、OpenBSD和NeXTStep文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  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 <gwingerde@gmail.com> * * 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 * * UFS2 (of FreeBSD 5.x) support added by * Niraj Kumar <niraj17@iitbombay.org>, Jan 2004 * * UFS2 write support added by * Evgeniy Dushistov <dushistov@mail.ru>, 2007 */#include <linux/module.h>#include <linux/bitops.h>#include <stdarg.h>#include <asm/uaccess.h>#include <asm/system.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/quotaops.h>#include <linux/slab.h>#include <linux/time.h>#include <linux/stat.h>#include <linux/string.h>#include <linux/blkdev.h>#include <linux/init.h>#include <linux/parser.h>#include <linux/smp_lock.h>#include <linux/buffer_head.h>#include <linux/vfs.h>#include <linux/log2.h>#include <linux/mount.h>#include <linux/seq_file.h>#include "ufs_fs.h"#include "ufs.h"#include "swab.h"#include "util.h"#ifdef CONFIG_UFS_DEBUG/* * Print contents of ufs_super_block, useful for debugging */static 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){	u32 magic = fs32_to_cpu(sb, usb3->fs_magic);	printk("ufs_print_super_stuff\n");	printk("  magic:     0x%x\n", magic);	if (fs32_to_cpu(sb, usb3->fs_magic) == UFS2_MAGIC) {		printk("  fs_size:   %llu\n", (unsigned long long)		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_size));		printk("  fs_dsize:  %llu\n", (unsigned long long)		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.fs_dsize));		printk("  bsize:         %u\n",		       fs32_to_cpu(sb, usb1->fs_bsize));		printk("  fsize:         %u\n",		       fs32_to_cpu(sb, usb1->fs_fsize));		printk("  fs_volname:  %s\n", usb2->fs_un.fs_u2.fs_volname);		printk("  fs_sblockloc: %llu\n", (unsigned long long)		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.fs_sblockloc));		printk("  cs_ndir(No of dirs):  %llu\n", (unsigned long long)		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir));		printk("  cs_nbfree(No of free blocks):  %llu\n",		       (unsigned long long)		       fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree));		printk(KERN_INFO"  cs_nifree(Num of free inodes): %llu\n",		       (unsigned long long)		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree));		printk(KERN_INFO"  cs_nffree(Num of free frags): %llu\n",		       (unsigned long long)		       fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree));		printk(KERN_INFO"  fs_maxsymlinklen: %u\n",		       fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen));	} else {		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(" 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 */static void ufs_print_cylinder_stuff(struct super_block *sb,				     struct ufs_cylinder_group *cg){	printk("\nufs_print_cylinder_stuff\n");	printk("size of ucg: %zu\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");}#else#  define ufs_print_super_stuff(sb, usb1, usb2, usb3) /**/#  define ufs_print_cylinder_stuff(sb, cg) /**/#endif /* CONFIG_UFS_DEBUG */static const 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 = UFS_SB(sb)->s_uspi;	usb1 = ubh_get_usb_first(uspi);		if (!(sb->s_flags & MS_RDONLY)) {		usb1->fs_clean = UFS_FSBAD;		ubh_mark_buffer_dirty(USPI_UBH(uspi));		sb->s_dirt = 1;		sb->s_flags |= MS_RDONLY;	}	va_start (args, fmt);	vsnprintf (error_buf, sizeof(error_buf), fmt, args);	va_end (args);	switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) {	case UFS_MOUNT_ONERROR_PANIC:		panic ("UFS-fs panic (device %s): %s: %s\n", 			sb->s_id, 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",			sb->s_id, 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 = UFS_SB(sb)->s_uspi;	usb1 = ubh_get_usb_first(uspi);		if (!(sb->s_flags & MS_RDONLY)) {		usb1->fs_clean = UFS_FSBAD;		ubh_mark_buffer_dirty(USPI_UBH(uspi));		sb->s_dirt = 1;	}	va_start (args, fmt);	vsnprintf (error_buf, sizeof(error_buf), fmt, args);	va_end (args);	sb->s_flags |= MS_RDONLY;	printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n",		sb->s_id, function, error_buf);}void ufs_warning (struct super_block * sb, const char * function,	const char * fmt, ...){	va_list args;	va_start (args, fmt);	vsnprintf (error_buf, sizeof(error_buf), fmt, args);	va_end (args);	printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n",		sb->s_id, function, error_buf);}enum {       Opt_type_old = UFS_MOUNT_UFSTYPE_OLD,       Opt_type_sunx86 = UFS_MOUNT_UFSTYPE_SUNx86,       Opt_type_sun = UFS_MOUNT_UFSTYPE_SUN,       Opt_type_sunos = UFS_MOUNT_UFSTYPE_SUNOS,       Opt_type_44bsd = UFS_MOUNT_UFSTYPE_44BSD,       Opt_type_ufs2 = UFS_MOUNT_UFSTYPE_UFS2,       Opt_type_hp = UFS_MOUNT_UFSTYPE_HP,       Opt_type_nextstepcd = UFS_MOUNT_UFSTYPE_NEXTSTEP_CD,       Opt_type_nextstep = UFS_MOUNT_UFSTYPE_NEXTSTEP,       Opt_type_openstep = UFS_MOUNT_UFSTYPE_OPENSTEP,       Opt_onerror_panic = UFS_MOUNT_ONERROR_PANIC,       Opt_onerror_lock = UFS_MOUNT_ONERROR_LOCK,       Opt_onerror_umount = UFS_MOUNT_ONERROR_UMOUNT,       Opt_onerror_repair = UFS_MOUNT_ONERROR_REPAIR,       Opt_err};static const match_table_t tokens = {	{Opt_type_old, "ufstype=old"},	{Opt_type_sunx86, "ufstype=sunx86"},	{Opt_type_sun, "ufstype=sun"},	{Opt_type_sunos, "ufstype=sunos"},	{Opt_type_44bsd, "ufstype=44bsd"},	{Opt_type_ufs2, "ufstype=ufs2"},	{Opt_type_ufs2, "ufstype=5xbsd"},	{Opt_type_hp, "ufstype=hp"},	{Opt_type_nextstepcd, "ufstype=nextstep-cd"},	{Opt_type_nextstep, "ufstype=nextstep"},	{Opt_type_openstep, "ufstype=openstep"},/*end of possible ufs types */	{Opt_onerror_panic, "onerror=panic"},	{Opt_onerror_lock, "onerror=lock"},	{Opt_onerror_umount, "onerror=umount"},	{Opt_onerror_repair, "onerror=repair"},	{Opt_err, NULL}};static int ufs_parse_options (char * options, unsigned * mount_options){	char * p;		UFSD("ENTER\n");		if (!options)		return 1;	while ((p = strsep(&options, ",")) != NULL) {		substring_t args[MAX_OPT_ARGS];		int token;		if (!*p)			continue;		token = match_token(p, tokens, args);		switch (token) {		case Opt_type_old:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_OLD);			break;		case Opt_type_sunx86:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_SUNx86);			break;		case Opt_type_sun:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_SUN);			break;		case Opt_type_sunos:			ufs_clear_opt(*mount_options, UFSTYPE);			ufs_set_opt(*mount_options, UFSTYPE_SUNOS);			break;		case Opt_type_44bsd:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_44BSD);			break;		case Opt_type_ufs2:			ufs_clear_opt(*mount_options, UFSTYPE);			ufs_set_opt(*mount_options, UFSTYPE_UFS2);			break;		case Opt_type_hp:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_HP);			break;		case Opt_type_nextstepcd:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);			break;		case Opt_type_nextstep:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);			break;		case Opt_type_openstep:			ufs_clear_opt (*mount_options, UFSTYPE);			ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);			break;		case Opt_onerror_panic:			ufs_clear_opt (*mount_options, ONERROR);			ufs_set_opt (*mount_options, ONERROR_PANIC);			break;		case Opt_onerror_lock:			ufs_clear_opt (*mount_options, ONERROR);			ufs_set_opt (*mount_options, ONERROR_LOCK);			break;		case Opt_onerror_umount:			ufs_clear_opt (*mount_options, ONERROR);			ufs_set_opt (*mount_options, ONERROR_UMOUNT);			break;		case Opt_onerror_repair:			printk("UFS-fs: Unable to do repair on error, "				"will lock lock instead\n");			ufs_clear_opt (*mount_options, ONERROR);			ufs_set_opt (*mount_options, ONERROR_REPAIR);			break;		default:			printk("UFS-fs: Invalid option: \"%s\" "					"or missing value\n", p);			return 0;		}	}	return 1;}/* * Diffrent types of UFS hold fs_cstotal in different * places, and use diffrent data structure for it. * To make things simplier we just copy fs_cstotal to ufs_sb_private_info */static void ufs_setup_cstotal(struct super_block *sb){	struct ufs_sb_info *sbi = UFS_SB(sb);	struct ufs_sb_private_info *uspi = sbi->s_uspi;	struct ufs_super_block_first *usb1;	struct ufs_super_block_second *usb2;	struct ufs_super_block_third *usb3;	unsigned mtype = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;	UFSD("ENTER, mtype=%u\n", mtype);	usb1 = ubh_get_usb_first(uspi);	usb2 = ubh_get_usb_second(uspi);	usb3 = ubh_get_usb_third(uspi);	if ((mtype == UFS_MOUNT_UFSTYPE_44BSD &&	     (usb1->fs_flags & UFS_FLAGS_UPDATED)) ||	    mtype == UFS_MOUNT_UFSTYPE_UFS2) {		/*we have statistic in different place, then usual*/		uspi->cs_total.cs_ndir = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_ndir);		uspi->cs_total.cs_nbfree = fs64_to_cpu(sb, usb2->fs_un.fs_u2.cs_nbfree);		uspi->cs_total.cs_nifree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nifree);		uspi->cs_total.cs_nffree = fs64_to_cpu(sb, usb3->fs_un1.fs_u2.cs_nffree);	} else {		uspi->cs_total.cs_ndir = fs32_to_cpu(sb, usb1->fs_cstotal.cs_ndir);		uspi->cs_total.cs_nbfree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nbfree);		uspi->cs_total.cs_nifree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nifree);		uspi->cs_total.cs_nffree = fs32_to_cpu(sb, usb1->fs_cstotal.cs_nffree);	}	UFSD("EXIT\n");}/* * Read on-disk structures associated with cylinder groups */static int ufs_read_cylinder_structures(struct super_block *sb){	struct ufs_sb_info *sbi = UFS_SB(sb);	struct ufs_sb_private_info *uspi = sbi->s_uspi;	struct ufs_buffer_head * ubh;	unsigned char * base, * space;	unsigned size, blks, i;	struct ufs_super_block_third *usb3;	UFSD("ENTER\n");	usb3 = ubh_get_usb_third(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; 	sbi->s_csp = (struct ufs_csum *)space;	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);		space += size;		ubh_brelse (ubh);		ubh = NULL;	}	/*

⌨️ 快捷键说明

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