Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5799018 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

ext4: move sysfs code from super.c to fs/ext4/sysfs.c



Also statically allocate the ext4_kset and ext4_feat objects, since we
only need exactly one of each, and it's simpler and less code if we
drop the dynamic allocation and deallocation when it's not needed.

Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 1f93e4a9
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -8,7 +8,7 @@ ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o page-io.o \
		ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
		ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
		ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \
		ext4_jbd2.o migrate.o mballoc.o block_validity.o move_extent.o \
		mmp.o indirect.o extents_status.o xattr.o xattr_user.o \
		mmp.o indirect.o extents_status.o xattr.o xattr_user.o \
		xattr_trusted.o inline.o readpage.o
		xattr_trusted.o inline.o readpage.o sysfs.o


ext4-$(CONFIG_EXT4_FS_POSIX_ACL)	+= acl.o
ext4-$(CONFIG_EXT4_FS_POSIX_ACL)	+= acl.o
ext4-$(CONFIG_EXT4_FS_SECURITY)		+= xattr_security.o
ext4-$(CONFIG_EXT4_FS_SECURITY)		+= xattr_security.o
+5 −0
Original line number Original line Diff line number Diff line
@@ -2903,6 +2903,11 @@ extern const struct inode_operations ext4_encrypted_symlink_inode_operations;
extern const struct inode_operations ext4_symlink_inode_operations;
extern const struct inode_operations ext4_symlink_inode_operations;
extern const struct inode_operations ext4_fast_symlink_inode_operations;
extern const struct inode_operations ext4_fast_symlink_inode_operations;


/* sysfs.c */
extern int ext4_register_sysfs(struct super_block *sb);
extern int __init ext4_init_sysfs(void);
extern void ext4_exit_sysfs(void);

/* block_validity */
/* block_validity */
extern void ext4_release_system_zone(struct super_block *sb);
extern void ext4_release_system_zone(struct super_block *sb);
extern int ext4_setup_system_zone(struct super_block *sb);
extern int ext4_setup_system_zone(struct super_block *sb);
+17 −409
Original line number Original line Diff line number Diff line
@@ -55,10 +55,8 @@
#include <trace/events/ext4.h>
#include <trace/events/ext4.h>


static struct proc_dir_entry *ext4_proc_root;
static struct proc_dir_entry *ext4_proc_root;
static struct kset *ext4_kset;
static struct ext4_lazy_init *ext4_li_info;
static struct ext4_lazy_init *ext4_li_info;
static struct mutex ext4_li_mtx;
static struct mutex ext4_li_mtx;
static struct ext4_features *ext4_feat;
static int ext4_mballoc_ready;
static int ext4_mballoc_ready;
static struct ratelimit_state ext4_mount_msg_ratelimit;
static struct ratelimit_state ext4_mount_msg_ratelimit;


@@ -83,7 +81,6 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly);
static void ext4_destroy_lazyinit_thread(void);
static void ext4_destroy_lazyinit_thread(void);
static void ext4_unregister_li_request(struct super_block *sb);
static void ext4_unregister_li_request(struct super_block *sb);
static void ext4_clear_request_list(void);
static void ext4_clear_request_list(void);
static int ext4_reserve_clusters(struct ext4_sb_info *, ext4_fsblk_t);


#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
static struct file_system_type ext2_fs_type = {
static struct file_system_type ext2_fs_type = {
@@ -2470,335 +2467,6 @@ static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi)
	return ret;
	return ret;
}
}


/* sysfs supprt */

struct ext4_attr {
	struct attribute attr;
	ssize_t (*show)(struct ext4_attr *, struct ext4_sb_info *, char *);
	ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *,
			 const char *, size_t);
	union {
		int offset;
		int deprecated_val;
	} u;
};

static int parse_strtoull(const char *buf,
		unsigned long long max, unsigned long long *value)
{
	int ret;

	ret = kstrtoull(skip_spaces(buf), 0, value);
	if (!ret && *value > max)
		ret = -EINVAL;
	return ret;
}

static ssize_t delayed_allocation_blocks_show(struct ext4_attr *a,
					      struct ext4_sb_info *sbi,
					      char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(s64) EXT4_C2B(sbi,
			percpu_counter_sum(&sbi->s_dirtyclusters_counter)));
}

