Commit d6f9469a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull erofs updates from Gao Xiang:
 "The most interesting part is the new mount api conversion, which is
  actually a old patch already pending for several cycles. And the
  others are recent trivial cleanups here.

  Summary:

   - Convert to use the new mount apis

   - Some random cleanup patches"

* tag 'erofs-for-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: suppress false positive last_block warning
  erofs: convert to use the new mount fs_context api
  erofs: code cleanup by removing ifdef macro surrounding
parents cadf3223 34f853b8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ submit_bio_out:
 */
static int erofs_raw_access_readpage(struct file *file, struct page *page)
{
	erofs_off_t last_block;
	erofs_off_t uninitialized_var(last_block);
	struct bio *bio;

	trace_erofs_readpage(page, true);
@@ -282,7 +282,7 @@ static int erofs_raw_access_readpage(struct file *file, struct page *page)

static void erofs_raw_access_readahead(struct readahead_control *rac)
{
	erofs_off_t last_block;
	erofs_off_t uninitialized_var(last_block);
	struct bio *bio = NULL;
	struct page *page;

+0 −6
Original line number Diff line number Diff line
@@ -311,27 +311,21 @@ int erofs_getattr(const struct path *path, struct kstat *stat,

const struct inode_operations erofs_generic_iops = {
	.getattr = erofs_getattr,
#ifdef CONFIG_EROFS_FS_XATTR
	.listxattr = erofs_listxattr,
#endif
	.get_acl = erofs_get_acl,
};

const struct inode_operations erofs_symlink_iops = {
	.get_link = page_get_link,
	.getattr = erofs_getattr,
#ifdef CONFIG_EROFS_FS_XATTR
	.listxattr = erofs_listxattr,
#endif
	.get_acl = erofs_get_acl,
};

const struct inode_operations erofs_fast_symlink_iops = {
	.get_link = simple_get_link,
	.getattr = erofs_getattr,
#ifdef CONFIG_EROFS_FS_XATTR
	.listxattr = erofs_listxattr,
#endif
	.get_acl = erofs_get_acl,
};
+16 −11
Original line number Diff line number Diff line
@@ -46,6 +46,17 @@ typedef u64 erofs_off_t;
/* data type for filesystem-wide blocks number */
typedef u32 erofs_blk_t;

struct erofs_fs_context {
#ifdef CONFIG_EROFS_FS_ZIP
	/* current strategy of how to use managed cache */
	unsigned char cache_strategy;

	/* threshold for decompression synchronously */
	unsigned int max_sync_decompress_pages;
#endif
	unsigned int mount_opt;
};

struct erofs_sb_info {
#ifdef CONFIG_EROFS_FS_ZIP
	/* list for all registered superblocks, mainly for shrinker */
@@ -55,14 +66,8 @@ struct erofs_sb_info {
	/* managed XArray arranged in physical block number */
	struct xarray managed_pslots;

	/* threshold for decompression synchronously */
	unsigned int max_sync_decompress_pages;

	unsigned int shrinker_run_no;

	/* current strategy of how to use managed cache */
	unsigned char cache_strategy;

	/* pseudo inode to manage cached pages */
	struct inode *managed_cache;
#endif	/* CONFIG_EROFS_FS_ZIP */
@@ -88,7 +93,7 @@ struct erofs_sb_info {
	u32 feature_compat;
	u32 feature_incompat;

	unsigned int mount_opt;
	struct erofs_fs_context ctx;	/* options */
};

#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
@@ -98,17 +103,17 @@ struct erofs_sb_info {
#define EROFS_MOUNT_XATTR_USER		0x00000010
#define EROFS_MOUNT_POSIX_ACL		0x00000020

#define clear_opt(sbi, option)	((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
#define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
#define test_opt(sbi, option)	((sbi)->mount_opt & EROFS_MOUNT_##option)
#define clear_opt(ctx, option)	((ctx)->mount_opt &= ~EROFS_MOUNT_##option)
#define set_opt(ctx, option)	((ctx)->mount_opt |= EROFS_MOUNT_##option)
#define test_opt(ctx, option)	((ctx)->mount_opt & EROFS_MOUNT_##option)

#ifdef CONFIG_EROFS_FS_ZIP
enum {
	EROFS_ZIP_CACHE_DISABLED,
	EROFS_ZIP_CACHE_READAHEAD,
	EROFS_ZIP_CACHE_READAROUND
};

#ifdef CONFIG_EROFS_FS_ZIP
#define EROFS_LOCKED_MAGIC     (INT_MIN | 0xE0F510CCL)

/* basic unit of the workstation of a super_block */
+0 −2
Original line number Diff line number Diff line
@@ -244,9 +244,7 @@ static struct dentry *erofs_lookup(struct inode *dir,
const struct inode_operations erofs_dir_iops = {
	.lookup = erofs_lookup,
	.getattr = erofs_getattr,
#ifdef CONFIG_EROFS_FS_XATTR
	.listxattr = erofs_listxattr,
#endif
	.get_acl = erofs_get_acl,
};
+112 −143
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
#include <linux/parser.h>
#include <linux/seq_file.h>
#include <linux/crc32c.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include "xattr.h"

#define CREATE_TRACE_POINTS
@@ -192,53 +194,18 @@ out:
	return ret;
}

#ifdef CONFIG_EROFS_FS_ZIP
static int erofs_build_cache_strategy(struct super_block *sb,
				      substring_t *args)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	const char *cs = match_strdup(args);
	int err = 0;

	if (!cs) {
		erofs_err(sb, "Not enough memory to store cache strategy");
		return -ENOMEM;
	}

	if (!strcmp(cs, "disabled")) {
		sbi->cache_strategy = EROFS_ZIP_CACHE_DISABLED;
	} else if (!strcmp(cs, "readahead")) {
		sbi->cache_strategy = EROFS_ZIP_CACHE_READAHEAD;
	} else if (!strcmp(cs, "readaround")) {
		sbi->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
	} else {
		erofs_err(sb, "Unrecognized cache strategy \"%s\"", cs);
		err = -EINVAL;
	}
	kfree(cs);
	return err;
}
#else
static int erofs_build_cache_strategy(struct super_block *sb,
				      substring_t *args)
{
	erofs_info(sb, "EROFS compression is disabled, so cache strategy is ignored");
	return 0;
}
#endif

/* set up default EROFS parameters */
static void erofs_default_options(struct erofs_sb_info *sbi)
static void erofs_default_options(struct erofs_fs_context *ctx)
{
#ifdef CONFIG_EROFS_FS_ZIP
	sbi->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
	sbi->max_sync_decompress_pages = 3;
	ctx->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
	ctx->max_sync_decompress_pages = 3;
#endif
#ifdef CONFIG_EROFS_FS_XATTR
	set_opt(sbi, XATTR_USER);
	set_opt(ctx, XATTR_USER);
#endif
#ifdef CONFIG_EROFS_FS_POSIX_ACL
	set_opt(sbi, POSIX_ACL);
	set_opt(ctx, POSIX_ACL);
#endif
}

@@ -251,73 +218,62 @@ enum {
	Opt_err
};

static match_table_t erofs_tokens = {
	{Opt_user_xattr, "user_xattr"},
	{Opt_nouser_xattr, "nouser_xattr"},
	{Opt_acl, "acl"},
	{Opt_noacl, "noacl"},
	{Opt_cache_strategy, "cache_strategy=%s"},
	{Opt_err, NULL}
static const struct constant_table erofs_param_cache_strategy[] = {
	{"disabled",	EROFS_ZIP_CACHE_DISABLED},
	{"readahead",	EROFS_ZIP_CACHE_READAHEAD},
	{"readaround",	EROFS_ZIP_CACHE_READAROUND},
	{}
};

static int erofs_parse_options(struct super_block *sb, char *options)
{
	substring_t args[MAX_OPT_ARGS];
	char *p;
	int err;

	if (!options)
		return 0;

	while ((p = strsep(&options, ","))) {
		int token;
static const struct fs_parameter_spec erofs_fs_parameters[] = {
	fsparam_flag_no("user_xattr",	Opt_user_xattr),
	fsparam_flag_no("acl",		Opt_acl),
	fsparam_enum("cache_strategy",	Opt_cache_strategy,
		     erofs_param_cache_strategy),
	{}
};

		if (!*p)
			continue;
static int erofs_fc_parse_param(struct fs_context *fc,
				struct fs_parameter *param)
{
	struct erofs_fs_context *ctx __maybe_unused = fc->fs_private;
	struct fs_parse_result result;
	int opt;

		args[0].to = args[0].from = NULL;
		token = match_token(p, erofs_tokens, args);
	opt = fs_parse(fc, erofs_fs_parameters, param, &result);
	if (opt < 0)
		return opt;

		switch (token) {
#ifdef CONFIG_EROFS_FS_XATTR
	switch (opt) {
	case Opt_user_xattr:
			set_opt(EROFS_SB(sb), XATTR_USER);
			break;
		case Opt_nouser_xattr:
			clear_opt(EROFS_SB(sb), XATTR_USER);
			break;
#ifdef CONFIG_EROFS_FS_XATTR
		if (result.boolean)
			set_opt(ctx, XATTR_USER);
		else
			clear_opt(ctx, XATTR_USER);
#else
		case Opt_user_xattr:
			erofs_info(sb, "user_xattr options not supported");
			break;
		case Opt_nouser_xattr:
			erofs_info(sb, "nouser_xattr options not supported");
			break;
		errorfc(fc, "{,no}user_xattr options not supported");
#endif
#ifdef CONFIG_EROFS_FS_POSIX_ACL
		case Opt_acl:
			set_opt(EROFS_SB(sb), POSIX_ACL);
			break;
		case Opt_noacl:
			clear_opt(EROFS_SB(sb), POSIX_ACL);
		break;
#else
	case Opt_acl:
			erofs_info(sb, "acl options not supported");
			break;
		case Opt_noacl:
			erofs_info(sb, "noacl options not supported");
			break;
#ifdef CONFIG_EROFS_FS_POSIX_ACL
		if (result.boolean)
			set_opt(ctx, POSIX_ACL);
		else
			clear_opt(ctx, POSIX_ACL);
#else
		errorfc(fc, "{,no}acl options not supported");
#endif
		break;
	case Opt_cache_strategy:
			err = erofs_build_cache_strategy(sb, args);
			if (err)
				return err;
#ifdef CONFIG_EROFS_FS_ZIP
		ctx->cache_strategy = result.uint_32;
#else
		errorfc(fc, "compression not supported, cache_strategy ignored");
#endif
		break;
	default:
			erofs_err(sb, "Unrecognized mount option \"%s\" or missing value", p);
			return -EINVAL;
		}
		return -ENOPARAM;
	}
	return 0;
}
@@ -381,10 +337,11 @@ static int erofs_init_managed_cache(struct super_block *sb)
static int erofs_init_managed_cache(struct super_block *sb) { return 0; }
#endif

static int erofs_fill_super(struct super_block *sb, void *data, int silent)
static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
{
	struct inode *inode;
	struct erofs_sb_info *sbi;
	struct erofs_fs_context *ctx = fc->fs_private;
	int err;

	sb->s_magic = EROFS_SUPER_MAGIC;
@@ -408,22 +365,15 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
	sb->s_time_gran = 1;

	sb->s_op = &erofs_sops;

#ifdef CONFIG_EROFS_FS_XATTR
	sb->s_xattr = erofs_xattr_handlers;
#endif
	/* set erofs default mount options */
	erofs_default_options(sbi);

	err = erofs_parse_options(sb, data);
	if (err)
		return err;

	if (test_opt(sbi, POSIX_ACL))
	if (test_opt(ctx, POSIX_ACL))
		sb->s_flags |= SB_POSIXACL;
	else
		sb->s_flags &= ~SB_POSIXACL;

	sbi->ctx = *ctx;

#ifdef CONFIG_EROFS_FS_ZIP
	xa_init(&sbi->managed_pslots);
#endif
@@ -450,15 +400,58 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
	if (err)
		return err;

	erofs_info(sb, "mounted with opts: %s, root inode @ nid %llu.",
		   (char *)data, ROOT_NID(sbi));
	erofs_info(sb, "mounted with root inode @ nid %llu.", ROOT_NID(sbi));
	return 0;
}

static int erofs_fc_get_tree(struct fs_context *fc)
{
	return get_tree_bdev(fc, erofs_fc_fill_super);
}

static int erofs_fc_reconfigure(struct fs_context *fc)
{
	struct super_block *sb = fc->root->d_sb;
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	struct erofs_fs_context *ctx = fc->fs_private;

	DBG_BUGON(!sb_rdonly(sb));

	if (test_opt(ctx, POSIX_ACL))
		fc->sb_flags |= SB_POSIXACL;
	else
		fc->sb_flags &= ~SB_POSIXACL;

	sbi->ctx = *ctx;

	fc->sb_flags |= SB_RDONLY;
	return 0;
}

static struct dentry *erofs_mount(struct file_system_type *fs_type, int flags,
				  const char *dev_name, void *data)
static void erofs_fc_free(struct fs_context *fc)
{
	kfree(fc->fs_private);
}

static const struct fs_context_operations erofs_context_ops = {
	.parse_param	= erofs_fc_parse_param,
	.get_tree       = erofs_fc_get_tree,
	.reconfigure    = erofs_fc_reconfigure,
	.free		= erofs_fc_free,
};

static int erofs_init_fs_context(struct fs_context *fc)
{
	return mount_bdev(fs_type, flags, dev_name, data, erofs_fill_super);
	fc->fs_private = kzalloc(sizeof(struct erofs_fs_context), GFP_KERNEL);
	if (!fc->fs_private)
		return -ENOMEM;

	/* set default mount options */
	erofs_default_options(fc->fs_private);

	fc->ops = &erofs_context_ops;

	return 0;
}

/*
@@ -497,7 +490,7 @@ static void erofs_put_super(struct super_block *sb)
static struct file_system_type erofs_fs_type = {
	.owner          = THIS_MODULE,
	.name           = "erofs",
	.mount          = erofs_mount,
	.init_fs_context = erofs_init_fs_context,
	.kill_sb        = erofs_kill_sb,
	.fs_flags       = FS_REQUIRES_DEV,
};
@@ -578,61 +571,37 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
static int erofs_show_options(struct seq_file *seq, struct dentry *root)
{
	struct erofs_sb_info *sbi __maybe_unused = EROFS_SB(root->d_sb);
	struct erofs_fs_context *ctx __maybe_unused = &sbi->ctx;

#ifdef CONFIG_EROFS_FS_XATTR
	if (test_opt(sbi, XATTR_USER))
	if (test_opt(ctx, XATTR_USER))
		seq_puts(seq, ",user_xattr");
	else
		seq_puts(seq, ",nouser_xattr");
#endif
#ifdef CONFIG_EROFS_FS_POSIX_ACL
	if (test_opt(sbi, POSIX_ACL))
	if (test_opt(ctx, POSIX_ACL))
		seq_puts(seq, ",acl");
	else
		seq_puts(seq, ",noacl");
#endif
#ifdef CONFIG_EROFS_FS_ZIP
	if (sbi->cache_strategy == EROFS_ZIP_CACHE_DISABLED) {
	if (ctx->cache_strategy == EROFS_ZIP_CACHE_DISABLED)
		seq_puts(seq, ",cache_strategy=disabled");
	} else if (sbi->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) {
	else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAHEAD)
		seq_puts(seq, ",cache_strategy=readahead");
	} else if (sbi->cache_strategy == EROFS_ZIP_CACHE_READAROUND) {
	else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAROUND)
		seq_puts(seq, ",cache_strategy=readaround");
	}
#endif
	return 0;
}

static int erofs_remount(struct super_block *sb, int *flags, char *data)
{
	struct erofs_sb_info *sbi = EROFS_SB(sb);
	unsigned int org_mnt_opt = sbi->mount_opt;
	int err;

	DBG_BUGON(!sb_rdonly(sb));
	err = erofs_parse_options(sb, data);
	if (err)
		goto out;

	if (test_opt(sbi, POSIX_ACL))
		sb->s_flags |= SB_POSIXACL;
	else
		sb->s_flags &= ~SB_POSIXACL;

	*flags |= SB_RDONLY;
	return 0;
out:
	sbi->mount_opt = org_mnt_opt;
	return err;
}

const struct super_operations erofs_sops = {
	.put_super = erofs_put_super,
	.alloc_inode = erofs_alloc_inode,
	.free_inode = erofs_free_inode,
	.statfs = erofs_statfs,
	.show_options = erofs_show_options,
	.remount_fs = erofs_remount,
};

module_init(erofs_module_init);
Loading