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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;#ifdef CONFIG_EXT3_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("EXT3 (no)user_xattr options not supported\n");			break;#endif#ifdef CONFIG_EXT3_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("EXT3 (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 "EXT3-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 "EXT3-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 "EXT3-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 = JBD_DEFAULT_MAX_COMMIT_AGE;			sbi->s_commit_interval = HZ * option;			break;		case Opt_data_journal:			data_opt = EXT3_MOUNT_JOURNAL_DATA;			goto datacheck;		case Opt_data_ordered:			data_opt = EXT3_MOUNT_ORDERED_DATA;			goto datacheck;		case Opt_data_writeback:			data_opt = EXT3_MOUNT_WRITEBACK_DATA;		datacheck:			if (is_remount) {				if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)						!= data_opt) {					printk(KERN_ERR						"EXT3-fs: cannot change data "						"mode on remount\n");					return 0;				}			} else {				sbi->s_mount_opt &= ~EXT3_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					"EXT3-fs: Cannot change journalled "					"quota options when quota turned on.\n");				return 0;			}			qname = match_strdup(&args[0]);			if (!qname) {				printk(KERN_ERR					"EXT3-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					"EXT3-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					"EXT3-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 "EXT3-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 "EXT3-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				"EXT3-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("EXT3-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;		default:			printk (KERN_ERR				"EXT3-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 & EXT3_MOUNT_USRQUOTA) &&		     sbi->s_qf_names[USRQUOTA])			clear_opt(sbi->s_mount_opt, USRQUOTA);		if ((sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) &&		     sbi->s_qf_names[GRPQUOTA])			clear_opt(sbi->s_mount_opt, GRPQUOTA);		if ((sbi->s_qf_names[USRQUOTA] &&				(sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) ||		    (sbi->s_qf_names[GRPQUOTA] &&				(sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) {			printk(KERN_ERR "EXT3-fs: old and new quota "					"format mixing.\n");			return 0;		}		if (!sbi->s_jquota_fmt) {			printk(KERN_ERR "EXT3-fs: journalled quota format "					"not specified.\n");			return 0;		}	} else {		if (sbi->s_jquota_fmt) {			printk(KERN_ERR "EXT3-fs: journalled quota format "					"specified with no journalling "					"enabled.\n");			return 0;		}	}#endif	return 1;}static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es,			    int read_only){	struct ext3_sb_info *sbi = EXT3_SB(sb);	int res = 0;	if (le32_to_cpu(es->s_rev_level) > EXT3_MAX_SUPP_REV) {		printk (KERN_ERR "EXT3-fs warning: revision level too high, "			"forcing read-only mode\n");		res = MS_RDONLY;	}	if (read_only)		return res;	if (!(sbi->s_mount_state & EXT3_VALID_FS))		printk (KERN_WARNING "EXT3-fs warning: mounting unchecked fs, "			"running e2fsck is recommended\n");	else if ((sbi->s_mount_state & EXT3_ERROR_FS))		printk (KERN_WARNING			"EXT3-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			"EXT3-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			"EXT3-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) & ~EXT3_VALID_FS);#endif	if (!(__s16) le16_to_cpu(es->s_max_mnt_count))		es->s_max_mnt_count = cpu_to_le16(EXT3_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());	ext3_update_dynamic_rev(sb);	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);	ext3_commit_super(sb, es, 1);	if (test_opt(sb, DEBUG))		printk(KERN_INFO "[EXT3 FS bs=%lu, gc=%lu, "				"bpg=%lu, ipg=%lu, mo=%04lx]\n",			sb->s_blocksize,			sbi->s_groups_count,			EXT3_BLOCKS_PER_GROUP(sb),			EXT3_INODES_PER_GROUP(sb),			sbi->s_mount_opt);	printk(KERN_INFO "EXT3 FS on %s, ", sb->s_id);	if (EXT3_SB(sb)->s_journal->j_inode == NULL) {		char b[BDEVNAME_SIZE];		printk("external journal on %s\n",			bdevname(EXT3_SB(sb)->s_journal->j_dev, b));	} else {		printk("internal journal\n");	}	return res;}/* Called at mount-time, super-block is locked */static int ext3_check_descriptors (struct super_block * sb){	struct ext3_sb_info *sbi = EXT3_SB(sb);	ext3_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);	ext3_fsblk_t last_block;	struct ext3_group_desc * gdp = NULL;	int desc_block = 0;	int i;	ext3_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 +				(EXT3_BLOCKS_PER_GROUP(sb) - 1);		if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)			gdp = (struct ext3_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)		{			ext3_error (sb, "ext3_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)		{			ext3_error (sb, "ext3_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)		{			ext3_error (sb, "ext3_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 += EXT3_BLOCKS_PER_GROUP(sb);		gdp++;	}	sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));	sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));	return 1;}/* ext3_orphan_cleanup() walks a singly-linked list of inodes (starting at * the superblock) which were deleted from all directories, but held open by * a process at the time of a crash.  We walk the list and try to delete these * inodes at recovery time (only with a read-write filesystem). * * In order to keep the orphan inode chain consistent during traversal (in * case of crash during recovery), we link each inode into the superblock * orphan list_head and handle it the same way as an inode deletion during * normal operation (which journals the operations for us). * * We only do an iget() and an iput() on each inode, which is very safe if we * accidentally point at an in-use or already deleted inode.  The worst that * can happen in this case is that we get a "bit already cleared" message from * ext3_free_inode().  The only reason we would point at a wrong inode is if * e2fsck was run on this filesystem, and it must have already done the orphan * inode cleanup for us, so we can safely abort without any further action. */static void ext3_orphan_cleanup (struct super_block * sb,				 struct ext3_super_block * es){	unsigned int s_flags = sb->s_flags;	int nr_orphans = 0, nr_truncates = 0;#ifdef CONFIG_QUOTA	int i;#endif	if (!es->s_last_orphan) {		jbd_debug(4, "no orphan inodes to clean up\n");		return;	}	if (bdev_read_only(sb->s_bdev)) {		printk(KERN_ERR "EXT3-fs: write access "			"unavailable, skipping orphan cleanup.\n");		return;	}	if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) {		if (es->s_last_orphan)			jbd_debug(1, "Errors on filesystem, "				  "clearing orphan list.\n");		es->s_last_orphan = 0;		jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");		return;	}	if (s_flags & MS_RDONLY) {		printk(KERN_INFO "EXT3-fs: %s: orphan cleanup on readonly fs\n",		       sb->s_id);		sb->s_flags &= ~MS_RDONLY;	}#ifdef CONFIG_QUOTA	/* Needed for iput() to work correctly and not trash data */	sb->s_flags |= MS_ACTIVE;	/* Turn on quotas so that they are updated correctly */

⌨️ 快捷键说明

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