All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] erofs: convert to use the new mount fs_context api
@ 2020-01-02  9:25 ` Chao Yu
  0 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2020-01-02  9:25 UTC (permalink / raw)
  To: viro; +Cc: dhowells, gaoxiang25, linux-erofs, linux-kernel, Chao Yu

Convert the erofs to use new internal mount API as the old one will
be obsoleted and removed.  This allows greater flexibility in
communication of mount parameters between userspace, the VFS and the
filesystem.

See Documentation/filesystems/mount_api.txt for more information.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
---
v3:
- if acl or xattr feature is not supported in erofs, change error msg
a bit to indicate {,no}acl or {,no}user_xattr options are not supported.

 fs/erofs/internal.h |   2 +-
 fs/erofs/super.c    | 233 +++++++++++++++++++-------------------------
 2 files changed, 101 insertions(+), 134 deletions(-)

diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 1ed5beff7d11..a5fac25db6af 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -102,13 +102,13 @@ struct erofs_sb_info {
 #define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
 #define test_opt(sbi, option)	((sbi)->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 */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 057e6d7b5b7f..388e6b34c736 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -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,41 +194,6 @@ static int erofs_read_superblock(struct super_block *sb)
 	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)
 {
@@ -251,73 +218,61 @@ 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_sb_info *sbi __maybe_unused = fc->s_fs_info;
+	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) {
+	switch (opt) {
+	case Opt_user_xattr:
 #ifdef CONFIG_EROFS_FS_XATTR
-		case Opt_user_xattr:
-			set_opt(EROFS_SB(sb), XATTR_USER);
-			break;
-		case Opt_nouser_xattr:
-			clear_opt(EROFS_SB(sb), XATTR_USER);
-			break;
+		if (result.boolean)
+			set_opt(sbi, XATTR_USER);
+		else
+			clear_opt(sbi, 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
+		break;
+	case Opt_acl:
 #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;
+		if (result.boolean)
+			set_opt(sbi, POSIX_ACL);
+		else
+			clear_opt(sbi, POSIX_ACL);
+#else
+		errorfc(fc, "{,no}acl options not supported");
+#endif
+		break;
+	case Opt_cache_strategy:
+#ifdef CONFIG_EROFS_FS_ZIP
+		sbi->cache_strategy = result.uint_32;
 #else
-		case Opt_acl:
-			erofs_info(sb, "acl options not supported");
-			break;
-		case Opt_noacl:
-			erofs_info(sb, "noacl options not supported");
-			break;
+		errorfc(fc, "compression not supported, cache_strategy ignored");
 #endif
-		case Opt_cache_strategy:
-			err = erofs_build_cache_strategy(sb, args);
-			if (err)
-				return err;
-			break;
-		default:
-			erofs_err(sb, "Unrecognized mount option \"%s\" or missing value", p);
-			return -EINVAL;
-		}
+		break;
+	default:
+		return -ENOPARAM;
 	}
 	return 0;
 }
@@ -381,7 +336,7 @@ 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;
@@ -394,11 +349,7 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
 		return -EINVAL;
 	}
 
-	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-	if (!sbi)
-		return -ENOMEM;
-
-	sb->s_fs_info = sbi;
+	sbi = sb->s_fs_info;
 	err = erofs_read_superblock(sb);
 	if (err)
 		return err;
@@ -412,12 +363,6 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
 #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))
 		sb->s_flags |= SB_POSIXACL;
@@ -450,15 +395,61 @@ 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);
+
+	DBG_BUGON(!sb_rdonly(sb));
+
+	if (test_opt(sbi, POSIX_ACL))
+		fc->sb_flags |= SB_POSIXACL;
+	else
+		fc->sb_flags &= ~SB_POSIXACL;
+
+	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)
 {
-	return mount_bdev(fs_type, flags, dev_name, data, erofs_fill_super);
+	/*
+	 * sbi stored in fs_context was cleaned after transferring
+	 * to corresponding superblock on a successful new mount,
+	 * or free it here.
+	 */
+	kfree(fc->s_fs_info);
+}
+
+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)
+{
+	struct erofs_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+
+	if (!sbi)
+		return -ENOMEM;
+
+	/* set default mount options */
+	erofs_default_options(sbi);
+
+	fc->s_fs_info = sbi;
+	fc->ops = &erofs_context_ops;
+	return 0;
 }
 
 /*
@@ -497,7 +488,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,
 };
@@ -603,36 +594,12 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
 	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);
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3] erofs: convert to use the new mount fs_context api
@ 2020-01-02  9:25 ` Chao Yu
  0 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2020-01-02  9:25 UTC (permalink / raw)
  To: viro; +Cc: dhowells, linux-erofs, linux-kernel