static ssize_t session_write_kbytes_show(struct ext4_attr *a,
					 struct ext4_sb_info *sbi, char *buf)
{
	struct super_block *sb = sbi->s_buddy_cache->i_sb;

	if (!sb->s_bdev->bd_part)
		return snprintf(buf, PAGE_SIZE, "0\n");
	return snprintf(buf, PAGE_SIZE, "%lu\n",
			(part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
			 sbi->s_sectors_written_start) >> 1);
}

static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a,
					  struct ext4_sb_info *sbi, char *buf)
{
	struct super_block *sb = sbi->s_buddy_cache->i_sb;

	if (!sb->s_bdev->bd_part)
		return snprintf(buf, PAGE_SIZE, "0\n");
	return snprintf(buf, PAGE_SIZE, "%llu\n",
			(unsigned long long)(sbi->s_kbytes_written +
			((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
			  EXT4_SB(sb)->s_sectors_written_start) >> 1)));
}

static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
					  struct ext4_sb_info *sbi,
					  const char *buf, size_t count)
{
	unsigned long t;
	int ret;

	ret = kstrtoul(skip_spaces(buf), 0, &t);
	if (ret)
		return ret;

	if (t && (!is_power_of_2(t) || t > 0x40000000))
		return -EINVAL;

	sbi->s_inode_readahead_blks = t;
	return count;
}

static ssize_t sbi_ui_show(struct ext4_attr *a,
			   struct ext4_sb_info *sbi, char *buf)
{
	unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);

	return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
}

static ssize_t sbi_ui_store(struct ext4_attr *a,
			    struct ext4_sb_info *sbi,
			    const char *buf, size_t count)
{
	unsigned int *ui = (unsigned int *) (((char *) sbi) + a->u.offset);
	unsigned long t;
	int ret;

	ret = kstrtoul(skip_spaces(buf), 0, &t);
	if (ret)
		return ret;
	*ui = t;
	return count;
}

static ssize_t es_ui_show(struct ext4_attr *a,
			   struct ext4_sb_info *sbi, char *buf)
{

	unsigned int *ui = (unsigned int *) (((char *) sbi->s_es) +
			   a->u.offset);

	return snprintf(buf, PAGE_SIZE, "%u\n", *ui);
}

static ssize_t reserved_clusters_show(struct ext4_attr *a,
				  struct ext4_sb_info *sbi, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%llu\n",
		(unsigned long long) atomic64_read(&sbi->s_resv_clusters));
}

static ssize_t reserved_clusters_store(struct ext4_attr *a,
				   struct ext4_sb_info *sbi,
				   const char *buf, size_t count)
{
	unsigned long long val;
	int ret;

	if (parse_strtoull(buf, -1ULL, &val))
		return -EINVAL;
	ret = ext4_reserve_clusters(sbi, val);

	return ret ? ret : count;
}

static ssize_t trigger_test_error(struct ext4_attr *a,
				  struct ext4_sb_info *sbi,
				  const char *buf, size_t count)
{
	int len = count;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (len && buf[len-1] == '\n')
		len--;

	if (len)
		ext4_error(sbi->s_sb, "%.*s", len, buf);
	return count;
}

static ssize_t sbi_deprecated_show(struct ext4_attr *a,
				   struct ext4_sb_info *sbi, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", a->u.deprecated_val);
}

#define EXT4_ATTR_OFFSET(_name,_mode,_show,_store,_elname) \
static struct ext4_attr ext4_attr_##_name = {			\
	.attr = {.name = __stringify(_name), .mode = _mode },	\
	.show	= _show,					\
	.store	= _store,					\
	.u = {							\
		.offset = offsetof(struct ext4_sb_info, _elname),\
	},							\
}

#define EXT4_ATTR_OFFSET_ES(_name,_mode,_show,_store,_elname)		\
static struct ext4_attr ext4_attr_##_name = {				\
	.attr = {.name = __stringify(_name), .mode = _mode },		\
	.show	= _show,						\
	.store	= _store,						\
	.u = {								\
		.offset = offsetof(struct ext4_super_block, _elname),	\
	},								\
}

#define EXT4_ATTR(name, mode, show, store) \
static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)

