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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		BUFFER_TRACE(sbi->s_sbh, "marking dirty");		mark_buffer_dirty(sbi->s_sbh);		ext4_commit_super(sb, es, 1);	}	for (i = 0; i < sbi->s_gdb_count; i++)		brelse(sbi->s_group_desc[i]);	kfree(sbi->s_group_desc);	percpu_counter_destroy(&sbi->s_freeblocks_counter);	percpu_counter_destroy(&sbi->s_freeinodes_counter);	percpu_counter_destroy(&sbi->s_dirs_counter);	brelse(sbi->s_sbh);#ifdef CONFIG_QUOTA	for (i = 0; i < MAXQUOTAS; i++)		kfree(sbi->s_qf_names[i]);#endif	/* Debugging code just in case the in-memory inode orphan list	 * isn't empty.  The on-disk one can be non-empty if we've	 * detected an error and taken the fs readonly, but the	 * in-memory list had better be clean by this point. */	if (!list_empty(&sbi->s_orphan))		dump_orphan_list(sb, sbi);	J_ASSERT(list_empty(&sbi->s_orphan));	invalidate_bdev(sb->s_bdev);	if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) {		/*		 * Invalidate the journal device's buffers.  We don't want them		 * floating about in memory - the physical journal device may		 * hotswapped, and it breaks the `ro-after' testing code.		 */		sync_blockdev(sbi->journal_bdev);		invalidate_bdev(sbi->journal_bdev);		ext4_blkdev_remove(sbi);	}	sb->s_fs_info = NULL;	kfree(sbi);	return;}static struct kmem_cache *ext4_inode_cachep;/* * Called inside transaction, so use GFP_NOFS */static struct inode *ext4_alloc_inode(struct super_block *sb){	struct ext4_inode_info *ei;	ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS);	if (!ei)		return NULL;#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL	ei->i_acl = EXT4_ACL_NOT_CACHED;	ei->i_default_acl = EXT4_ACL_NOT_CACHED;#endif	ei->i_block_alloc_info = NULL;	ei->vfs_inode.i_version = 1;	memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));	return &ei->vfs_inode;}static void ext4_destroy_inode(struct inode *inode){	if (!list_empty(&(EXT4_I(inode)->i_orphan))) {		printk("EXT4 Inode %p: orphan list check failed!\n",			EXT4_I(inode));		print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4,				EXT4_I(inode), sizeof(struct ext4_inode_info),				true);		dump_stack();	}	kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));}static void init_once(struct kmem_cache *cachep, void *foo){	struct ext4_inode_info *ei = (struct ext4_inode_info *) foo;	INIT_LIST_HEAD(&ei->i_orphan);#ifdef CONFIG_EXT4DEV_FS_XATTR	init_rwsem(&ei->xattr_sem);#endif	mutex_init(&ei->truncate_mutex);	inode_init_once(&ei->vfs_inode);}static int init_inodecache(void){	ext4_inode_cachep = kmem_cache_create("ext4_inode_cache",					     sizeof(struct ext4_inode_info),					     0, (SLAB_RECLAIM_ACCOUNT|						SLAB_MEM_SPREAD),					     init_once);	if (ext4_inode_cachep == NULL)		return -ENOMEM;	return 0;}static void destroy_inodecache(void){	kmem_cache_destroy(ext4_inode_cachep);}static void ext4_clear_inode(struct inode *inode){	struct ext4_block_alloc_info *rsv = EXT4_I(inode)->i_block_alloc_info;#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL	if (EXT4_I(inode)->i_acl &&			EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) {		posix_acl_release(EXT4_I(inode)->i_acl);		EXT4_I(inode)->i_acl = EXT4_ACL_NOT_CACHED;	}	if (EXT4_I(inode)->i_default_acl &&			EXT4_I(inode)->i_default_acl != EXT4_ACL_NOT_CACHED) {		posix_acl_release(EXT4_I(inode)->i_default_acl);		EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED;	}#endif	ext4_discard_reservation(inode);	EXT4_I(inode)->i_block_alloc_info = NULL;	if (unlikely(rsv))		kfree(rsv);}static inline void ext4_show_quota_options(struct seq_file *seq, struct super_block *sb){#if defined(CONFIG_QUOTA)	struct ext4_sb_info *sbi = EXT4_SB(sb);	if (sbi->s_jquota_fmt)		seq_printf(seq, ",jqfmt=%s",		(sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");	if (sbi->s_qf_names[USRQUOTA])		seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);	if (sbi->s_qf_names[GRPQUOTA])		seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);	if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA)		seq_puts(seq, ",usrquota");	if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)		seq_puts(seq, ",grpquota");#endif}/* * Show an option if *  - it's set to a non-default value OR *  - if the per-sb default is different from the global default */static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs){	struct super_block *sb = vfs->mnt_sb;	struct ext4_sb_info *sbi = EXT4_SB(sb);	struct ext4_super_block *es = sbi->s_es;	unsigned long def_mount_opts;	def_mount_opts = le32_to_cpu(es->s_default_mount_opts);	if (sbi->s_sb_block != 1)		seq_printf(seq, ",sb=%llu", sbi->s_sb_block);	if (test_opt(sb, MINIX_DF))		seq_puts(seq, ",minixdf");	if (test_opt(sb, GRPID))		seq_puts(seq, ",grpid");	if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS))		seq_puts(seq, ",nogrpid");	if (sbi->s_resuid != EXT4_DEF_RESUID ||	    le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) {		seq_printf(seq, ",resuid=%u", sbi->s_resuid);	}	if (sbi->s_resgid != EXT4_DEF_RESGID ||	    le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) {		seq_printf(seq, ",resgid=%u", sbi->s_resgid);	}	if (test_opt(sb, ERRORS_CONT)) {		int def_errors = le16_to_cpu(es->s_errors);		if (def_errors == EXT4_ERRORS_PANIC ||		    def_errors == EXT4_ERRORS_RO) {			seq_puts(seq, ",errors=continue");		}	}	if (test_opt(sb, ERRORS_RO))		seq_puts(seq, ",errors=remount-ro");	if (test_opt(sb, ERRORS_PANIC))		seq_puts(seq, ",errors=panic");	if (test_opt(sb, NO_UID32))		seq_puts(seq, ",nouid32");	if (test_opt(sb, DEBUG))		seq_puts(seq, ",debug");	if (test_opt(sb, OLDALLOC))		seq_puts(seq, ",oldalloc");#ifdef CONFIG_EXT4_FS_XATTR	if (test_opt(sb, XATTR_USER))		seq_puts(seq, ",user_xattr");	if (!test_opt(sb, XATTR_USER) &&	    (def_mount_opts & EXT4_DEFM_XATTR_USER)) {		seq_puts(seq, ",nouser_xattr");	}#endif#ifdef CONFIG_EXT4_FS_POSIX_ACL	if (test_opt(sb, POSIX_ACL))		seq_puts(seq, ",acl");	if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))		seq_puts(seq, ",noacl");#endif	if (!test_opt(sb, RESERVATION))		seq_puts(seq, ",noreservation");	if (sbi->s_commit_interval) {		seq_printf(seq, ",commit=%u",			   (unsigned) (sbi->s_commit_interval / HZ));	}	if (test_opt(sb, BARRIER))		seq_puts(seq, ",barrier=1");	if (test_opt(sb, NOBH))		seq_puts(seq, ",nobh");	if (!test_opt(sb, EXTENTS))		seq_puts(seq, ",noextents");	if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)		seq_puts(seq, ",data=journal");	else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)		seq_puts(seq, ",data=ordered");	else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)		seq_puts(seq, ",data=writeback");	ext4_show_quota_options(seq, sb);	return 0;}static struct inode *ext4_nfs_get_inode(struct super_block *sb,		u64 ino, u32 generation){	struct inode *inode;	if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)		return ERR_PTR(-ESTALE);	if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))		return ERR_PTR(-ESTALE);	/* iget isn't really right if the inode is currently unallocated!!	 *	 * ext4_read_inode will return a bad_inode if the inode had been	 * deleted, so we should be safe.	 *	 * Currently we don't know the generation for parent directory, so	 * a generation of 0 means "accept any"	 */	inode = iget(sb, ino);	if (inode == NULL)		return ERR_PTR(-ENOMEM);	if (is_bad_inode(inode) ||	    (generation && inode->i_generation != generation)) {		iput(inode);		return ERR_PTR(-ESTALE);	}	return inode;}static struct dentry *ext4_fh_to_dentry(struct super_block *sb, struct fid *fid,		int fh_len, int fh_type){	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,				    ext4_nfs_get_inode);}static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid,		int fh_len, int fh_type){	return generic_fh_to_parent(sb, fid, fh_len, fh_type,				    ext4_nfs_get_inode);}#ifdef CONFIG_QUOTA#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))static int ext4_dquot_initialize(struct inode *inode, int type);static int ext4_dquot_drop(struct inode *inode);static int ext4_write_dquot(struct dquot *dquot);static int ext4_acquire_dquot(struct dquot *dquot);static int ext4_release_dquot(struct dquot *dquot);static int ext4_mark_dquot_dirty(struct dquot *dquot);static int ext4_write_info(struct super_block *sb, int type);static int ext4_quota_on(struct super_block *sb, int type, int format_id, char *path);static int ext4_quota_on_mount(struct super_block *sb, int type);static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,			       size_t len, loff_t off);static ssize_t ext4_quota_write(struct super_block *sb, int type,				const char *data, size_t len, loff_t off);static struct dquot_operations ext4_quota_operations = {	.initialize	= ext4_dquot_initialize,	.drop		= ext4_dquot_drop,	.alloc_space	= dquot_alloc_space,	.alloc_inode	= dquot_alloc_inode,	.free_space	= dquot_free_space,	.free_inode	= dquot_free_inode,	.transfer	= dquot_transfer,	.write_dquot	= ext4_write_dquot,	.acquire_dquot	= ext4_acquire_dquot,	.release_dquot	= ext4_release_dquot,	.mark_dirty	= ext4_mark_dquot_dirty,	.write_info	= ext4_write_info};static struct quotactl_ops ext4_qctl_operations = {	.quota_on	= ext4_quota_on,	.quota_off	= vfs_quota_off,	.quota_sync	= vfs_quota_sync,	.get_info	= vfs_get_dqinfo,	.set_info	= vfs_set_dqinfo,	.get_dqblk	= vfs_get_dqblk,	.set_dqblk	= vfs_set_dqblk};#endifstatic const struct super_operations ext4_sops = {	.alloc_inode	= ext4_alloc_inode,	.destroy_inode	= ext4_destroy_inode,	.read_inode	= ext4_read_inode,	.write_inode	= ext4_write_inode,	.dirty_inode	= ext4_dirty_inode,	.delete_inode	= ext4_delete_inode,	.put_super	= ext4_put_super,	.write_super	= ext4_write_super,	.sync_fs	= ext4_sync_fs,	.write_super_lockfs = ext4_write_super_lockfs,	.unlockfs	= ext4_unlockfs,	.statfs		= ext4_statfs,	.remount_fs	= ext4_remount,	.clear_inode	= ext4_clear_inode,	.show_options	= ext4_show_options,#ifdef CONFIG_QUOTA	.quota_read	= ext4_quota_read,	.quota_write	= ext4_quota_write,#endif};static const struct export_operations ext4_export_ops = {	.fh_to_dentry = ext4_fh_to_dentry,	.fh_to_parent = ext4_fh_to_parent,	.get_parent = ext4_get_parent,};enum {	Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,	Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,	Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,	Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,	Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,	Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,	Opt_grpquota, Opt_extents, Opt_noextents,};static match_table_t tokens = {	{Opt_bsd_df, "bsddf"},	{Opt_minix_df, "minixdf"},	{Opt_grpid, "grpid"},	{Opt_grpid, "bsdgroups"},	{Opt_nogrpid, "nogrpid"},	{Opt_nogrpid, "sysvgroups"},	{Opt_resgid, "resgid=%u"},	{Opt_resuid, "resuid=%u"},	{Opt_sb, "sb=%u"},	{Opt_err_cont, "errors=continue"},	{Opt_err_panic, "errors=panic"},	{Opt_err_ro, "errors=remount-ro"},	{Opt_nouid32, "nouid32"},	{Opt_nocheck, "nocheck"},	{Opt_nocheck, "check=none"},	{Opt_debug, "debug"},	{Opt_oldalloc, "oldalloc"},	{Opt_orlov, "orlov"},	{Opt_user_xattr, "user_xattr"},	{Opt_nouser_xattr, "nouser_xattr"},	{Opt_acl, "acl"},	{Opt_noacl, "noacl"},	{Opt_reservation, "reservation"},	{Opt_noreservation, "noreservation"},	{Opt_noload, "noload"},	{Opt_nobh, "nobh"},	{Opt_bh, "bh"},	{Opt_commit, "commit=%u"},	{Opt_journal_update, "journal=update"},	{Opt_journal_inum, "journal=%u"},	{Opt_journal_dev, "journal_dev=%u"},	{Opt_abort, "abort"},	{Opt_data_journal, "data=journal"},	{Opt_data_ordered, "data=ordered"},	{Opt_data_writeback, "data=writeback"},	{Opt_offusrjquota, "usrjquota="},	{Opt_usrjquota, "usrjquota=%s"},	{Opt_offgrpjquota, "grpjquota="},	{Opt_grpjquota, "grpjquota=%s"},	{Opt_jqfmt_vfsold, "jqfmt=vfsold"},	{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},	{Opt_grpquota, "grpquota"},	{Opt_noquota, "noquota"},	{Opt_quota, "quota"},	{Opt_usrquota, "usrquota"},	{Opt_barrier, "barrier=%u"},	{Opt_extents, "extents"},	{Opt_noextents, "noextents"},	{Opt_err, NULL},	{Opt_resize, "resize"},};static ext4_fsblk_t get_sb_block(void **data){	ext4_fsblk_t	sb_block;	char		*options = (char *) *data;	if (!options || strncmp(options, "sb=", 3) != 0)		return 1;	/* Default location */	options += 3;	/*todo: use simple_strtoll with >32bit ext4 */	sb_block = simple_strtoul(options, &options, 0);	if (*options && *options != ',') {		printk("EXT4-fs: Invalid sb specification: %s\n",		       (char *) *data);		return 1;	}	if (*options == ',')		options++;	*data = (void *) options;	return sb_block;}static int parse_options (char *options, struct super_block *sb,			  unsigned int *inum, unsigned long *journal_devnum,			  ext4_fsblk_t *n_blocks_count, int is_remount){	struct ext4_sb_info *sbi = EXT4_SB(sb);	char * p;	substring_t args[MAX_OPT_ARGS];	int data_opt = 0;	int option;#ifdef CONFIG_QUOTA

⌨️ 快捷键说明

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