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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int qtype;	char *qname;#endif	if (!options)		return 1;	while ((p = strsep (&options, ",")) != NULL) {		int token;		if (!*p)			continue;		token = match_token(p, tokens, args);		switch (token) {		case Opt_bsd_df:			clear_opt (sbi->s_mount_opt, MINIX_DF);			break;		case Opt_minix_df:			set_opt (sbi->s_mount_opt, MINIX_DF);			break;		case Opt_grpid:			set_opt (sbi->s_mount_opt, GRPID);			break;		case Opt_nogrpid:			clear_opt (sbi->s_mount_opt, GRPID);			break;		case Opt_resuid:			if (match_int(&args[0], &option))				return 0;			sbi->s_resuid = option;			break;		case Opt_resgid:			if (match_int(&args[0], &option))				return 0;			sbi->s_resgid = option;			break;		case Opt_sb:			/* handled by get_sb_block() instead of here */			/* *sb_block = match_int(&args[0]); */			break;		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;#ifdef CONFIG_EXT4DEV_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("EXT4 (no)user_xattr options not supported\n");			break;#endif#ifdef CONFIG_EXT4DEV_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("EXT4 (no)acl options not supported\n");			break;#endif		case Opt_reservation:			set_opt(sbi->s_mount_opt, RESERVATION);			break;		case Opt_noreservation:			clear_opt(sbi->s_mount_opt, RESERVATION);			break;		case Opt_journal_update:			/* @@@ FIXME */			/* Eventually we will want to be able to create			   a journal file here.  For now, only allow the			   user to specify an existing inode to be the			   journal file. */			if (is_remount) {				printk(KERN_ERR "EXT4-fs: cannot specify "				       "journal on remount\n");				return 0;			}			set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);			break;		case Opt_journal_inum:			if (is_remount) {				printk(KERN_ERR "EXT4-fs: cannot specify "				       "journal on remount\n");				return 0;			}			if (match_int(&args[0], &option))				return 0;			*inum = option;			break;		case Opt_journal_dev:			if (is_remount) {				printk(KERN_ERR "EXT4-fs: cannot specify "				       "journal on remount\n");				return 0;			}			if (match_int(&args[0], &option))				return 0;			*journal_devnum = option;			break;		case Opt_noload:			set_opt (sbi->s_mount_opt, NOLOAD);			break;		case Opt_commit:			if (match_int(&args[0], &option))				return 0;			if (option < 0)				return 0;			if (option == 0)				option = JBD2_DEFAULT_MAX_COMMIT_AGE;			sbi->s_commit_interval = HZ * option;			break;		case Opt_data_journal:			data_opt = EXT4_MOUNT_JOURNAL_DATA;			goto datacheck;		case Opt_data_ordered:			data_opt = EXT4_MOUNT_ORDERED_DATA;			goto datacheck;		case Opt_data_writeback:			data_opt = EXT4_MOUNT_WRITEBACK_DATA;		datacheck:			if (is_remount) {				if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS)						!= data_opt) {					printk(KERN_ERR						"EXT4-fs: cannot change data "						"mode on remount\n");					return 0;				}			} else {				sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS;				sbi->s_mount_opt |= data_opt;			}			break;#ifdef CONFIG_QUOTA		case Opt_usrjquota:			qtype = USRQUOTA;			goto set_qf_name;		case Opt_grpjquota:			qtype = GRPQUOTA;set_qf_name:			if (sb_any_quota_enabled(sb)) {				printk(KERN_ERR					"EXT4-fs: Cannot change journalled "					"quota options when quota turned on.\n");				return 0;			}			qname = match_strdup(&args[0]);			if (!qname) {				printk(KERN_ERR					"EXT4-fs: not enough memory for "					"storing quotafile name.\n");				return 0;			}			if (sbi->s_qf_names[qtype] &&			    strcmp(sbi->s_qf_names[qtype], qname)) {				printk(KERN_ERR					"EXT4-fs: %s quota file already "					"specified.\n", QTYPE2NAME(qtype));				kfree(qname);				return 0;			}			sbi->s_qf_names[qtype] = qname;			if (strchr(sbi->s_qf_names[qtype], '/')) {				printk(KERN_ERR					"EXT4-fs: quotafile must be on "					"filesystem root.\n");				kfree(sbi->s_qf_names[qtype]);				sbi->s_qf_names[qtype] = NULL;				return 0;			}			set_opt(sbi->s_mount_opt, QUOTA);			break;		case Opt_offusrjquota:			qtype = USRQUOTA;			goto clear_qf_name;		case Opt_offgrpjquota:			qtype = GRPQUOTA;clear_qf_name:			if (sb_any_quota_enabled(sb)) {				printk(KERN_ERR "EXT4-fs: Cannot change "					"journalled quota options when "					"quota turned on.\n");				return 0;			}			/*			 * The space will be released later when all options			 * are confirmed to be correct			 */			sbi->s_qf_names[qtype] = NULL;			break;		case Opt_jqfmt_vfsold:			sbi->s_jquota_fmt = QFMT_VFS_OLD;			break;		case Opt_jqfmt_vfsv0:			sbi->s_jquota_fmt = QFMT_VFS_V0;			break;		case Opt_quota:		case Opt_usrquota:			set_opt(sbi->s_mount_opt, QUOTA);			set_opt(sbi->s_mount_opt, USRQUOTA);			break;		case Opt_grpquota:			set_opt(sbi->s_mount_opt, QUOTA);			set_opt(sbi->s_mount_opt, GRPQUOTA);			break;		case Opt_noquota:			if (sb_any_quota_enabled(sb)) {				printk(KERN_ERR "EXT4-fs: Cannot change quota "					"options when quota turned on.\n");				return 0;			}			clear_opt(sbi->s_mount_opt, QUOTA);			clear_opt(sbi->s_mount_opt, USRQUOTA);			clear_opt(sbi->s_mount_opt, GRPQUOTA);			break;#else		case Opt_quota:		case Opt_usrquota:		case Opt_grpquota:		case Opt_usrjquota:		case Opt_grpjquota:		case Opt_offusrjquota:		case Opt_offgrpjquota:		case Opt_jqfmt_vfsold:		case Opt_jqfmt_vfsv0:			printk(KERN_ERR				"EXT4-fs: journalled quota options not "				"supported.\n");			break;		case Opt_noquota:			break;#endif		case Opt_abort:			set_opt(sbi->s_mount_opt, ABORT);			break;		case Opt_barrier:			if (match_int(&args[0], &option))				return 0;			if (option)				set_opt(sbi->s_mount_opt, BARRIER);			else				clear_opt(sbi->s_mount_opt, BARRIER);			break;		case Opt_ignore:			break;		case Opt_resize:			if (!is_remount) {				printk("EXT4-fs: resize option only available "					"for remount\n");				return 0;			}			if (match_int(&args[0], &option) != 0)				return 0;			*n_blocks_count = option;			break;		case Opt_nobh:			set_opt(sbi->s_mount_opt, NOBH);			break;		case Opt_bh:			clear_opt(sbi->s_mount_opt, NOBH);			break;		case Opt_extents:			set_opt (sbi->s_mount_opt, EXTENTS);			break;		case Opt_noextents:			clear_opt (sbi->s_mount_opt, EXTENTS);			break;		default:			printk (KERN_ERR				"EXT4-fs: Unrecognized mount option \"%s\" "				"or missing value\n", p);			return 0;		}	}#ifdef CONFIG_QUOTA	if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {		if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) &&		     sbi->s_qf_names[USRQUOTA])			clear_opt(sbi->s_mount_opt, USRQUOTA);		if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) &&		     sbi->s_qf_names[GRPQUOTA])			clear_opt(sbi->s_mount_opt, GRPQUOTA);		if ((sbi->s_qf_names[USRQUOTA] &&				(sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) ||		    (sbi->s_qf_names[GRPQUOTA] &&				(sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) {			printk(KERN_ERR "EXT4-fs: old and new quota "					"format mixing.\n");			return 0;		}		if (!sbi->s_jquota_fmt) {			printk(KERN_ERR "EXT4-fs: journalled quota format "					"not specified.\n");			return 0;		}	} else {		if (sbi->s_jquota_fmt) {			printk(KERN_ERR "EXT4-fs: journalled quota format "					"specified with no journalling "					"enabled.\n");			return 0;		}	}#endif	return 1;}static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,			    int read_only){	struct ext4_sb_info *sbi = EXT4_SB(sb);	int res = 0;	if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) {		printk (KERN_ERR "EXT4-fs warning: revision level too high, "			"forcing read-only mode\n");		res = MS_RDONLY;	}	if (read_only)		return res;	if (!(sbi->s_mount_state & EXT4_VALID_FS))		printk (KERN_WARNING "EXT4-fs warning: mounting unchecked fs, "			"running e2fsck is recommended\n");	else if ((sbi->s_mount_state & EXT4_ERROR_FS))		printk (KERN_WARNING			"EXT4-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 (KERN_WARNING			"EXT4-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 (KERN_WARNING			"EXT4-fs warning: checktime reached, "			"running e2fsck is recommended\n");#if 0		/* @@@ We _will_ want to clear the valid bit if we find		 * inconsistencies, to force a fsck at reboot.  But for		 * a plain journaled filesystem we can keep it set as		 * valid forever! :)		 */	es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT4_VALID_FS);#endif	if (!(__s16) le16_to_cpu(es->s_max_mnt_count))		es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT);	es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);	es->s_mtime = cpu_to_le32(get_seconds());	ext4_update_dynamic_rev(sb);	EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);	ext4_commit_super(sb, es, 1);	if (test_opt(sb, DEBUG))		printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%lu, "				"bpg=%lu, ipg=%lu, mo=%04lx]\n",			sb->s_blocksize,			sbi->s_groups_count,			EXT4_BLOCKS_PER_GROUP(sb),			EXT4_INODES_PER_GROUP(sb),			sbi->s_mount_opt);	printk(KERN_INFO "EXT4 FS on %s, ", sb->s_id);	if (EXT4_SB(sb)->s_journal->j_inode == NULL) {		char b[BDEVNAME_SIZE];		printk("external journal on %s\n",			bdevname(EXT4_SB(sb)->s_journal->j_dev, b));	} else {		printk("internal journal\n");	}	return res;}__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,			    struct ext4_group_desc *gdp){	__u16 crc = 0;	if (sbi->s_es->s_feature_ro_compat &	    cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {		int offset = offsetof(struct ext4_group_desc, bg_checksum);		__le32 le_group = cpu_to_le32(block_group);		crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));		crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));		crc = crc16(crc, (__u8 *)gdp, offset);		offset += sizeof(gdp->bg_checksum); /* skip checksum */		/* for checksum of struct ext4_group_desc do the rest...*/		if ((sbi->s_es->s_feature_incompat &		     cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&		    offset < le16_to_cpu(sbi->s_es->s_desc_size))			crc = crc16(crc, (__u8 *)gdp + offset,				    le16_to_cpu(sbi->s_es->s_desc_size) -					offset);	}	return cpu_to_le16(crc);}int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group,				struct ext4_group_desc *gdp){	if ((sbi->s_es->s_feature_ro_compat &	     cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&	    (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))		return 0;	return 1;}

⌨️ 快捷键说明

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