#define EXT4_INFO_ATTR(name) EXT4_ATTR(name, 0444, NULL, NULL)
#define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL)
#define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store)

#define EXT4_RO_ATTR_ES_UI(name, elname)	\
	EXT4_ATTR_OFFSET_ES(name, 0444, es_ui_show, NULL, elname)
#define EXT4_RW_ATTR_SBI_UI(name, elname)	\
	EXT4_ATTR_OFFSET(name, 0644, sbi_ui_show, sbi_ui_store, elname)

#define ATTR_LIST(name) &ext4_attr_##name.attr
#define EXT4_DEPRECATED_ATTR(_name, _val)	\
static struct ext4_attr ext4_attr_##_name = {			\
	.attr = {.name = __stringify(_name), .mode = 0444 },	\
	.show	= sbi_deprecated_show,				\
	.u = {							\
		.deprecated_val = _val,				\
	},							\
}

EXT4_RO_ATTR(delayed_allocation_blocks);
EXT4_RO_ATTR(session_write_kbytes);
EXT4_RO_ATTR(lifetime_write_kbytes);
EXT4_RW_ATTR(reserved_clusters);
EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
		 inode_readahead_blks_store, s_inode_readahead_blks);
EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats);
EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan);
EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
EXT4_DEPRECATED_ATTR(max_writeback_mb_bump, 128);
EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
EXT4_RW_ATTR_SBI_UI(err_ratelimit_burst, s_err_ratelimit_state.burst);
EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.interval);
EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst);
EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval);
EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst);
EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
EXT4_RO_ATTR_ES_UI(first_error_time, s_first_error_time);
EXT4_RO_ATTR_ES_UI(last_error_time, s_last_error_time);

static struct attribute *ext4_attrs[] = {
	ATTR_LIST(delayed_allocation_blocks),
	ATTR_LIST(session_write_kbytes),
	ATTR_LIST(lifetime_write_kbytes),
	ATTR_LIST(reserved_clusters),
	ATTR_LIST(inode_readahead_blks),
	ATTR_LIST(inode_goal),
	ATTR_LIST(mb_stats),
	ATTR_LIST(mb_max_to_scan),
	ATTR_LIST(mb_min_to_scan),
	ATTR_LIST(mb_order2_req),
	ATTR_LIST(mb_stream_req),
	ATTR_LIST(mb_group_prealloc),
	ATTR_LIST(max_writeback_mb_bump),
	ATTR_LIST(extent_max_zeroout_kb),
	ATTR_LIST(trigger_fs_error),
	ATTR_LIST(err_ratelimit_interval_ms),
	ATTR_LIST(err_ratelimit_burst),
	ATTR_LIST(warning_ratelimit_interval_ms),
	ATTR_LIST(warning_ratelimit_burst),
	ATTR_LIST(msg_ratelimit_interval_ms),
	ATTR_LIST(msg_ratelimit_burst),
	ATTR_LIST(errors_count),
	ATTR_LIST(first_error_time),
	ATTR_LIST(last_error_time),
	NULL,
};

/* Features this copy of ext4 supports */
EXT4_INFO_ATTR(lazy_itable_init);
EXT4_INFO_ATTR(batched_discard);
EXT4_INFO_ATTR(meta_bg_resize);
EXT4_INFO_ATTR(encryption);

static struct attribute *ext4_feat_attrs[] = {
	ATTR_LIST(lazy_itable_init),
	ATTR_LIST(batched_discard),
	ATTR_LIST(meta_bg_resize),
	ATTR_LIST(encryption),
	NULL,
};

static ssize_t ext4_attr_show(struct kobject *kobj,
			      struct attribute *attr, char *buf)
{
	struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
						s_kobj);
	struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);

	return a->show ? a->show(a, sbi, buf) : 0;
}

static ssize_t ext4_attr_store(struct kobject *kobj,
			       struct attribute *attr,
			       const char *buf, size_t len)
{
	struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
						s_kobj);
	struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);

	return a->store ? a->store(a, sbi, buf, len) : 0;
}

static void ext4_sb_release(struct kobject *kobj)
{
	struct ext4_sb_info *sbi = container_of(kobj, struct ext4_sb_info,
						s_kobj);
	complete(&sbi->s_kobj_unregister);
}

