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

📄 super.c

📁 嵌入式系统设计与实例开发源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		goto out_bdev;	}	len = le32_to_cpu(es->s_blocks_count);	start = sb_block + 1;	brelse(bh);	/* we're done with the superblock */	journal = journal_init_dev(journal_dev, sb->s_dev, 					start, len, blocksize);	if (!journal) {		printk(KERN_ERR "EXT3-fs: failed to create device journal\n");		goto out_bdev;	}	ll_rw_block(READ, 1, &journal->j_sb_buffer);	wait_on_buffer(journal->j_sb_buffer);	if (!buffer_uptodate(journal->j_sb_buffer)) {		printk(KERN_ERR "EXT3-fs: I/O error on journal device\n");		goto out_journal;	}	if (ntohl(journal->j_superblock->s_nr_users) != 1) {		printk(KERN_ERR "EXT3-fs: External journal has more than one "					"user (unsupported) - %d\n",			ntohl(journal->j_superblock->s_nr_users));		goto out_journal;	}	EXT3_SB(sb)->journal_bdev = bdev;	return journal;out_journal:	journal_destroy(journal);out_bdev:	ext3_blkdev_put(bdev);	return NULL;}static int ext3_load_journal(struct super_block * sb,			     struct ext3_super_block * es){	journal_t *journal;	int journal_inum = le32_to_cpu(es->s_journal_inum);	int journal_dev = le32_to_cpu(es->s_journal_dev);	int err = 0;	int really_read_only;	really_read_only = is_read_only(sb->s_dev);	/*	 * Are we loading a blank journal or performing recovery after a	 * crash?  For recovery, we need to check in advance whether we	 * can get read-write access to the device.	 */	if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER)) {		if (sb->s_flags & MS_RDONLY) {			printk(KERN_INFO "EXT3-fs: INFO: recovery "					"required on readonly filesystem.\n");			if (really_read_only) {				printk(KERN_ERR "EXT3-fs: write access "					"unavailable, cannot proceed.\n");				return -EROFS;			}			printk (KERN_INFO "EXT3-fs: write access will "					"be enabled during recovery.\n");		}	}	if (journal_inum && journal_dev) {		printk(KERN_ERR "EXT3-fs: filesystem has both journal "		       "and inode journals!\n");		return -EINVAL;	}	if (journal_inum) {		if (!(journal = ext3_get_journal(sb, journal_inum)))			return -EINVAL;	} else {		if (!(journal = ext3_get_dev_journal(sb, journal_dev)))			return -EINVAL;	}		if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {		err = journal_update_format(journal);		if (err)  {			printk(KERN_ERR "EXT3-fs: error updating journal.\n");			journal_destroy(journal);			return err;		}	}	if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER))		err = journal_wipe(journal, !really_read_only);	if (!err)		err = journal_load(journal);	if (err) {		printk(KERN_ERR "EXT3-fs: error loading journal.\n");		journal_destroy(journal);		return err;	}	EXT3_SB(sb)->s_journal = journal;	ext3_clear_journal_err(sb, es);	return 0;}static int ext3_create_journal(struct super_block * sb,			       struct ext3_super_block * es,			       int journal_inum){	journal_t *journal;	if (sb->s_flags & MS_RDONLY) {		printk(KERN_ERR "EXT3-fs: readonly filesystem when trying to "				"create journal.\n");		return -EROFS;	}	if (!(journal = ext3_get_journal(sb, journal_inum)))		return -EINVAL;	printk(KERN_INFO "EXT3-fs: creating new journal on inode %d\n",	       journal_inum);	if (journal_create(journal)) {		printk(KERN_ERR "EXT3-fs: error creating journal.\n");		journal_destroy(journal);		return -EIO;	}	EXT3_SB(sb)->s_journal = journal;	ext3_update_dynamic_rev(sb);	EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);	EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL);	es->s_journal_inum = cpu_to_le32(journal_inum);	sb->s_dirt = 1;	/* Make sure we flush the recovery flag to disk. */	ext3_commit_super(sb, es, 1);	return 0;}static void ext3_commit_super (struct super_block * sb,			       struct ext3_super_block * es,			       int sync){	es->s_wtime = cpu_to_le32(CURRENT_TIME);	BUFFER_TRACE(sb->u.ext3_sb.s_sbh, "marking dirty");	mark_buffer_dirty(sb->u.ext3_sb.s_sbh);	if (sync) {		ll_rw_block(WRITE, 1, &sb->u.ext3_sb.s_sbh);		wait_on_buffer(sb->u.ext3_sb.s_sbh);	}}/* * Have we just finished recovery?  If so, and if we are mounting (or * remounting) the filesystem readonly, then we will end up with a * consistent fs on disk.  Record that fact. */static void ext3_mark_recovery_complete(struct super_block * sb,					struct ext3_super_block * es){	journal_flush(EXT3_SB(sb)->s_journal);	if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&	    sb->s_flags & MS_RDONLY) {		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);		sb->s_dirt = 0;		ext3_commit_super(sb, es, 1);	}}/* * If we are mounting (or read-write remounting) a filesystem whose journal * has recorded an error from a previous lifetime, move that error to the * main filesystem now. */static void ext3_clear_journal_err(struct super_block * sb,				   struct ext3_super_block * es){	journal_t *journal;	int j_errno;	const char *errstr;		journal = EXT3_SB(sb)->s_journal;	/*	 * Now check for any error status which may have been recorded in the	 * journal by a prior ext3_error() or ext3_abort()	 */	j_errno = journal_errno(journal);	if (j_errno) {		char nbuf[16];				errstr = ext3_decode_error(sb, j_errno, nbuf);		ext3_warning(sb, __FUNCTION__, "Filesystem error recorded "			     "from previous mount: %s", errstr);		ext3_warning(sb, __FUNCTION__, "Marking fs in need of "			     "filesystem check.");				sb->u.ext3_sb.s_mount_state |= EXT3_ERROR_FS;		es->s_state |= cpu_to_le16(EXT3_ERROR_FS);		ext3_commit_super (sb, es, 1);		journal_clear_err(journal);	}}/* * Force the running and committing transactions to commit, * and wait on the commit. */int ext3_force_commit(struct super_block *sb){	journal_t *journal;	int ret;	if (sb->s_flags & MS_RDONLY)		return 0;	journal = EXT3_SB(sb)->s_journal;	sb->s_dirt = 0;	lock_kernel();	/* important: lock down j_running_transaction */	ret = ext3_journal_force_commit(journal);	unlock_kernel();	return ret;}/* * Ext3 always journals updates to the superblock itself, so we don't * have to propagate any other updates to the superblock on disk at this * point.  Just start an async writeback to get the buffers on their way * to the disk. * * This implicitly triggers the writebehind on sync(). */static int do_sync_supers = 0;MODULE_PARM(do_sync_supers, "i");MODULE_PARM_DESC(do_sync_supers, "Write superblocks synchronously");void ext3_write_super (struct super_block * sb){	tid_t target;		if (down_trylock(&sb->s_lock) == 0)		BUG();		/* aviro detector */	sb->s_dirt = 0;	target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);	if (do_sync_supers) {		unlock_super(sb);		log_wait_commit(EXT3_SB(sb)->s_journal, target);		lock_super(sb);	}}/* * LVM calls this function before a (read-only) snapshot is created.  This * gives us a chance to flush the journal completely and mark the fs clean. */void ext3_write_super_lockfs(struct super_block *sb){	sb->s_dirt = 0;	lock_kernel();		/* 2.4.5 forgot to do this for us */	if (!(sb->s_flags & MS_RDONLY)) {		journal_t *journal = EXT3_SB(sb)->s_journal;		/* Now we set up the journal barrier. */		journal_lock_updates(journal);		journal_flush(journal);		/* Journal blocked and flushed, clear needs_recovery flag. */		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);	}	unlock_kernel();}/* * Called by LVM after the snapshot is done.  We need to reset the RECOVER * flag here, even though the filesystem is not technically dirty yet. */void ext3_unlockfs(struct super_block *sb){	if (!(sb->s_flags & MS_RDONLY)) {		lock_kernel();		lock_super(sb);		/* Reser the needs_recovery flag before the fs is unlocked. */		EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);		unlock_super(sb);		journal_unlock_updates(EXT3_SB(sb)->s_journal);		unlock_kernel();	}}int ext3_remount (struct super_block * sb, int * flags, char * data){	struct ext3_super_block * es;	struct ext3_sb_info *sbi = EXT3_SB(sb);	unsigned long tmp;	clear_ro_after(sb);	/*	 * Allow the "check" option to be passed as a remount option.	 */	if (!parse_options(data, &tmp, sbi, &tmp, 1))		return -EINVAL;	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)		ext3_abort(sb, __FUNCTION__, "Abort forced by user");	es = sbi->s_es;	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)			return -EROFS;		if (*flags & MS_RDONLY) {			/*			 * First of all, the unconditional stuff we have to do			 * to disable replay of the journal when we next remount			 */			sb->s_flags |= MS_RDONLY;			/*			 * OK, test if we are remounting a valid rw partition			 * readonly, and if so set the rdonly flag and then			 * mark the partition as valid again.			 */			if (!(es->s_state & cpu_to_le16(EXT3_VALID_FS)) &&			    (sbi->s_mount_state & EXT3_VALID_FS))				es->s_state = cpu_to_le16(sbi->s_mount_state);			ext3_mark_recovery_complete(sb, es);		} else {			int ret;			if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb,					~EXT3_FEATURE_RO_COMPAT_SUPP))) {				printk(KERN_WARNING "EXT3-fs: %s: couldn't "				       "remount RDWR because of unsupported "				       "optional features (%x).\n",				       bdevname(sb->s_dev), ret);				return -EROFS;			}			/*			 * Mounting a RDONLY partition read-write, so reread			 * and store the current valid flag.  (It may have			 * been changed by e2fsck since we originally mounted			 * the partition.)			 */			ext3_clear_journal_err(sb, es);			sbi->s_mount_state = le16_to_cpu(es->s_state);			if (!ext3_setup_super (sb, es, 0))				sb->s_flags &= ~MS_RDONLY;		}	}	setup_ro_after(sb);	return 0;}int ext3_statfs (struct super_block * sb, struct statfs * buf){	struct ext3_super_block *es = EXT3_SB(sb)->s_es;	unsigned long overhead;	int i;	if (test_opt (sb, MINIX_DF))		overhead = 0;	else {		/*		 * Compute the overhead (FS structures)		 */		/*		 * All of the blocks before first_data_block are		 * overhead		 */		overhead = le32_to_cpu(es->s_first_data_block);		/*		 * Add the overhead attributed to the superblock and		 * block group descriptors.  If the sparse superblocks		 * feature is turned on, then not all groups have this.		 */		for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++)			overhead += ext3_bg_has_super(sb, i) +				ext3_bg_num_gdb(sb, i);		/*		 * Every block group has an inode bitmap, a block		 * bitmap, and an inode table.		 */		overhead += (EXT3_SB(sb)->s_groups_count *			     (2 + EXT3_SB(sb)->s_itb_per_group));	}	buf->f_type = EXT3_SUPER_MAGIC;	buf->f_bsize = sb->s_blocksize;	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;	buf->f_bfree = ext3_count_free_blocks (sb);	buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);	if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))		buf->f_bavail = 0;	buf->f_files = le32_to_cpu(es->s_inodes_count);	buf->f_ffree = ext3_count_free_inodes (sb);	buf->f_namelen = EXT3_NAME_LEN;	return 0;}static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super);static int __init init_ext3_fs(void){        return register_filesystem(&ext3_fs_type);}static void __exit exit_ext3_fs(void){	unregister_filesystem(&ext3_fs_type);}EXPORT_NO_SYMBOLS;MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");MODULE_LICENSE("GPL");module_init(init_ext3_fs)module_exit(exit_ext3_fs)

⌨️ 快捷键说明

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