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

📄 super.c

📁 UnixBSD、SunOs、FreeBSD、NetBSD、OpenBSD和NeXTStep文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	 * Read cylinder group (we read only first fragment from block	 * at this time) and prepare internal data structures for cg caching.	 */	if (!(sbi->s_ucg = kmalloc (sizeof(struct buffer_head *) * uspi->s_ncg, GFP_KERNEL)))		goto failed;	for (i = 0; i < uspi->s_ncg; i++) 		sbi->s_ucg[i] = NULL;	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {		sbi->s_ucpi[i] = NULL;		sbi->s_cgno[i] = UFS_CGNO_EMPTY;	}	for (i = 0; i < uspi->s_ncg; i++) {		UFSD("read cg %u\n", i);		if (!(sbi->s_ucg[i] = sb_bread(sb, ufs_cgcmin(i))))			goto failed;		if (!ufs_cg_chkmagic (sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data))			goto failed;		ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data);	}	for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) {		if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_KERNEL)))			goto failed;		sbi->s_cgno[i] = UFS_CGNO_EMPTY;	}	sbi->s_cg_loaded = 0;	UFSD("EXIT\n");	return 1;failed:	kfree (base);	if (sbi->s_ucg) {		for (i = 0; i < uspi->s_ncg; i++)			if (sbi->s_ucg[i])				brelse (sbi->s_ucg[i]);		kfree (sbi->s_ucg);		for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)			kfree (sbi->s_ucpi[i]);	}	UFSD("EXIT (FAILED)\n");	return 0;}/* * Sync our internal copy of fs_cstotal with disk */static void ufs_put_cstotal(struct super_block *sb){	unsigned mtype = UFS_SB(sb)->s_mount_opt & UFS_MOUNT_UFSTYPE;	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;	struct ufs_super_block_first *usb1;	struct ufs_super_block_second *usb2;	struct ufs_super_block_third *usb3;	UFSD("ENTER\n");	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*/		usb2->fs_un.fs_u2.cs_ndir =			cpu_to_fs64(sb, uspi->cs_total.cs_ndir);		usb2->fs_un.fs_u2.cs_nbfree =			cpu_to_fs64(sb, uspi->cs_total.cs_nbfree);		usb3->fs_un1.fs_u2.cs_nifree =			cpu_to_fs64(sb, uspi->cs_total.cs_nifree);		usb3->fs_un1.fs_u2.cs_nffree =			cpu_to_fs64(sb, uspi->cs_total.cs_nffree);	} else {		usb1->fs_cstotal.cs_ndir =			cpu_to_fs32(sb, uspi->cs_total.cs_ndir);		usb1->fs_cstotal.cs_nbfree =			cpu_to_fs32(sb, uspi->cs_total.cs_nbfree);		usb1->fs_cstotal.cs_nifree =			cpu_to_fs32(sb, uspi->cs_total.cs_nifree);		usb1->fs_cstotal.cs_nffree =			cpu_to_fs32(sb, uspi->cs_total.cs_nffree);	}	ubh_mark_buffer_dirty(USPI_UBH(uspi));	ufs_print_super_stuff(sb, usb1, usb2, usb3);	UFSD("EXIT\n");}/** * ufs_put_super_internal() - put on-disk intrenal structures * @sb: pointer to super_block structure * Put on-disk structures associated with cylinder groups * and write them back to disk, also update cs_total on disk */static void ufs_put_super_internal(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 blks, size, i;		UFSD("ENTER\n");	ufs_put_cstotal(sb);	size = uspi->s_cssize;	blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift;	base = space = (char*) sbi->s_csp;	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 < sbi->s_cg_loaded; i++) {		ufs_put_cylinder (sb, i);		kfree (sbi->s_ucpi[i]);	}	for (; i < UFS_MAX_GROUP_LOADED; i++) 		kfree (sbi->s_ucpi[i]);	for (i = 0; i < uspi->s_ncg; i++) 		brelse (sbi->s_ucg[i]);	kfree (sbi->s_ucg);	kfree (base);	UFSD("EXIT\n");}static int ufs_fill_super(struct super_block *sb, void *data, int silent){	struct ufs_sb_info * sbi;	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;	unsigned super_block_offset;	int ret = -EINVAL;	uspi = NULL;	ubh = NULL;	flags = 0;		UFSD("ENTER\n");			sbi = kzalloc(sizeof(struct ufs_sb_info), GFP_KERNEL);	if (!sbi)		goto failed_nomem;	sb->s_fs_info = sbi;	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	 */	sbi->s_mount_opt = 0;	ufs_set_opt (sbi->s_mount_opt, ONERROR_LOCK);	if (!ufs_parse_options ((char *) data, &sbi->s_mount_opt)) {		printk("wrong mount options\n");		goto failed;	}	if (!(sbi->s_mount_opt & UFS_MOUNT_UFSTYPE)) {		if (!silent)			printk("You didn't specify the type of your ufs filesystem\n\n"			"mount -t ufs -o ufstype="			"sun|sunx86|44bsd|ufs2|5xbsd|old|hp|nextstep|nextstep-cd|openstep ...\n\n"			">>>WARNING<<< Wrong ufstype may corrupt your filesystem, "			"default is ufstype=old\n");		ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);	}	uspi = kzalloc(sizeof(struct ufs_sb_private_info), GFP_KERNEL);	sbi->s_uspi = uspi;	if (!uspi)		goto failed;	uspi->s_dirblksize = UFS_SECTOR_SIZE;	super_block_offset=UFS_SBLOCK;	/* 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 (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {	case UFS_MOUNT_UFSTYPE_44BSD:		UFSD("ufstype=44bsd\n");		uspi->s_fsize = block_size = 512;		uspi->s_fmask = ~(512 - 1);		uspi->s_fshift = 9;		uspi->s_sbsize = super_block_size = 1536;		uspi->s_sbbase = 0;		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;		break;	case UFS_MOUNT_UFSTYPE_UFS2:		UFSD("ufstype=ufs2\n");		super_block_offset=SBLOCK_UFS2;		uspi->s_fsize = block_size = 512;		uspi->s_fmask = ~(512 - 1);		uspi->s_fshift = 9;		uspi->s_sbsize = super_block_size = 1536;		uspi->s_sbbase =  0;		flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;		break;			case UFS_MOUNT_UFSTYPE_SUN:		UFSD("ufstype=sun\n");		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		uspi->s_maxsymlinklen = 0; /* Not supported on disk */		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;		break;	case UFS_MOUNT_UFSTYPE_SUNOS:		UFSD(("ufstype=sunos\n"))		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = 2048;		super_block_size = 2048;		uspi->s_sbbase = 0;		uspi->s_maxsymlinklen = 0; /* Not supported on disk */		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_SUNOS | UFS_CG_SUN;		break;	case UFS_MOUNT_UFSTYPE_SUNx86:		UFSD("ufstype=sunx86\n");		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		uspi->s_maxsymlinklen = 0; /* Not supported on disk */		flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;		break;	case UFS_MOUNT_UFSTYPE_OLD:		UFSD("ufstype=old\n");		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;		if (!(sb->s_flags & MS_RDONLY)) {			if (!silent)				printk(KERN_INFO "ufstype=old is supported read-only\n");			sb->s_flags |= MS_RDONLY;		}		break;		case UFS_MOUNT_UFSTYPE_NEXTSTEP:		UFSD("ufstype=nextstep\n");		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		uspi->s_dirblksize = 1024;		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;		if (!(sb->s_flags & MS_RDONLY)) {			if (!silent)				printk(KERN_INFO "ufstype=nextstep is supported read-only\n");			sb->s_flags |= MS_RDONLY;		}		break;		case UFS_MOUNT_UFSTYPE_NEXTSTEP_CD:		UFSD("ufstype=nextstep-cd\n");		uspi->s_fsize = block_size = 2048;		uspi->s_fmask = ~(2048 - 1);		uspi->s_fshift = 11;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		uspi->s_dirblksize = 1024;		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;		if (!(sb->s_flags & MS_RDONLY)) {			if (!silent)				printk(KERN_INFO "ufstype=nextstep-cd is supported read-only\n");			sb->s_flags |= MS_RDONLY;		}		break;		case UFS_MOUNT_UFSTYPE_OPENSTEP:		UFSD("ufstype=openstep\n");		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		uspi->s_dirblksize = 1024;		flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;		if (!(sb->s_flags & MS_RDONLY)) {			if (!silent)				printk(KERN_INFO "ufstype=openstep is supported read-only\n");			sb->s_flags |= MS_RDONLY;		}		break;		case UFS_MOUNT_UFSTYPE_HP:		UFSD("ufstype=hp\n");		uspi->s_fsize = block_size = 1024;		uspi->s_fmask = ~(1024 - 1);		uspi->s_fshift = 10;		uspi->s_sbsize = super_block_size = 2048;		uspi->s_sbbase = 0;		flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;		if (!(sb->s_flags & MS_RDONLY)) {			if (!silent)				printk(KERN_INFO "ufstype=hp is supported read-only\n");			sb->s_flags |= MS_RDONLY; 		} 		break;	default:		if (!silent)			printk("unknown ufstype\n");		goto failed;	}	again:		if (!sb_set_blocksize(sb, block_size)) {		printk(KERN_ERR "UFS: failed to set blocksize\n");		goto failed;	}	/*	 * read ufs super block from device	 */	ubh = ubh_bread_uspi(uspi, sb, uspi->s_sbbase + super_block_offset/block_size, super_block_size);		if (!ubh)             goto failed;	usb1 = ubh_get_usb_first(uspi);	usb2 = ubh_get_usb_second(uspi);	usb3 = ubh_get_usb_third(uspi);	/* Sort out mod used on SunOS 4.1.3 for fs_state */	uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);	if (((flags & UFS_ST_MASK) == UFS_ST_SUNOS) &&	    (uspi->s_postblformat != UFS_42POSTBLFMT)) {		flags &= ~UFS_ST_MASK;		flags |=  UFS_ST_SUN;	}	/*	 * Check ufs magic number	 */	sbi->s_bytesex = BYTESEX_LE;	switch ((uspi->fs_magic = fs32_to_cpu(sb, usb3->fs_magic))) {		case UFS_MAGIC:		case UFS2_MAGIC:		case UFS_MAGIC_LFN:	        case UFS_MAGIC_FEA:	        case UFS_MAGIC_4GB:			goto magic_found;	}	sbi->s_bytesex = BYTESEX_BE;	switch ((uspi->fs_magic = fs32_to_cpu(sb, usb3->fs_magic))) {		case UFS_MAGIC:		case UFS2_MAGIC:		case UFS_MAGIC_LFN:	        case UFS_MAGIC_FEA:	        case UFS_MAGIC_4GB:			goto magic_found;	}	if ((((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP) 	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_NEXTSTEP_CD) 	  || ((sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) == UFS_MOUNT_UFSTYPE_OPENSTEP)) 	  && uspi->s_sbbase < 256) {		ubh_brelse_uspi(uspi);		ubh = NULL;		uspi->s_sbbase += 8;		goto again;	}	if (!silent)		printk("ufs_read_super: bad magic number\n");	goto failed;magic_found:	/*	 * Check block and fragment sizes	 */	uspi->s_bsize = fs32_to_cpu(sb, usb1->fs_bsize);	uspi->s_fsize = fs32_to_cpu(sb, usb1->fs_fsize);	uspi->s_sbsize = fs32_to_cpu(sb, usb1->fs_sbsize);	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);	if (!is_power_of_2(uspi->s_fsize)) {		printk(KERN_ERR "ufs_read_super: fragment size %u is not a power of 2\n",			uspi->s_fsize);			goto failed;	}	if (uspi->s_fsize < 512) {		printk(KERN_ERR "ufs_read_super: fragment size %u is too small\n",			uspi->s_fsize);		goto failed;	}	if (uspi->s_fsize > 4096) {		printk(KERN_ERR "ufs_read_super: fragment size %u is too large\n",			uspi->s_fsize);		goto failed;	}	if (!is_power_of_2(uspi->s_bsize)) {		printk(KERN_ERR "ufs_read_super: block size %u is not a power of 2\n",			uspi->s_bsize);		goto failed;	}	if (uspi->s_bsize < 4096) {		printk(KERN_ERR "ufs_read_super: block size %u is too small\n",			uspi->s_bsize);		goto failed;	}	if (uspi->s_bsize / uspi->s_fsize > 8) {		printk(KERN_ERR "ufs_read_super: too many fragments per block (%u)\n",			uspi->s_bsize / uspi->s_fsize);		goto failed;	}	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {		ubh_brelse_uspi(uspi);		ubh = NULL;		block_size = uspi->s_fsize;		super_block_size = uspi->s_sbsize;		UFSD("another value of block_size or super_block_size %u, %u\n", block_size, super_block_size);		goto again;	}	sbi->s_flags = flags;/*after that line some functions use s_flags*/	ufs_print_super_stuff(sb, usb1, usb2, usb3);	/*	 * Check, if file system was correctly unmounted.	 * If not, make it read only.	 */	if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||	  ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||	  (((flags & UFS_ST_MASK) == UFS_ST_SUN ||	    (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||	  (flags & UFS_ST_MASK) == UFS_ST_SUNx86) &&	  (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {		switch(usb1->fs_clean) {		case UFS_FSCLEAN:			UFSD("fs is clean\n");			break;		case UFS_FSSTABLE:			UFSD("fs is stable\n");			break;		case UFS_FSOSF1:			UFSD("fs is DEC OSF/1\n");			break;		case UFS_FSACTIVE:			printk("ufs_read_super: fs is active\n");			sb->s_flags |= MS_RDONLY;			break;		case UFS_FSBAD:			printk("ufs_read_super: fs is bad\n");			sb->s_flags |= MS_RDONLY;			break;		default:			printk("ufs_read_super: can't grok fs_clean 0x%x\n", usb1->fs_clean);			sb->s_flags |= MS_RDONLY;			break;		}	} else {		printk("ufs_read_super: fs needs fsck\n");		sb->s_flags |= MS_RDONLY;	}	/*	 * Read ufs_super_block into internal data structures	 */	sb->s_op = &ufs_super_ops;	sb->dq_op = NULL; /***/	sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);	uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);

⌨️ 快捷键说明

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