static const struct sysfs_ops ext4_attr_ops = {
	.show	= ext4_attr_show,
	.store	= ext4_attr_store,
};

static struct kobj_type ext4_ktype = {
	.default_attrs	= ext4_attrs,
	.sysfs_ops	= &ext4_attr_ops,
	.release	= ext4_sb_release,
};

static void ext4_feat_release(struct kobject *kobj)
{
	complete(&ext4_feat->f_kobj_unregister);
}

static ssize_t ext4_feat_show(struct kobject *kobj,
			      struct attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "supported\n");
}

/*
 * We can not use ext4_attr_show/store because it relies on the kobject
 * being embedded in the ext4_sb_info structure which is definitely not
 * true in this case.
 */
static const struct sysfs_ops ext4_feat_ops = {
	.show	= ext4_feat_show,
	.store	= NULL,
};

static struct kobj_type ext4_feat_ktype = {
	.default_attrs	= ext4_feat_attrs,
	.sysfs_ops	= &ext4_feat_ops,
	.release	= ext4_feat_release,
};

/*
/*
 * Check whether this filesystem can be mounted based on
 * Check whether this filesystem can be mounted based on
 * the features present and the RDONLY/RDWR mount requested.
 * the features present and the RDONLY/RDWR mount requested.
@@ -3403,10 +3071,10 @@ int ext4_calculate_overhead(struct super_block *sb)
	return 0;
	return 0;
}
}



static void ext4_set_resv_clusters(struct super_block *sb)
static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
{
{
	ext4_fsblk_t resv_clusters;
	ext4_fsblk_t resv_clusters;
	struct ext4_sb_info *sbi = EXT4_SB(sb);


	/*
	/*
	 * There's no need to reserve anything when we aren't using extents.
	 * There's no need to reserve anything when we aren't using extents.
@@ -3415,7 +3083,7 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
	 * to keep ext2/3 backward compatibility.
	 * to keep ext2/3 backward compatibility.
	 */
	 */
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS))
		return 0;
		return;
	/*
	/*
	 * By default we reserve 2% or 4096 clusters, whichever is smaller.
	 * By default we reserve 2% or 4096 clusters, whichever is smaller.
	 * This should cover the situations where we can not afford to run
	 * This should cover the situations where we can not afford to run
@@ -3424,26 +3092,13 @@ static ext4_fsblk_t ext4_calculate_resv_clusters(struct super_block *sb)
	 * allocation would require 1, or 2 blocks, higher numbers are
	 * allocation would require 1, or 2 blocks, higher numbers are
	 * very rare.
	 * very rare.
	 */
	 */
	resv_clusters = ext4_blocks_count(EXT4_SB(sb)->s_es) >>
	resv_clusters = (ext4_blocks_count(sbi->s_es) >>
			EXT4_SB(sb)->s_cluster_bits;
			 sbi->s_cluster_bits);


	do_div(resv_clusters, 50);
	do_div(resv_clusters, 50);
	resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096);
	resv_clusters = min_t(ext4_fsblk_t, resv_clusters, 4096);


	return resv_clusters;
	atomic64_set(&sbi->s_resv_clusters, resv_clusters);
}


static int ext4_reserve_clusters(struct ext4_sb_info *sbi, ext4_fsblk_t count)
{
	ext4_fsblk_t clusters = ext4_blocks_count(sbi->s_es) >>
				sbi->s_cluster_bits;

	if (count >= clusters)
		return -EINVAL;

	atomic64_set(&sbi->s_resv_clusters, count);
	return 0;
}
}