Convert the erofs to use new internal mount API as the old one will
be obsoleted and removed.  This allows greater flexibility in
communication of mount parameters between userspace, the VFS and the
filesystem.

See Documentation/filesystems/mount_api.txt for more information.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
---
v3:
- if acl or xattr feature is not supported in erofs, change error msg
a bit to indicate {,no}acl or {,no}user_xattr options are not supported.

 fs/erofs/internal.h |   2 +-
 fs/erofs/super.c    | 233 +++++++++++++++++++-------------------------
 2 files changed, 101 insertions(+), 134 deletions(-)

diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 1ed5beff7d11..a5fac25db6af 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -102,13 +102,13 @@ struct erofs_sb_info {
 #define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
 #define test_opt(sbi, option)	((sbi)->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 */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 057e6d7b5b7f..388e6b34c736 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -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,41 +194,6 @@ static int erofs_read_superblock(struct super_block *sb)
 	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)
 {
@@ -251,73 +218,61 @@ 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_sb_info *sbi __maybe_unused = fc->s_fs_info;
+	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) {
+	switch (opt) {
+	case Opt_user_xattr:
 #ifdef CONFIG_EROFS_FS_XATTR
-		case Opt_user_xattr:
-			set_opt(EROFS_SB(sb), XATTR_USER);
-			break;
-		case Opt_nouser_xattr:
-			clear_opt(EROFS_SB(sb), XATTR_USER);
-			break;
+		if (result.boolean)
+			set_opt(sbi, XATTR_USER);
+		else
+			clear_opt(sbi, 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
+		break;
+	case Opt_acl:
 #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;
+		if (result.boolean)
+			set_opt(sbi, POSIX_ACL);
+		else
+			clear_opt(sbi, POSIX_ACL);
+#else
+		errorfc(fc, "{,no}acl options not supported");
+#endif
+		break;
+	case Opt_cache_strategy:
+#ifdef CONFIG_EROFS_FS_ZIP
+		sbi->cache_strategy = result.uint_32;
 #else
-		case Opt_acl:
-			erofs_info(sb, "acl options not supported");
-			break;
-		case Opt_noacl:
-			erofs_info(sb, "noacl options not supported");
-			break;
+		errorfc(fc, "compression not supported, cache_strategy ignored");
 #endif
-		case Opt_cache_strategy:
-			err = erofs_build_cache_strategy(sb, args);
-			if (err)
-				return err;
-			break;
-		default:
-			erofs_err(sb, "Unrecognized mount option \"%s\" or missing value", p);
-			return -EINVAL;
-		}
+		break;
+	default:
+		return -ENOPARAM;
 	}
 	return 0;
 }
@@ -381,7 +336,7 @@ 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;
@@ -394,11 +349,7 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
 		return -EINVAL;
 	}
 
-	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-	if (!sbi)
-		return -ENOMEM;
-
-	sb->s_fs_info = sbi;
+	sbi = sb->s_fs_info;
 	err = erofs_read_superblock(sb);
 	if (err)
 		return err;
@@ -412,12 +363,6 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
 #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))
 		sb->s_flags |= SB_POSIXACL;
