Commit 567e629f authored by Bill O'Donnell's avatar Bill O'Donnell Committed by Damien Le Moal
Browse files

zonefs: convert zonefs to use the new mount api

Convert the zonefs filesystem to use the new mount API.
Tested using the zonefs test suite from:
https://github.com/damien-lemoal/zonefs-tools



Signed-off-by: default avatarBill O'Donnell <bodonnel@redhat.com>
Reviewed-by: default avatarIan Kent <raven@themaw.net>
Signed-off-by: default avatarDamien Le Moal <dlemoal@kernel.org>
parent 841c3516
Loading
Loading
Loading
Loading
+95 −72
Original line number Diff line number Diff line
@@ -15,12 +15,13 @@
#include <linux/writeback.h>
#include <linux/quotaops.h>
#include <linux/seq_file.h>
#include <linux/parser.h>
#include <linux/uio.h>
#include <linux/mman.h>
#include <linux/sched/mm.h>
#include <linux/crc32.h>
#include <linux/task_io_accounting_ops.h>
#include <linux/fs_parser.h>
#include <linux/fs_context.h>

#include "zonefs.h"

@@ -460,59 +461,48 @@ static int zonefs_statfs(struct dentry *dentry, struct kstatfs *buf)
}

enum {
	Opt_errors_ro, Opt_errors_zro, Opt_errors_zol, Opt_errors_repair,
	Opt_explicit_open, Opt_err,
	Opt_errors, Opt_explicit_open,
};

static const match_table_t tokens = {
	{ Opt_errors_ro,	"errors=remount-ro"},
	{ Opt_errors_zro,	"errors=zone-ro"},
	{ Opt_errors_zol,	"errors=zone-offline"},
	{ Opt_errors_repair,	"errors=repair"},
	{ Opt_explicit_open,	"explicit-open" },
	{ Opt_err,		NULL}
struct zonefs_context {
	unsigned long s_mount_opts;
};

static int zonefs_parse_options(struct super_block *sb, char *options)
{
	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
	substring_t args[MAX_OPT_ARGS];
	char *p;

	if (!options)
		return 0;

	while ((p = strsep(&options, ",")) != NULL) {
		int token;
static const struct constant_table zonefs_param_errors[] = {
	{"remount-ro",		ZONEFS_MNTOPT_ERRORS_RO},
	{"zone-ro",		ZONEFS_MNTOPT_ERRORS_ZRO},
	{"zone-offline",	ZONEFS_MNTOPT_ERRORS_ZOL},
	{"repair", 		ZONEFS_MNTOPT_ERRORS_REPAIR},
	{}
};

		if (!*p)
			continue;
static const struct fs_parameter_spec zonefs_param_spec[] = {
	fsparam_enum	("errors",		Opt_errors, zonefs_param_errors),
	fsparam_flag	("explicit-open",	Opt_explicit_open),
	{}
};

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_errors_ro:
			sbi->s_mount_opts &= ~ZONEFS_MNTOPT_ERRORS_MASK;
			sbi->s_mount_opts |= ZONEFS_MNTOPT_ERRORS_RO;
			break;
		case Opt_errors_zro:
			sbi->s_mount_opts &= ~ZONEFS_MNTOPT_ERRORS_MASK;
			sbi->s_mount_opts |= ZONEFS_MNTOPT_ERRORS_ZRO;
			break;
		case Opt_errors_zol:
			sbi->s_mount_opts &= ~ZONEFS_MNTOPT_ERRORS_MASK;
			sbi->s_mount_opts |= ZONEFS_MNTOPT_ERRORS_ZOL;
			break;
		case Opt_errors_repair:
			sbi->s_mount_opts &= ~ZONEFS_MNTOPT_ERRORS_MASK;
			sbi->s_mount_opts |= ZONEFS_MNTOPT_ERRORS_REPAIR;
static int zonefs_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
	struct zonefs_context *ctx = fc->fs_private;
	struct fs_parse_result result;
	int opt;

	opt = fs_parse(fc, zonefs_param_spec, param, &result);
	if (opt < 0)
		return opt;

	switch (opt) {
	case Opt_errors:
		ctx->s_mount_opts &= ~ZONEFS_MNTOPT_ERRORS_MASK;
		ctx->s_mount_opts |= result.uint_32;
		break;
	case Opt_explicit_open:
			sbi->s_mount_opts |= ZONEFS_MNTOPT_EXPLICIT_OPEN;
		ctx->s_mount_opts |= ZONEFS_MNTOPT_EXPLICIT_OPEN;
		break;
	default:
		return -EINVAL;
	}
	}

	return 0;
}
@@ -533,13 +523,6 @@ static int zonefs_show_options(struct seq_file *seq, struct dentry *root)
	return 0;
}