static int ext4_fill_super(struct super_block *sb, void *data, int silent)
static int ext4_fill_super(struct super_block *sb, void *data, int silent)
@@ -4192,12 +3847,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
			 "available");
			 "available");
	}
	}


	err = ext4_reserve_clusters(sbi, ext4_calculate_resv_clusters(sb));
	ext4_set_resv_clusters(sb);
	if (err) {
		ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
			 "reserved pool", ext4_calculate_resv_clusters(sb));
		goto failed_mount4a;
	}


	err = ext4_setup_system_zone(sb);
	err = ext4_setup_system_zone(sb);
	if (err) {
	if (err) {
@@ -4248,10 +3898,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
	if (err)
	if (err)
		goto failed_mount6;
		goto failed_mount6;


	sbi->s_kobj.kset = ext4_kset;
	err = ext4_register_sysfs(sb);
	init_completion(&sbi->s_kobj_unregister);
	err = kobject_init_and_add(&sbi->s_kobj, &ext4_ktype, NULL,
				   "%s", sb->s_id);
	if (err)
	if (err)
		goto failed_mount7;
		goto failed_mount7;


@@ -5586,37 +5233,6 @@ static struct file_system_type ext4_fs_type = {
};
};
MODULE_ALIAS_FS("ext4");
MODULE_ALIAS_FS("ext4");


static int __init ext4_init_feat_adverts(void)
{
	struct ext4_features *ef;
	int ret = -ENOMEM;

	ef = kzalloc(sizeof(struct ext4_features), GFP_KERNEL);
	if (!ef)
		goto out;

	ef->f_kobj.kset = ext4_kset;
	init_completion(&ef->f_kobj_unregister);
	ret = kobject_init_and_add(&ef->f_kobj, &ext4_feat_ktype, NULL,
				   "features");
	if (ret) {
		kfree(ef);
		goto out;
	}

	ext4_feat = ef;
	ret = 0;
out:
	return ret;
}

static void ext4_exit_feat_adverts(void)
{
	kobject_put(&ext4_feat->f_kobj);
	wait_for_completion(&ext4_feat->f_kobj_unregister);
	kfree(ext4_feat);
}

/* Shared across all ext4 file systems */
/* Shared across all ext4 file systems */
wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
@@ -5643,21 +5259,16 @@ static int __init ext4_init_fs(void)


	err = ext4_init_pageio();
	err = ext4_init_pageio();
	if (err)
	if (err)
		goto out7;
		goto out5;


	err = ext4_init_system_zone();
	err = ext4_init_system_zone();
	if (err)
	if (err)
		goto out6;
		goto out4;
	ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
	if (!ext4_kset) {
		err = -ENOMEM;
		goto out5;
	}
	ext4_proc_root = proc_mkdir("fs/ext4", NULL);
	ext4_proc_root = proc_mkdir("fs/ext4", NULL);


	err = ext4_init_feat_adverts();
	err = ext4_init_sysfs();
	if (err)
	if (err)
		goto out4;
		goto out3;


	err = ext4_init_mballoc();
	err = ext4_init_mballoc();
	if (err)
	if (err)
@@ -5682,16 +5293,14 @@ static int __init ext4_init_fs(void)
	ext4_mballoc_ready = 0;
	ext4_mballoc_ready = 0;
	ext4_exit_mballoc();
	ext4_exit_mballoc();
out2:
out2:
	ext4_exit_feat_adverts();
	ext4_exit_sysfs();
out4:
out3:
	if (ext4_proc_root)
	if (ext4_proc_root)
		remove_proc_entry("fs/ext4", NULL);
		remove_proc_entry("fs/ext4", NULL);
	kset_unregister(ext4_kset);
out5:
	ext4_exit_system_zone();
	ext4_exit_system_zone();
out6:
out4:
	ext4_exit_pageio();
	ext4_exit_pageio();
out7:
out5:
	ext4_exit_es();
	ext4_exit_es();


	return err;
	return err;
@@ -5706,9 +5315,8 @@ static void __exit ext4_exit_fs(void)
	unregister_filesystem(&ext4_fs_type);
	unregister_filesystem(&ext4_fs_type);
	destroy_inodecache();
	destroy_inodecache();
	ext4_exit_mballoc();
	ext4_exit_mballoc();
	ext4_exit_feat_adverts();
	ext4_exit_sysfs();
	remove_proc_entry("fs/ext4", NULL);
	remove_proc_entry("fs/ext4", NULL);
	kset_unregister(ext4_kset);
	ext4_exit_system_zone();
	ext4_exit_system_zone();
	ext4_exit_pageio();
	ext4_exit_pageio();
	ext4_exit_es();
	ext4_exit_es();

fs/ext4/sysfs.c

0 → 100644
+387 −0

File added.

Preview size limit exceeded, changes collapsed.