@@ -450,15 +395,61 @@ 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);
+
+	DBG_BUGON(!sb_rdonly(sb));
+
+	if (test_opt(sbi, POSIX_ACL))
+		fc->sb_flags |= SB_POSIXACL;
+	else
+		fc->sb_flags &= ~SB_POSIXACL;
+
+	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)
 {
-	return mount_bdev(fs_type, flags, dev_name, data, erofs_fill_super);
+	/*
+	 * sbi stored in fs_context was cleaned after transferring
+	 * to corresponding superblock on a successful new mount,
+	 * or free it here.
+	 */
+	kfree(fc->s_fs_info);
+}
+
+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)
+{
+	struct erofs_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+
+	if (!sbi)
+		return -ENOMEM;
+
+	/* set default mount options */
+	erofs_default_options(sbi);
+
+	fc->s_fs_info = sbi;
+	fc->ops = &erofs_context_ops;
+	return 0;
 }
 
 /*
@@ -497,7 +488,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,
 };
@@ -603,36 +594,12 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
 	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);
-- 
2.18.0.rc1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: convert to use the new mount fs_context api
  2020-01-02  9:25 ` Chao Yu
  (?)
@ 2020-01-03 23:57 ` kbuild test robot
  -1 siblings, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2020-01-03 23:57 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3715 bytes --]

Hi Chao,

I love your patch! Yet something to improve:

[auto build test ERROR on xiang-erofs/dev-test]
[also build test ERROR on v5.5-rc4 next-20191219]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Chao-Yu/erofs-convert-to-use-the-new-mount-fs_context-api/20200104-040405
base:   https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git dev-test
config: x86_64-randconfig-s0-20200104 (attached as .config)
compiler: gcc-7 (Debian 7.5.0-3) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   fs/erofs/super.c:231:34: error: macro "fsparam_enum" passed 3 arguments, but takes just 2
           erofs_param_cache_strategy),
                                     ^
   fs/erofs/super.c:230:2: error: 'fsparam_enum' undeclared here (not in a function); did you mean 'fs_param_is_enum'?
     fsparam_enum("cache_strategy", Opt_cache_strategy,
     ^~~~~~~~~~~~
     fs_param_is_enum
   fs/erofs/super.c: In function 'erofs_fc_parse_param':
   fs/erofs/super.c:242:21: error: passing argument 2 of 'fs_parse' from incompatible pointer type [-Werror=incompatible-pointer-types]
     opt = fs_parse(fc, erofs_fs_parameters, param, &result);
                        ^~~~~~~~~~~~~~~~~~~
   In file included from fs/erofs/super.c:14:0:
   include/linux/fs_parser.h:84:12: note: expected 'const struct fs_parameter_description *' but argument is of type 'const struct fs_parameter_spec *'
    extern int fs_parse(struct fs_context *fc,
               ^~~~~~~~
>> fs/erofs/super.c:254:3: error: implicit declaration of function 'errorfc'; did you mean 'errorf'? [-Werror=implicit-function-declaration]
      errorfc(fc, "{,no}user_xattr options not supported");
      ^~~~~~~
      errorf
   cc1: some warnings being treated as errors

vim +254 fs/erofs/super.c

   234	
   235	static int erofs_fc_parse_param(struct fs_context *fc,
   236					struct fs_parameter *param)
   237	{
   238		struct erofs_sb_info *sbi __maybe_unused = fc->s_fs_info;
   239		struct fs_parse_result result;
   240		int opt;
   241	
 > 242		opt = fs_parse(fc, erofs_fs_parameters, param, &result);
   243		if (opt < 0)
   244			return opt;
   245	
   246		switch (opt) {
   247		case Opt_user_xattr:
   248	#ifdef CONFIG_EROFS_FS_XATTR
   249			if (result.boolean)
   250				set_opt(sbi, XATTR_USER);
   251			else
   252				clear_opt(sbi, XATTR_USER);
   253	#else
 > 254			errorfc(fc, "{,no}user_xattr options not supported");
   255	#endif
   256			break;
   257		case Opt_acl:
   258	#ifdef CONFIG_EROFS_FS_POSIX_ACL
   259			if (result.boolean)
   260				set_opt(sbi, POSIX_ACL);
   261			else
   262				clear_opt(sbi, POSIX_ACL);
   263	#else
   264			errorfc(fc, "{,no}acl options not supported");
   265	#endif
   266			break;
   267		case Opt_cache_strategy:
   268	#ifdef CONFIG_EROFS_FS_ZIP
   269			sbi->cache_strategy = result.uint_32;
   270	#else
   271			errorfc(fc, "compression not supported, cache_strategy ignored");
   272	#endif
   273			break;
   274		default:
   275			return -ENOPARAM;
   276		}
   277		return 0;
   278	}
   279	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org Intel Corporation

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 37850 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: convert to use the new mount fs_context api
  2020-01-02  9:25 ` Chao Yu
  (?)
  (?)
@ 2020-01-04  1:29 ` kbuild test robot
  -1 siblings, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2020-01-04  1:29 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3962 bytes --]

Hi Chao,

I love your patch! Yet something to improve:

[auto build test ERROR on xiang-erofs/dev-test]
[also build test ERROR on v5.5-rc4 next-20191219]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Chao-Yu/erofs-convert-to-use-the-new-mount-fs_context-api/20200104-040405
base:   https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git dev-test
config: c6x-allyesconfig (attached as .config)
compiler: c6x-elf-gcc (GCC) 7.5.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.5.0 make.cross ARCH=c6x 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> fs///erofs/super.c:231:34: error: macro "fsparam_enum" passed 3 arguments, but takes just 2
           erofs_param_cache_strategy),
                                     ^
>> fs///erofs/super.c:230:2: error: 'fsparam_enum' undeclared here (not in a function); did you mean 'fs_param_is_enum'?
     fsparam_enum("cache_strategy", Opt_cache_strategy,
     ^~~~~~~~~~~~
     fs_param_is_enum
   fs///erofs/super.c: In function 'erofs_fc_parse_param':
>> fs///erofs/super.c:242:21: error: passing argument 2 of 'fs_parse' from incompatible pointer type [-Werror=incompatible-pointer-types]
     opt = fs_parse(fc, erofs_fs_parameters, param, &result);
                        ^~~~~~~~~~~~~~~~~~~
   In file included from fs///erofs/super.c:14:0:
   include/linux/fs_parser.h:84:12: note: expected 'const struct fs_parameter_description *' but argument is of type 'const struct fs_parameter_spec *'
    extern int fs_parse(struct fs_context *fc,
               ^~~~~~~~
   cc1: some warnings being treated as errors

vim +/fsparam_enum +231 fs///erofs/super.c

   226	
   227	static const struct fs_parameter_spec erofs_fs_parameters[] = {
   228		fsparam_flag_no("user_xattr",	Opt_user_xattr),
   229		fsparam_flag_no("acl",		Opt_acl),
 > 230		fsparam_enum("cache_strategy",	Opt_cache_strategy,
 > 231			     erofs_param_cache_strategy),
   232		{}
   233	};
   234	
   235	static int erofs_fc_parse_param(struct fs_context *fc,
   236					struct fs_parameter *param)
   237	{
   238		struct erofs_sb_info *sbi __maybe_unused = fc->s_fs_info;
   239		struct fs_parse_result result;
   240		int opt;
   241	
 > 242		opt = fs_parse(fc, erofs_fs_parameters, param, &result);
   243		if (opt < 0)
   244			return opt;
   245	
   246		switch (opt) {
   247		case Opt_user_xattr:
   248	#ifdef CONFIG_EROFS_FS_XATTR
   249			if (result.boolean)
   250				set_opt(sbi, XATTR_USER);
   251			else
   252				clear_opt(sbi, XATTR_USER);
   253	#else
   254			errorfc(fc, "{,no}user_xattr options not supported");
   255	#endif
   256			break;
   257		case Opt_acl:
   258	#ifdef CONFIG_EROFS_FS_POSIX_ACL
   259			if (result.boolean)
   260				set_opt(sbi, POSIX_ACL);
   261			else
   262				clear_opt(sbi, POSIX_ACL);
   263	#else
   264			errorfc(fc, "{,no}acl options not supported");
   265	#endif
   266			break;
   267		case Opt_cache_strategy:
   268	#ifdef CONFIG_EROFS_FS_ZIP
   269			sbi->cache_strategy = result.uint_32;
   270	#else
   271			errorfc(fc, "compression not supported, cache_strategy ignored");
   272	#endif
   273			break;
   274		default:
   275			return -ENOPARAM;
   276		}
   277		return 0;
   278	}
   279	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org Intel Corporation

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 50690 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: convert to use the new mount fs_context api
  2020-01-02  9:25 ` Chao Yu
@ 2020-01-28 17:23   ` Gao Xiang via Linux-erofs
  -1 siblings, 0 replies; 6+ messages in thread
From: Gao Xiang @ 2020-01-28 17:23 UTC (permalink / raw)
  To: Al Viro; +Cc: Chao Yu, dhowells, linux-erofs, linux-kernel

Hello Al,

Would you mind consider taking this patch into your working branch as well?
And we could avoid legacy mount API since 5.6...

Thank you very much,
Gao Xiang

On Thu, Jan 02, 2020 at 05:25:56PM +0800, Chao Yu wrote:
> Convert the erofs to use new internal mount API as the old one will
> be obsoleted and removed.  This allows greater flexibility in
> communication of mount parameters between userspace, the VFS and the
> filesystem.
> 
> See Documentation/filesystems/mount_api.txt for more information.
> 
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
> ---
> v3:
> - if acl or xattr feature is not supported in erofs, change error msg
> a bit to indicate {,no}acl or {,no}user_xattr options are not supported.
> 
>  fs/erofs/internal.h |   2 +-
>  fs/erofs/super.c    | 233 +++++++++++++++++++-------------------------
>  2 files changed, 101 insertions(+), 134 deletions(-)
> 
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index 1ed5beff7d11..a5fac25db6af 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -102,13 +102,13 @@ struct erofs_sb_info {
>  #define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
>  #define test_opt(sbi, option)	((sbi)->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 */
> diff --git a/fs/erofs/super.c b/fs/erofs/super.c
> index 057e6d7b5b7f..388e6b34c736 100644
> --- a/fs/erofs/super.c
> +++ b/fs/erofs/super.c
> @@ -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,41 +194,6 @@ static int erofs_read_superblock(struct super_block *sb)
>  	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)
>  {
> @@ -251,73 +218,61 @@ 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_sb_info *sbi __maybe_unused = fc->s_fs_info;
> +	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) {
> +	switch (opt) {
> +	case Opt_user_xattr:
>  #ifdef CONFIG_EROFS_FS_XATTR
> -		case Opt_user_xattr:
> -			set_opt(EROFS_SB(sb), XATTR_USER);
> -			break;
> -		case Opt_nouser_xattr:
> -			clear_opt(EROFS_SB(sb), XATTR_USER);
> -			break;
> +		if (result.boolean)
> +			set_opt(sbi, XATTR_USER);
> +		else
> +			clear_opt(sbi, 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
> +		break;
> +	case Opt_acl:
>  #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;
> +		if (result.boolean)
> +			set_opt(sbi, POSIX_ACL);
> +		else
> +			clear_opt(sbi, POSIX_ACL);
> +#else
> +		errorfc(fc, "{,no}acl options not supported");
> +#endif
> +		break;
> +	case Opt_cache_strategy:
> +#ifdef CONFIG_EROFS_FS_ZIP
> +		sbi->cache_strategy = result.uint_32;
>  #else
> -		case Opt_acl:
> -			erofs_info(sb, "acl options not supported");
> -			break;
> -		case Opt_noacl:
> -			erofs_info(sb, "noacl options not supported");
> -			break;
> +		errorfc(fc, "compression not supported, cache_strategy ignored");
>  #endif
> -		case Opt_cache_strategy:
> -			err = erofs_build_cache_strategy(sb, args);
> -			if (err)
> -				return err;
> -			break;
> -		default:
> -			erofs_err(sb, "Unrecognized mount option \"%s\" or missing value", p);
> -			return -EINVAL;
> -		}
> +		break;
> +	default:
> +		return -ENOPARAM;
>  	}
>  	return 0;
>  }
> @@ -381,7 +336,7 @@ 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;
> @@ -394,11 +349,7 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
>  		return -EINVAL;
>  	}
>  
> -	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
> -	if (!sbi)
> -		return -ENOMEM;
> -
> -	sb->s_fs_info = sbi;
> +	sbi = sb->s_fs_info;
>  	err = erofs_read_superblock(sb);
>  	if (err)
>  		return err;
> @@ -412,12 +363,6 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
>  #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))
>  		sb->s_flags |= SB_POSIXACL;
> @@ -450,15 +395,61 @@ 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);
> +
> +	DBG_BUGON(!sb_rdonly(sb));
> +
> +	if (test_opt(sbi, POSIX_ACL))
> +		fc->sb_flags |= SB_POSIXACL;
> +	else
> +		fc->sb_flags &= ~SB_POSIXACL;
> +
> +	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)
>  {
> -	return mount_bdev(fs_type, flags, dev_name, data, erofs_fill_super);
> +	/*
> +	 * sbi stored in fs_context was cleaned after transferring
> +	 * to corresponding superblock on a successful new mount,
> +	 * or free it here.
> +	 */
> +	kfree(fc->s_fs_info);
> +}
> +
> +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)
> +{
> +	struct erofs_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
> +
> +	if (!sbi)
> +		return -ENOMEM;
> +
> +	/* set default mount options */
> +	erofs_default_options(sbi);
> +
> +	fc->s_fs_info = sbi;
> +	fc->ops = &erofs_context_ops;
> +	return 0;
>  }
>  
>  /*
> @@ -497,7 +488,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,
>  };
> @@ -603,36 +594,12 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
>  	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);
> -- 
> 2.18.0.rc1
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] erofs: convert to use the new mount fs_context api
@ 2020-01-28 17:23   ` Gao Xiang via Linux-erofs
  0 siblings, 0 replies; 6+ messages in thread
From: Gao Xiang via Linux-erofs @ 2020-01-28 17:23 UTC (permalink / raw)
  To: Al Viro; +Cc: dhowells, linux-erofs, linux-kernel

Hello Al,

Would you mind consider taking this patch into your working branch as well?
And we could avoid legacy mount API since 5.6...

Thank you very much,
Gao Xiang

On Thu, Jan 02, 2020 at 05:25:56PM +0800, Chao Yu wrote:
> Convert the erofs to use new internal mount API as the old one will
> be obsoleted and removed.  This allows greater flexibility in
> communication of mount parameters between userspace, the VFS and the
> filesystem.
> 
> See Documentation/filesystems/mount_api.txt for more information.
> 
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
> ---
> v3:
> - if acl or xattr feature is not supported in erofs, change error msg
> a bit to indicate {,no}acl or {,no}user_xattr options are not supported.
> 
>  fs/erofs/internal.h |   2 +-
>  fs/erofs/super.c    | 233 +++++++++++++++++++-------------------------
>  2 files changed, 101 insertions(+), 134 deletions(-)
> 
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index 1ed5beff7d11..a5fac25db6af 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -102,13 +102,13 @@ struct erofs_sb_info {
>  #define set_opt(sbi, option)	((sbi)->mount_opt |= EROFS_MOUNT_##option)
>  #define test_opt(sbi, option)	((sbi)->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 */
> diff --git a/fs/erofs/super.c b/fs/erofs/super.c
> index 057e6d7b5b7f..388e6b34c736 100644
> --- a/fs/erofs/super.c
> +++ b/fs/erofs/super.c
> @@ -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,41 +194,6 @@ static int erofs_read_superblock(struct super_block *sb)
>  	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)
>  {
> @@ -251,73 +218,61 @@ 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_sb_info *sbi __maybe_unused = fc->s_fs_info;
> +	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) {
> +	switch (opt) {
> +	case Opt_user_xattr:
>  #ifdef CONFIG_EROFS_FS_XATTR
> -		case Opt_user_xattr:
> -			set_opt(EROFS_SB(sb), XATTR_USER);
> -			break;
> -		case Opt_nouser_xattr:
> -			clear_opt(EROFS_SB(sb), XATTR_USER);
> -			break;
> +		if (result.boolean)
> +			set_opt(sbi, XATTR_USER);
> +		else
> +			clear_opt(sbi, 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
> +		break;
> +	case Opt_acl:
>  #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;
> +		if (result.boolean)
> +			set_opt(sbi, POSIX_ACL);
> +		else
> +			clear_opt(sbi, POSIX_ACL);
> +#else
> +		errorfc(fc, "{,no}acl options not supported");
> +#endif
> +		break;
> +	case Opt_cache_strategy:
> +#ifdef CONFIG_EROFS_FS_ZIP
> +		sbi->cache_strategy = result.uint_32;
>  #else
> -		case Opt_acl:
> -			erofs_info(sb, "acl options not supported");
> -			break;
> -		case Opt_noacl:
> -			erofs_info(sb, "noacl options not supported");
> -			break;
> +		errorfc(fc, "compression not supported, cache_strategy ignored");
>  #endif
> -		case Opt_cache_strategy:
> -			err = erofs_build_cache_strategy(sb, args);
> -			if (err)
> -				return err;
> -			break;
> -		default:
> -			erofs_err(sb, "Unrecognized mount option \"%s\" or missing value", p);
> -			return -EINVAL;
> -		}
> +		break;
> +	default:
> +		return -ENOPARAM;
>  	}
>  	return 0;
>  }
> @@ -381,7 +336,7 @@ 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;
> @@ -394,11 +349,7 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
>  		return -EINVAL;
>  	}
>  
> -	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
> -	if (!sbi)
> -		return -ENOMEM;
> -
> -	sb->s_fs_info = sbi;
> +	sbi = sb->s_fs_info;
>  	err = erofs_read_superblock(sb);
>  	if (err)
>  		return err;
> @@ -412,12 +363,6 @@ static int erofs_fill_super(struct super_block *sb, void *data, int silent)
>  #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))
>  		sb->s_flags |= SB_POSIXACL;
> @@ -450,15 +395,61 @@ 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);
> +
> +	DBG_BUGON(!sb_rdonly(sb));
> +
> +	if (test_opt(sbi, POSIX_ACL))
> +		fc->sb_flags |= SB_POSIXACL;
> +	else
> +		fc->sb_flags &= ~SB_POSIXACL;
> +
> +	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)
>  {
> -	return mount_bdev(fs_type, flags, dev_name, data, erofs_fill_super);
> +	/*
> +	 * sbi stored in fs_context was cleaned after transferring
> +	 * to corresponding superblock on a successful new mount,
> +	 * or free it here.
> +	 */
> +	kfree(fc->s_fs_info);
> +}
> +
> +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)
> +{
> +	struct erofs_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
> +
> +	if (!sbi)
> +		return -ENOMEM;
> +
> +	/* set default mount options */
> +	erofs_default_options(sbi);
> +
> +	fc->s_fs_info = sbi;
> +	fc->ops = &erofs_context_ops;
> +	return 0;
>  }
>  
>  /*
> @@ -497,7 +488,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,
>  };
> @@ -603,36 +594,12 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
>  	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);
> -- 
> 2.18.0.rc1
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-01-28 17:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-02  9:25 [PATCH v3] erofs: convert to use the new mount fs_context api Chao Yu
2020-01-02  9:25 ` Chao Yu
2020-01-03 23:57 ` kbuild test robot
2020-01-04  1:29 ` kbuild test robot
2020-01-28 17:23 ` Gao Xiang
2020-01-28 17:23   ` Gao Xiang via Linux-erofs

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.