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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	for (i = 0; i < MAXQUOTAS; i++) {		if (EXT3_SB(sb)->s_qf_names[i]) {			int ret = ext3_quota_on_mount(sb, i);			if (ret < 0)				printk(KERN_ERR					"EXT3-fs: Cannot turn on journalled "					"quota: error %d\n", ret);		}	}#endif	while (es->s_last_orphan) {		struct inode *inode;		if (!(inode =		      ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan)))) {			es->s_last_orphan = 0;			break;		}		list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan);		DQUOT_INIT(inode);		if (inode->i_nlink) {			printk(KERN_DEBUG				"%s: truncating inode %lu to %Ld bytes\n",				__FUNCTION__, inode->i_ino, inode->i_size);			jbd_debug(2, "truncating inode %lu to %Ld bytes\n",				  inode->i_ino, inode->i_size);			ext3_truncate(inode);			nr_truncates++;		} else {			printk(KERN_DEBUG				"%s: deleting unreferenced inode %lu\n",				__FUNCTION__, inode->i_ino);			jbd_debug(2, "deleting unreferenced inode %lu\n",				  inode->i_ino);			nr_orphans++;		}		iput(inode);  /* The delete magic happens here! */	}#define PLURAL(x) (x), ((x)==1) ? "" : "s"	if (nr_orphans)		printk(KERN_INFO "EXT3-fs: %s: %d orphan inode%s deleted\n",		       sb->s_id, PLURAL(nr_orphans));	if (nr_truncates)		printk(KERN_INFO "EXT3-fs: %s: %d truncate%s cleaned up\n",		       sb->s_id, PLURAL(nr_truncates));#ifdef CONFIG_QUOTA	/* Turn quotas off */	for (i = 0; i < MAXQUOTAS; i++) {		if (sb_dqopt(sb)->files[i])			vfs_quota_off(sb, i);	}#endif	sb->s_flags = s_flags; /* Restore MS_RDONLY status */}/* * 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 ext3_max_size(int bits){	loff_t res = EXT3_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 ext3_fsblk_t descriptor_loc(struct super_block *sb,				    ext3_fsblk_t logic_sb_block,				    int nr){	struct ext3_sb_info *sbi = EXT3_SB(sb);	unsigned long bg, first_meta_bg;	int has_super = 0;	first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||	    nr < first_meta_bg)		return (logic_sb_block + nr + 1);	bg = sbi->s_desc_per_block * nr;	if (ext3_bg_has_super(sb, bg))		has_super = 1;	return (has_super + ext3_group_first_block_no(sb, bg));}static int ext3_fill_super (struct super_block *sb, void *data, int silent){	struct buffer_head * bh;	struct ext3_super_block *es = NULL;	struct ext3_sb_info *sbi;	ext3_fsblk_t block;	ext3_fsblk_t sb_block = get_sb_block(&data);	ext3_fsblk_t logic_sb_block;	unsigned long offset = 0;	unsigned int journal_inum = 0;	unsigned long journal_devnum = 0;	unsigned long def_mount_opts;	struct inode *root;	int blocksize;	int hblock;	int db_count;	int i;	int needs_recovery;	__le32 features;	int err;	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);	if (!sbi)		return -ENOMEM;	sb->s_fs_info = sbi;	sbi->s_mount_opt = 0;	sbi->s_resuid = EXT3_DEF_RESUID;	sbi->s_resgid = EXT3_DEF_RESGID;	sbi->s_sb_block = sb_block;	unlock_kernel();	blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);	if (!blocksize) {		printk(KERN_ERR "EXT3-fs: unable to set blocksize\n");		goto out_fail;	}	/*	 * The ext3 superblock will not be buffer aligned for other than 1kB	 * block sizes.  We need to calculate the offset from buffer start.	 */	if (blocksize != EXT3_MIN_BLOCK_SIZE) {		logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;		offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;	} else {		logic_sb_block = sb_block;	}	if (!(bh = sb_bread(sb, logic_sb_block))) {		printk (KERN_ERR "EXT3-fs: unable to read superblock\n");		goto out_fail;	}	/*	 * Note: s_es must be initialized as soon as possible because	 *       some ext3 macro-instructions depend on its value	 */	es = (struct ext3_super_block *) (((char *)bh->b_data) + offset);	sbi->s_es = es;	sb->s_magic = le16_to_cpu(es->s_magic);	if (sb->s_magic != EXT3_SUPER_MAGIC)		goto cantfind_ext3;	/* Set defaults before we parse the mount options */	def_mount_opts = le32_to_cpu(es->s_default_mount_opts);	if (def_mount_opts & EXT3_DEFM_DEBUG)		set_opt(sbi->s_mount_opt, DEBUG);	if (def_mount_opts & EXT3_DEFM_BSDGROUPS)		set_opt(sbi->s_mount_opt, GRPID);	if (def_mount_opts & EXT3_DEFM_UID16)		set_opt(sbi->s_mount_opt, NO_UID32);#ifdef CONFIG_EXT3_FS_XATTR	if (def_mount_opts & EXT3_DEFM_XATTR_USER)		set_opt(sbi->s_mount_opt, XATTR_USER);#endif#ifdef CONFIG_EXT3_FS_POSIX_ACL	if (def_mount_opts & EXT3_DEFM_ACL)		set_opt(sbi->s_mount_opt, POSIX_ACL);#endif	if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)		sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;	else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)		sbi->s_mount_opt |= EXT3_MOUNT_ORDERED_DATA;	else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_WBACK)		sbi->s_mount_opt |= EXT3_MOUNT_WRITEBACK_DATA;	if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC)		set_opt(sbi->s_mount_opt, ERRORS_PANIC);	else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_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, sb, &journal_inum, &journal_devnum,			    NULL, 0))		goto failed_mount;	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);	if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV &&	    (EXT3_HAS_COMPAT_FEATURE(sb, ~0U) ||	     EXT3_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||	     EXT3_HAS_INCOMPAT_FEATURE(sb, ~0U)))		printk(KERN_WARNING		       "EXT3-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 = EXT3_HAS_INCOMPAT_FEATURE(sb, ~EXT3_FEATURE_INCOMPAT_SUPP);	if (features) {		printk(KERN_ERR "EXT3-fs: %s: couldn't mount because of "		       "unsupported optional features (%x).\n",		       sb->s_id, le32_to_cpu(features));		goto failed_mount;	}	features = EXT3_HAS_RO_COMPAT_FEATURE(sb, ~EXT3_FEATURE_RO_COMPAT_SUPP);	if (!(sb->s_flags & MS_RDONLY) && features) {		printk(KERN_ERR "EXT3-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(es->s_log_block_size);	if (blocksize < EXT3_MIN_BLOCK_SIZE ||	    blocksize > EXT3_MAX_BLOCK_SIZE) {		printk(KERN_ERR		       "EXT3-fs: Unsupported filesystem blocksize %d on %s.\n",		       blocksize, sb->s_id);		goto failed_mount;	}	hblock = bdev_hardsect_size(sb->s_bdev);	if (sb->s_blocksize != blocksize) {		/*		 * Make sure the blocksize for the filesystem is larger		 * than the hardware sectorsize for the machine.		 */		if (blocksize < hblock) {			printk(KERN_ERR "EXT3-fs: blocksize %d too small for "			       "device blocksize %d.\n", blocksize, hblock);			goto failed_mount;		}		brelse (bh);		if (!sb_set_blocksize(sb, blocksize)) {			printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n",				blocksize);			goto out_fail;		}		logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;		offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;		bh = sb_bread(sb, logic_sb_block);		if (!bh) {			printk(KERN_ERR			       "EXT3-fs: Can't read superblock on 2nd try.\n");			goto failed_mount;		}		es = (struct ext3_super_block *)(((char *)bh->b_data) + offset);		sbi->s_es = es;		if (es->s_magic != cpu_to_le16(EXT3_SUPER_MAGIC)) {			printk (KERN_ERR				"EXT3-fs: Magic mismatch, very weird !\n");			goto failed_mount;		}	}	sb->s_maxbytes = ext3_max_size(sb->s_blocksize_bits);	if (le32_to_cpu(es->s_rev_level) == EXT3_GOOD_OLD_REV) {		sbi->s_inode_size = EXT3_GOOD_OLD_INODE_SIZE;		sbi->s_first_ino = EXT3_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 < EXT3_GOOD_OLD_INODE_SIZE) ||		    (!is_power_of_2(sbi->s_inode_size)) ||		    (sbi->s_inode_size > blocksize)) {			printk (KERN_ERR				"EXT3-fs: unsupported inode size: %d\n",				sbi->s_inode_size);			goto failed_mount;		}	}	sbi->s_frag_size = EXT3_MIN_FRAG_SIZE <<				   le32_to_cpu(es->s_log_frag_size);	if (blocksize != sbi->s_frag_size) {		printk(KERN_ERR		       "EXT3-fs: fragsize %lu != blocksize %u (unsupported)\n",		       sbi->s_frag_size, blocksize);		goto failed_mount;	}	sbi->s_frags_per_block = 1;	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 (EXT3_INODE_SIZE(sb) == 0 || EXT3_INODES_PER_GROUP(sb) == 0)		goto cantfind_ext3;	sbi->s_inodes_per_block = blocksize / EXT3_INODE_SIZE(sb);	if (sbi->s_inodes_per_block == 0)		goto cantfind_ext3;	sbi->s_itb_per_group = sbi->s_inodes_per_group /					sbi->s_inodes_per_block;	sbi->s_desc_per_block = blocksize / sizeof(struct ext3_group_desc);	sbi->s_sbh = bh;	sbi->s_mount_state = le16_to_cpu(es->s_state);	sbi->s_addr_per_block_bits = ilog2(EXT3_ADDR_PER_BLOCK(sb));	sbi->s_desc_per_block_bits = ilog2(EXT3_DESC_PER_BLOCK(sb));	for (i=0; i < 4; i++)		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);	sbi->s_def_hash_version = es->s_def_hash_version;	if (sbi->s_blocks_per_group > blocksize * 8) {		printk (KERN_ERR			"EXT3-fs: #blocks per group too big: %lu\n",			sbi->s_blocks_per_group);		goto failed_mount;	}	if (sbi->s_frags_per_group > blocksize * 8) {		printk (KERN_ERR			"EXT3-fs: #fragments per group too big: %lu\n",			sbi->s_frags_per_group);		goto failed_mount;	}	if (sbi->s_inodes_per_group > blocksize * 8) {		printk (KERN_ERR			"EXT3-fs: #inodes per group too big: %lu\n",			sbi->s_inodes_per_group);		goto failed_mount;	}	if (le32_to_cpu(es->s_blocks_count) >		    (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {		printk(KERN_ERR "EXT3-fs: filesystem on %s:"			" too large to mount safely\n", sb->s_id);		if (sizeof(sector_t) < 8)			printk(KERN_WARNING "EXT3-fs: CONFIG_LBD not "					"enabled\n");		goto failed_mount;	}	if (EXT3_BLOCKS_PER_GROUP(sb) == 0)		goto cantfind_ext3;	sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -			       le32_to_cpu(es->s_first_data_block) - 1)				       / EXT3_BLOCKS_PER_GROUP(sb)) + 1;	db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /		   EXT3_DESC_PER_BLOCK(sb);	sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),				    GFP_KERNEL);	if (sbi->s_group_desc == NULL) {		printk (KERN_ERR "EXT3-fs: not enough memory\n");		goto failed_mount;	}	bgl_lock_init(&sbi->s_blockgroup_lock);	for (i = 0; i < db_count; i++) {		block = descriptor_loc(sb, logic_sb_block, i);		sbi->s_group_desc[i] = sb_bread(sb, block);		if (!sbi->s_group_desc[i]) {			printk (KERN_ERR "EXT3-fs: "				"can't read group descriptor %d\n", i);			db_count = i;			goto failed_mount2;		}	}	if (!ext3_check_descriptors (sb)) {		printk(KERN_ERR "EXT3-fs: group descriptors corrupted!\n");		goto failed_mount2;	}	sbi->s_gdb_count = db_count;	get_random_bytes(&sbi->s_next_generation, sizeof(u32));	spin_lock_init(&sbi->s_next_gen_lock);	err = percpu_counter_init(&sbi->s_freeblocks_counter,			ext3_count_free_blocks(sb));	if (!err) {		err = percpu_counter_init(&sbi->s_freeinodes_counter,				ext3_count_free_inodes(sb));	}	if (!err) {		err = percpu_counter_init(&sbi->s_dirs_counter,				ext3_count_dirs(sb));	}	if (err) {		printk(KERN_ERR "EXT3-fs: insufficient memory\n");		goto failed_mount3;	}	/* per fileystem reservation list head & lock */	spin_lock_init(&sbi->s_rsv_window_lock);	sbi->s_rsv_window_root = RB_ROOT;	/* Add a single, static dummy reservation to the start of the	 * reservation window list --- it gives us a placeholder for	 * append-at-start-of-list which makes the allocation logic	 * _much_ simpler. */	sbi->s_rsv_window_head.rsv_start = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;	sbi->s_rsv_window_head.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;	sbi->s_rsv_window_head.rsv_alloc_hit = 0;	sbi->s_rsv_window_head.rsv_goal_size = 0;	ext3_rsv_window_add(sb, &sbi->s_rsv_window_head);	/*	 * set up enough so that it can read an inode	 */	sb->s_op = &ext3_sops;	sb->s_export_op = &ext3_export_ops;	sb->s_xattr = ext3_xattr_handlers;#ifdef CONFIG_QUOTA	sb->s_qcop = &ext3_qctl_operations;	sb->dq_op = &ext3_quota_operations;#endif	INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */	sb->s_root = NULL;	needs_recovery = (es->s_last_orphan != 0 ||			  EXT3_HAS_INCOMPAT_FEATURE(sb,				    EXT3_FEATURE_INCOMPAT_RECOVER));	/*	 * The first inode we look at is the journal inode.  Don't try	 * root first: it may be modified in the journal!	 */	if (!test_opt(sb, NOLOAD) &&	    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {		if (ext3_load_journal(sb, es, journal_devnum))			goto failed_mount3;	} else if (journal_inum) {		if (ext3_create_journal(sb, es, journal_inum))			goto failed_mount3;	} else {		if (!silent)			printk (KERN_ERR				"ext3: No journal on filesystem on %s\n",				sb->s_id);		goto failed_mount3;	}	/* We have now updated the journal if required, so we can	 * validate the data journaling mode. */	switch (test_opt(sb, DATA_FLAGS)) {	case 0:		/* No mode set, assume a default based on the journal                   capabilities: ORDERED_DATA if the journal can

⌨️ 快捷键说明

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