static int zonefs_remount(struct super_block *sb, int *flags, char *data)
{
	sync_filesystem(sb);

	return zonefs_parse_options(sb, data);
}

static int zonefs_inode_setattr(struct mnt_idmap *idmap,
				struct dentry *dentry, struct iattr *iattr)
{
@@ -1195,7 +1178,6 @@ static const struct super_operations zonefs_sops = {
	.alloc_inode	= zonefs_alloc_inode,
	.free_inode	= zonefs_free_inode,
	.statfs		= zonefs_statfs,
	.remount_fs	= zonefs_remount,
	.show_options	= zonefs_show_options,
};

@@ -1240,9 +1222,10 @@ static void zonefs_release_zgroup_inodes(struct super_block *sb)
 * sub-directories and files according to the device zone configuration and
 * format options.
 */
static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
static int zonefs_fill_super(struct super_block *sb, struct fs_context *fc)
{
	struct zonefs_sb_info *sbi;
	struct zonefs_context *ctx = fc->fs_private;
	struct inode *inode;
	enum zonefs_ztype ztype;
	int ret;
@@ -1279,7 +1262,7 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
	sbi->s_uid = GLOBAL_ROOT_UID;
	sbi->s_gid = GLOBAL_ROOT_GID;
	sbi->s_perm = 0640;
	sbi->s_mount_opts = ZONEFS_MNTOPT_ERRORS_RO;
	sbi->s_mount_opts = ctx->s_mount_opts;

	atomic_set(&sbi->s_wro_seq_files, 0);
	sbi->s_max_wro_seq_files = bdev_max_open_zones(sb->s_bdev);
@@ -1290,10 +1273,6 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
	if (ret)
		return ret;

	ret = zonefs_parse_options(sb, data);
	if (ret)
		return ret;

	zonefs_info(sb, "Mounting %u zones", bdev_nr_zones(sb->s_bdev));

	if (!sbi->s_max_wro_seq_files &&
@@ -1354,12 +1333,6 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent)
	return ret;
}

static struct dentry *zonefs_mount(struct file_system_type *fs_type,
				   int flags, const char *dev_name, void *data)
{
	return mount_bdev(fs_type, flags, dev_name, data, zonefs_fill_super);
}

static void zonefs_kill_super(struct super_block *sb)
{
	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
@@ -1374,15 +1347,65 @@ static void zonefs_kill_super(struct super_block *sb)
	kfree(sbi);
}

static void zonefs_free_fc(struct fs_context *fc)
{
	struct zonefs_context *ctx = fc->fs_private;

	kfree(ctx);
}

static int zonefs_get_tree(struct fs_context *fc)
{
	return get_tree_bdev(fc, zonefs_fill_super);
}

static int zonefs_reconfigure(struct fs_context *fc)
{
	struct zonefs_context *ctx = fc->fs_private;
	struct super_block *sb = fc->root->d_sb;
	struct zonefs_sb_info *sbi = sb->s_fs_info;

	sync_filesystem(fc->root->d_sb);
	/* Copy new options from ctx into sbi. */
	sbi->s_mount_opts = ctx->s_mount_opts;

	return 0;
}

static const struct fs_context_operations zonefs_context_ops = {
	.parse_param    = zonefs_parse_param,
	.get_tree       = zonefs_get_tree,
	.reconfigure	= zonefs_reconfigure,
	.free           = zonefs_free_fc,
};

/*
 * Set up the filesystem mount context.
 */
static int zonefs_init_fs_context(struct fs_context *fc)
{
	struct zonefs_context *ctx;

	ctx = kzalloc(sizeof(struct zonefs_context), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;
	ctx->s_mount_opts = ZONEFS_MNTOPT_ERRORS_RO;
	fc->ops = &zonefs_context_ops;
	fc->fs_private = ctx;

	return 0;
}

/*
 * File system definition and registration.
 */
static struct file_system_type zonefs_type = {
	.owner			= THIS_MODULE,
	.name			= "zonefs",
	.mount		= zonefs_mount,
	.kill_sb		= zonefs_kill_super,
	.fs_flags		= FS_REQUIRES_DEV,
	.init_fs_context	= zonefs_init_fs_context,
	.parameters		= zonefs_param_spec,
};

static int __init zonefs_init_inodecache(void)