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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		case Opt_err_panic:			clear_opt (sbi->s_mount_opt, ERRORS_CONT);			clear_opt (sbi->s_mount_opt, ERRORS_RO);			set_opt (sbi->s_mount_opt, ERRORS_PANIC);			break;		case Opt_err_ro:			clear_opt (sbi->s_mount_opt, ERRORS_CONT);			clear_opt (sbi->s_mount_opt, ERRORS_PANIC);			set_opt (sbi->s_mount_opt, ERRORS_RO);			break;		case Opt_err_cont:			clear_opt (sbi->s_mount_opt, ERRORS_RO);			clear_opt (sbi->s_mount_opt, ERRORS_PANIC);			set_opt (sbi->s_mount_opt, ERRORS_CONT);			break;		case Opt_nouid32:			set_opt (sbi->s_mount_opt, NO_UID32);			break;		case Opt_nocheck:			clear_opt (sbi->s_mount_opt, CHECK);			break;		case Opt_debug:			set_opt (sbi->s_mount_opt, DEBUG);			break;		case Opt_oldalloc:			set_opt (sbi->s_mount_opt, OLDALLOC);			break;		case Opt_orlov:			clear_opt (sbi->s_mount_opt, OLDALLOC);			break;		case Opt_nobh:			set_opt (sbi->s_mount_opt, NOBH);			break;#ifdef CONFIG_EXT2_FS_XATTR		case Opt_user_xattr:			set_opt (sbi->s_mount_opt, XATTR_USER);			break;		case Opt_nouser_xattr:			clear_opt (sbi->s_mount_opt, XATTR_USER);			break;#else		case Opt_user_xattr:		case Opt_nouser_xattr:			printk("EXT2 (no)user_xattr options not supported\n");			break;#endif#ifdef CONFIG_EXT2_FS_POSIX_ACL		case Opt_acl:			set_opt(sbi->s_mount_opt, POSIX_ACL);			break;		case Opt_noacl:			clear_opt(sbi->s_mount_opt, POSIX_ACL);			break;#else		case Opt_acl:		case Opt_noacl:			printk("EXT2 (no)acl options not supported\n");			break;#endif		case Opt_xip:#ifdef CONFIG_EXT2_FS_XIP			set_opt (sbi->s_mount_opt, XIP);#else			printk("EXT2 xip option not supported\n");#endif			break;#if defined(CONFIG_QUOTA)		case Opt_quota:		case Opt_usrquota:			set_opt(sbi->s_mount_opt, USRQUOTA);			break;		case Opt_grpquota:			set_opt(sbi->s_mount_opt, GRPQUOTA);			break;#else		case Opt_quota:		case Opt_usrquota:		case Opt_grpquota:			printk(KERN_ERR				"EXT2-fs: quota operations not supported.\n");			break;#endif		case Opt_reservation:			set_opt(sbi->s_mount_opt, RESERVATION);			printk("reservations ON\n");			break;		case Opt_noreservation:			clear_opt(sbi->s_mount_opt, RESERVATION);			printk("reservations OFF\n");			break;		case Opt_ignore:			break;		default:			return 0;		}	}	return 1;}static int ext2_setup_super (struct super_block * sb,			      struct ext2_super_block * es,			      int read_only){	int res = 0;	struct ext2_sb_info *sbi = EXT2_SB(sb);	if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) {		printk ("EXT2-fs warning: revision level too high, "			"forcing read-only mode\n");		res = MS_RDONLY;	}	if (read_only)		return res;	if (!(sbi->s_mount_state & EXT2_VALID_FS))		printk ("EXT2-fs warning: mounting unchecked fs, "			"running e2fsck is recommended\n");	else if ((sbi->s_mount_state & EXT2_ERROR_FS))		printk ("EXT2-fs warning: mounting fs with errors, "			"running e2fsck is recommended\n");	else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&		 le16_to_cpu(es->s_mnt_count) >=		 (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))		printk ("EXT2-fs warning: maximal mount count reached, "			"running e2fsck is recommended\n");	else if (le32_to_cpu(es->s_checkinterval) &&		(le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= get_seconds()))		printk ("EXT2-fs warning: checktime reached, "			"running e2fsck is recommended\n");	if (!le16_to_cpu(es->s_max_mnt_count))		es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);	es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);	ext2_write_super(sb);	if (test_opt (sb, DEBUG))		printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "			"bpg=%lu, ipg=%lu, mo=%04lx]\n",			EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,			sbi->s_frag_size,			sbi->s_groups_count,			EXT2_BLOCKS_PER_GROUP(sb),			EXT2_INODES_PER_GROUP(sb),			sbi->s_mount_opt);	return res;}static int ext2_check_descriptors (struct super_block * sb){	int i;	int desc_block = 0;	struct ext2_sb_info *sbi = EXT2_SB(sb);	unsigned long first_block = le32_to_cpu(sbi->s_es->s_first_data_block);	unsigned long last_block;	struct ext2_group_desc * gdp = NULL;	ext2_debug ("Checking group descriptors");	for (i = 0; i < sbi->s_groups_count; i++)	{		if (i == sbi->s_groups_count - 1)			last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1;		else			last_block = first_block +				(EXT2_BLOCKS_PER_GROUP(sb) - 1);		if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0)			gdp = (struct ext2_group_desc *) sbi->s_group_desc[desc_block++]->b_data;		if (le32_to_cpu(gdp->bg_block_bitmap) < first_block ||		    le32_to_cpu(gdp->bg_block_bitmap) > last_block)		{			ext2_error (sb, "ext2_check_descriptors",				    "Block bitmap for group %d"				    " not in group (block %lu)!",				    i, (unsigned long) le32_to_cpu(gdp->bg_block_bitmap));			return 0;		}		if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block ||		    le32_to_cpu(gdp->bg_inode_bitmap) > last_block)		{			ext2_error (sb, "ext2_check_descriptors",				    "Inode bitmap for group %d"				    " not in group (block %lu)!",				    i, (unsigned long) le32_to_cpu(gdp->bg_inode_bitmap));			return 0;		}		if (le32_to_cpu(gdp->bg_inode_table) < first_block ||		    le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group - 1 >		    last_block)		{			ext2_error (sb, "ext2_check_descriptors",				    "Inode table for group %d"				    " not in group (block %lu)!",				    i, (unsigned long) le32_to_cpu(gdp->bg_inode_table));			return 0;		}		first_block += EXT2_BLOCKS_PER_GROUP(sb);		gdp++;	}	return 1;}/* * Maximal file size.  There is a direct, and {,double-,triple-}indirect * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. * We need to be 1 filesystem block less than the 2^32 sector limit. */static loff_t ext2_max_size(int bits){	loff_t res = EXT2_NDIR_BLOCKS;	/* This constant is calculated to be the largest file size for a	 * dense, 4k-blocksize file such that the total number of	 * sectors in the file, including data and all indirect blocks,	 * does not exceed 2^32. */	const loff_t upper_limit = 0x1ff7fffd000LL;	res += 1LL << (bits-2);	res += 1LL << (2*(bits-2));	res += 1LL << (3*(bits-2));	res <<= bits;	if (res > upper_limit)		res = upper_limit;	return res;}static unsigned long descriptor_loc(struct super_block *sb,				    unsigned long logic_sb_block,				    int nr){	struct ext2_sb_info *sbi = EXT2_SB(sb);	unsigned long bg, first_data_block, first_meta_bg;	int has_super = 0;		first_data_block = le32_to_cpu(sbi->s_es->s_first_data_block);	first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);	if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_META_BG) ||	    nr < first_meta_bg)		return (logic_sb_block + nr + 1);	bg = sbi->s_desc_per_block * nr;	if (ext2_bg_has_super(sb, bg))		has_super = 1;	return (first_data_block + has_super + (bg * sbi->s_blocks_per_group));}static int ext2_fill_super(struct super_block *sb, void *data, int silent){	struct buffer_head * bh;	struct ext2_sb_info * sbi;	struct ext2_super_block * es;	struct inode *root;	unsigned long block;	unsigned long sb_block = get_sb_block(&data);	unsigned long logic_sb_block;	unsigned long offset = 0;	unsigned long def_mount_opts;	int blocksize = BLOCK_SIZE;	int db_count;	int i, j;	__le32 features;	int err;	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);	if (!sbi)		return -ENOMEM;	sb->s_fs_info = sbi;	sbi->s_sb_block = sb_block;	/*	 * See what the current blocksize for the device is, and	 * use that as the blocksize.  Otherwise (or if the blocksize	 * is smaller than the default) use the default.	 * This is important for devices that have a hardware	 * sectorsize that is larger than the default.	 */	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);	if (!blocksize) {		printk ("EXT2-fs: unable to set blocksize\n");		goto failed_sbi;	}	/*	 * If the superblock doesn't start on a hardware sector boundary,	 * calculate the offset.  	 */	if (blocksize != BLOCK_SIZE) {		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;		offset = (sb_block*BLOCK_SIZE) % blocksize;	} else {		logic_sb_block = sb_block;	}	if (!(bh = sb_bread(sb, logic_sb_block))) {		printk ("EXT2-fs: unable to read superblock\n");		goto failed_sbi;	}	/*	 * Note: s_es must be initialized as soon as possible because	 *       some ext2 macro-instructions depend on its value	 */	es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);	sbi->s_es = es;	sb->s_magic = le16_to_cpu(es->s_magic);	if (sb->s_magic != EXT2_SUPER_MAGIC)		goto cantfind_ext2;	/* Set defaults before we parse the mount options */	def_mount_opts = le32_to_cpu(es->s_default_mount_opts);	if (def_mount_opts & EXT2_DEFM_DEBUG)		set_opt(sbi->s_mount_opt, DEBUG);	if (def_mount_opts & EXT2_DEFM_BSDGROUPS)		set_opt(sbi->s_mount_opt, GRPID);	if (def_mount_opts & EXT2_DEFM_UID16)		set_opt(sbi->s_mount_opt, NO_UID32);#ifdef CONFIG_EXT2_FS_XATTR	if (def_mount_opts & EXT2_DEFM_XATTR_USER)		set_opt(sbi->s_mount_opt, XATTR_USER);#endif#ifdef CONFIG_EXT2_FS_POSIX_ACL	if (def_mount_opts & EXT2_DEFM_ACL)		set_opt(sbi->s_mount_opt, POSIX_ACL);#endif		if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)		set_opt(sbi->s_mount_opt, ERRORS_PANIC);	else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO)		set_opt(sbi->s_mount_opt, ERRORS_RO);	else		set_opt(sbi->s_mount_opt, ERRORS_CONT);	sbi->s_resuid = le16_to_cpu(es->s_def_resuid);	sbi->s_resgid = le16_to_cpu(es->s_def_resgid);		set_opt(sbi->s_mount_opt, RESERVATION);	if (!parse_options ((char *) data, sbi))		goto failed_mount;	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |		((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?		 MS_POSIXACL : 0);	ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset				    EXT2_MOUNT_XIP if not */	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&	    (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||	     EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||	     EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U)))		printk("EXT2-fs warning: feature flags set on rev 0 fs, "		       "running e2fsck is recommended\n");	/*	 * Check feature flags regardless of the revision level, since we	 * previously didn't change the revision level when setting the flags,	 * so there is a chance incompat flags are set on a rev 0 filesystem.	 */	features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP);	if (features) {		printk("EXT2-fs: %s: couldn't mount because of "		       "unsupported optional features (%x).\n",		       sb->s_id, le32_to_cpu(features));		goto failed_mount;	}	if (!(sb->s_flags & MS_RDONLY) &&	    (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){		printk("EXT2-fs: %s: couldn't mount RDWR because of "		       "unsupported optional features (%x).\n",		       sb->s_id, le32_to_cpu(features));		goto failed_mount;	}	blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);	if ((ext2_use_xip(sb)) && ((blocksize != PAGE_SIZE) ||				  (sb->s_blocksize != blocksize))) {		if (!silent)			printk("XIP: Unsupported blocksize\n");		goto failed_mount;	}	/* If the blocksize doesn't match, re-read the thing.. */	if (sb->s_blocksize != blocksize) {		brelse(bh);		if (!sb_set_blocksize(sb, blocksize)) {			printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");			goto failed_sbi;		}		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;		offset = (sb_block*BLOCK_SIZE) % blocksize;		bh = sb_bread(sb, logic_sb_block);		if(!bh) {			printk("EXT2-fs: Couldn't read superblock on "			       "2nd try.\n");			goto failed_sbi;		}		es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);		sbi->s_es = es;		if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) {			printk ("EXT2-fs: Magic mismatch, very weird !\n");			goto failed_mount;		}	}	sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {		sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;		sbi->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;	} else {		sbi->s_inode_size = le16_to_cpu(es->s_inode_size);		sbi->s_first_ino = le32_to_cpu(es->s_first_ino);		if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) ||		    !is_power_of_2(sbi->s_inode_size) ||		    (sbi->s_inode_size > blocksize)) {			printk ("EXT2-fs: unsupported inode size: %d\n",				sbi->s_inode_size);			goto failed_mount;		}	}	sbi->s_frag_size = EXT2_MIN_FRAG_SIZE <<				   le32_to_cpu(es->s_log_frag_size);	if (sbi->s_frag_size == 0)		goto cantfind_ext2;	sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size;	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);	sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);	if (EXT2_INODE_SIZE(sb) == 0)		goto cantfind_ext2;	sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb);	if (sbi->s_inodes_per_block == 0 || sbi->s_inodes_per_group == 0)		goto cantfind_ext2;	sbi->s_itb_per_group = sbi->s_inodes_per_group /					sbi->s_inodes_per_block;	sbi->s_desc_per_block = sb->s_blocksize /					sizeof (struct ext2_group_desc);	sbi->s_sbh = bh;	sbi->s_mount_state = le16_to_cpu(es->s_state);	sbi->s_addr_per_block_bits =		ilog2 (EXT2_ADDR_PER_BLOCK(sb));	sbi->s_desc_per_block_bits =		ilog2 (EXT2_DESC_PER_BLOCK(sb));	if (sb->s_magic != EXT2_SUPER_MAGIC)		goto cantfind_ext2;	if (sb->s_blocksize != bh->b_size) {		if (!silent)			printk ("VFS: Unsupported blocksize on dev "				"%s.\n", sb->s_id);		goto failed_mount;	}	if (sb->s_blocksize != sbi->s_frag_size) {		printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n",			sbi->s_frag_size, sb->s_blocksize);		goto failed_mount;	}	if (sbi->s_blocks_per_group > sb->s_blocksize * 8) {		printk ("EXT2-fs: #blocks per group too big: %lu\n",			sbi->s_blocks_per_group);		goto failed_mount;	}

⌨️ 快捷键说明

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