linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/15] xfs: mount API patch series
@ 2019-08-23  0:59 Ian Kent
  2019-08-23  0:59 ` [PATCH v2 01/15] vfs: Create fs_context-aware mount_bdev() replacement Ian Kent
                   ` (15 more replies)
  0 siblings, 16 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

This patch series adds support to xfs for the new kernel mount API
as described in the LWN article at https://lwn.net/Articles/780267/.

In the article there's a lengthy description of the reasons for
adopting the API and problems expected to be resolved by using it.

The series has been applied to the repository located at
git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git, and built, and
the xfstests suite run against it.

I didn't see any failures that look like they are related to mounting.

Changes from the initial posting of the series:
- changed .name to uppercase in fs_parameter_description to ensure
  consistent error log messages between the vfs parser and the xfs
  parameter parser.
- clearify comment above xfs_parse_param() about when possibly
  allocated mp->m_logname or mp->m_rtname are freed.
- factor out xfs_remount_rw() and xfs_remount_ro() from  xfs_remount().
- changed xfs_mount_alloc() to not set super block in xfs_mount so it
  can be re-used when switching to the mount-api.
- fixed don't check for NULL when calling kfree() in xfs_fc_free().
- refactored xfs_parseargs() in an attempt to highlight the code
  that actually changes in converting to use the new mount api.
- dropped xfs-mount-api-rename-xfs_fill_super.patch, it didn't seem
  necessary.
- move comment about remount difficulties above xfs_reconfigure()
  and increase line length to try and make the comment managable.
- add patch vfs-Create-fs_context-aware-mount_bdev-replacement.patch
  that adds the vfs_get_block_super() needed by the series.

The patch "vfs: Create fs_context-aware mount_bdev() replacement" is
currently included in linux-next so there will be conflicts if this
series is merged in the next merge window so please be aware of it.

---

David Howells (1):
      vfs: Create fs_context-aware mount_bdev() replacement

Ian Kent (14):
      xfs: mount-api - add fs parameter description
      xfs: mount-api - refactor suffix_kstrtoint()
      xfs: mount-api - refactor xfs_parseags()
      xfs: mount-api - make xfs_parse_param() take context .parse_param() args
      xfs: mount-api - move xfs_parseargs() validation to a helper
      xfs: mount-api - refactor xfs_fs_fill_super()
      xfs: mount-api - add xfs_get_tree()
      xfs: mount-api - add xfs_remount_rw() helper
      xfs: mount-api - add xfs_remount_ro() helper
      xfs: mount api - add xfs_reconfigure()
      xfs: mount-api - add xfs_fc_free()
      xfs: mount-api - dont set sb in xfs_mount_alloc()
      xfs: mount-api - switch to new mount-api
      xfs: mount-api - remove legacy mount functions


 fs/fs_context.c            |    2 
 fs/super.c                 |  111 +++++
 fs/xfs/xfs_super.c         |  949 ++++++++++++++++++++++++--------------------
 include/linux/fs_context.h |    9 
 4 files changed, 631 insertions(+), 440 deletions(-)

--
Ian

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

* [PATCH v2 01/15] vfs: Create fs_context-aware mount_bdev() replacement
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-23  0:59 ` [PATCH v2 02/15] xfs: mount-api - add fs parameter description Ian Kent
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

From: David Howells <dhowells@redhat.com>

Create a function, vfs_get_block_super(), that is fs_context-aware and a
replacement for mount_bdev().  It caches the block device pointer and file
open mode in the fs_context struct so that this information can be passed
into sget_fc()'s test and set functions.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Jens Axboe <axboe@kernel.dk>
cc: linux-block@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/fs_context.c            |    2 +
 fs/super.c                 |  111 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs_context.h |    9 ++++
 3 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/fs/fs_context.c b/fs/fs_context.c
index 103643c68e3f..270ecae32216 100644
--- a/fs/fs_context.c
+++ b/fs/fs_context.c
@@ -501,6 +501,8 @@ void put_fs_context(struct fs_context *fc)
 
 	if (fc->need_free && fc->ops && fc->ops->free)
 		fc->ops->free(fc);
+	if (fc->dev_destructor)
+		fc->dev_destructor(fc);
 
 	security_free_mnt_opts(&fc->security);
 	put_net(fc->net_ns);
diff --git a/fs/super.c b/fs/super.c
index 113c58f19425..95cf8a2d5b25 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1215,6 +1215,110 @@ int get_tree_single(struct fs_context *fc,
 EXPORT_SYMBOL(get_tree_single);
 
 #ifdef CONFIG_BLOCK
+static void fc_bdev_destructor(struct fs_context *fc)
+{
+	if (fc->bdev) {
+		blkdev_put(fc->bdev, fc->bdev_mode);
+		fc->bdev = NULL;
+	}
+}
+
+static int set_bdev_super_fc(struct super_block *s, struct fs_context *fc)
+{
+	s->s_mode = fc->bdev_mode;
+	s->s_bdev = fc->bdev;
+	s->s_dev = s->s_bdev->bd_dev;
+	s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
+	fc->bdev = NULL;
+	return 0;
+}
+
+static int test_bdev_super_fc(struct super_block *s, struct fs_context *fc)
+{
+	return s->s_bdev == fc->bdev;
+}
+
+/**
+ * vfs_get_block_super - Get a superblock based on a single block device
+ * @fc: The filesystem context holding the parameters
+ * @keying: How to distinguish superblocks
+ * @fill_super: Helper to initialise a new superblock
+ */
+int vfs_get_block_super(struct fs_context *fc,
+			int (*fill_super)(struct super_block *,
+					  struct fs_context *))
+{
+	struct block_device *bdev;
+	struct super_block *s;
+	int error = 0;
+
+	fc->bdev_mode = FMODE_READ | FMODE_EXCL;
+	if (!(fc->sb_flags & SB_RDONLY))
+		fc->bdev_mode |= FMODE_WRITE;
+
+	if (!fc->source)
+		return invalf(fc, "No source specified");
+
+	bdev = blkdev_get_by_path(fc->source, fc->bdev_mode, fc->fs_type);
+	if (IS_ERR(bdev)) {
+		errorf(fc, "%s: Can't open blockdev", fc->source);
+		return PTR_ERR(bdev);
+	}
+
+	fc->dev_destructor = fc_bdev_destructor;
+	fc->bdev = bdev;
+
+	/* Once the superblock is inserted into the list by sget_fc(), s_umount
+	 * will protect the lockfs code from trying to start a snapshot while
+	 * we are mounting
+	 */
+	mutex_lock(&bdev->bd_fsfreeze_mutex);
+	if (bdev->bd_fsfreeze_count > 0) {
+		mutex_unlock(&bdev->bd_fsfreeze_mutex);
+		warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev);
+		return -EBUSY;
+	}
+
+	fc->sb_flags |= SB_NOSEC;
+	s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc);
+	mutex_unlock(&bdev->bd_fsfreeze_mutex);
+	if (IS_ERR(s))
+		return PTR_ERR(s);
+
+	if (s->s_root) {
+		/* Don't summarily change the RO/RW state. */
+		if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) {
+			warnf(fc, "%pg: Can't mount, would change RO state", bdev);
+			error = -EBUSY;
+			goto error_sb;
+		}
+
+		/* Leave fc->bdev to fc_bdev_destructor() to clean up to avoid
+		 * locking conflicts.
+		 */
+	} else {
+		snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
+		sb_set_blocksize(s, block_size(bdev));
+		error = fill_super(s, fc);
+		if (error)
+			goto error_sb;
+
+		s->s_flags |= SB_ACTIVE;
+		bdev->bd_super = s;
+	}
+
+	BUG_ON(fc->root);
+	fc->root = dget(s->s_root);
+	return 0;
+
+error_sb:
+	deactivate_locked_super(s);
+	/* Leave fc->bdev to fc_bdev_destructor() to clean up */
+	return error;
+}
+EXPORT_SYMBOL(vfs_get_block_super);
+
+
 static int set_bdev_super(struct super_block *s, void *data)
 {
 	s->s_bdev = data;
@@ -1414,8 +1518,13 @@ int vfs_get_tree(struct fs_context *fc)
 	 * on the superblock.
 	 */
 	error = fc->ops->get_tree(fc);
-	if (error < 0)
+	if (error < 0) {
+		if (fc->dev_destructor) {
+			fc->dev_destructor(fc);
+			fc->dev_destructor = NULL;
+		}
 		return error;
+	}
 
 	if (!fc->root) {
 		pr_err("Filesystem %s get_tree() didn't set fc->root\n",
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h
index 7c6fe3d47fa6..ed5b4349671e 100644
--- a/include/linux/fs_context.h
+++ b/include/linux/fs_context.h
@@ -88,6 +88,9 @@ struct fs_context {
 	struct mutex		uapi_mutex;	/* Userspace access mutex */
 	struct file_system_type	*fs_type;
 	void			*fs_private;	/* The filesystem's context */
+	union {
+		struct block_device *bdev;	/* The backing blockdev (if applicable) */
+	};
 	struct dentry		*root;		/* The root and superblock */
 	struct user_namespace	*user_ns;	/* The user namespace for this mount */
 	struct net		*net_ns;	/* The network namespace for this mount */
@@ -97,6 +100,7 @@ struct fs_context {
 	const char		*subtype;	/* The subtype to set on the superblock */
 	void			*security;	/* Linux S&M options */
 	void			*s_fs_info;	/* Proposed s_fs_info */
+	fmode_t			bdev_mode;	/* File open mode for bdev */
 	unsigned int		sb_flags;	/* Proposed superblock flags (SB_*) */
 	unsigned int		sb_flags_mask;	/* Superblock flags that were changed */
 	unsigned int		s_iflags;	/* OR'd with sb->s_iflags */
@@ -105,6 +109,7 @@ struct fs_context {
 	enum fs_context_phase	phase:8;	/* The phase the context is in */
 	bool			need_free:1;	/* Need to call ops->free() */
 	bool			global:1;	/* Goes into &init_user_ns */
+	void (*dev_destructor)(struct fs_context *fc); /* For block or mtd */
 };
 
 struct fs_context_operations {
@@ -154,6 +159,10 @@ extern int get_tree_single(struct fs_context *fc,
 			 int (*fill_super)(struct super_block *sb,
 					   struct fs_context *fc));
 
+extern int vfs_get_block_super(struct fs_context *fc,
+			       int (*fill_super)(struct super_block *sb,
+						 struct fs_context *fc));
+
 extern const struct file_operations fscontext_fops;
 
 /*


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

* [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
  2019-08-23  0:59 ` [PATCH v2 01/15] vfs: Create fs_context-aware mount_bdev() replacement Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-27 12:39   ` Brian Foster
  2019-08-23  0:59 ` [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint() Ian Kent
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

The new mount-api uses an array of struct fs_parameter_spec for
parameter parsing, create this table populated with the xfs mount
parameters.

The new mount-api table definition is wider than the token based
parameter table and interleaving the option description comments
between each table line is much less readable than adding them to
the end of each table entry. So add the option description comment
to each entry line even though it causes quite a few of the entries
to be longer than 80 characters.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   48 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index f9450235533c..74c88b92ce22 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -38,6 +38,8 @@
 
 #include <linux/magic.h>
 #include <linux/parser.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 
 static const struct super_operations xfs_super_operations;
 struct bio_set xfs_ioend_bioset;
@@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-level xfs sysfs dir */
 static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs attrs */
 #endif
 
-/*
- * Table driven mount option parser.
- */
 enum {
 	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
 	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
@@ -109,6 +108,49 @@ static const match_table_t tokens = {
 	{Opt_err,	NULL},
 };
 
+static const struct fs_parameter_spec xfs_param_specs[] = {
+ fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS log buffers */
+ fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS log buffers */
+ fsparam_string ("logdev",     Opt_logdev),    /* log device */
+ fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O device */
+ fsparam_u32	("biosize",    Opt_biosize),   /* log2 of preferred buffered io size */
+ fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs compatible mount */
+ fsparam_flag	("noalign",    Opt_noalign),   /* turn off stripe alignment */
+ fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on stripe width allocation */
+ fsparam_u32	("sunit",      Opt_sunit),     /* data volume stripe unit */
+ fsparam_u32	("swidth",     Opt_swidth),    /* data volume stripe width */
+ fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore filesystem UUID */
+ fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID from parent directory (or not) */
+ fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from parent directory */
+ fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from current process */
+ fsparam_string ("allocsize",  Opt_allocsize), /* preferred allocation size */
+ fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS recovery */
+ fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be allocated anywhere */
+ fsparam_flag	("inode32",    Opt_inode32),   /* inode allocation limited to XFS_MAXINUMBER_32 */
+ fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free (or keep) empty inode clusters */
+ fsparam_flag_no("largeio",    Opt_largeio),   /* report (or do not report) large I/O sizes in stat() */
+ fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do not) use attr2 attribute format */
+ fsparam_flag	("filestreams",Opt_filestreams), /* use filestreams allocator */
+ fsparam_flag_no("quota",      Opt_quota),     /* disk quotas (user) */
+ fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota enabled */
+ fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota enabled */
+ fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota enabled */
+ fsparam_flag	("uquota",     Opt_uquota),    /* user quota (IRIX variant) */
+ fsparam_flag	("gquota",     Opt_gquota),    /* group quota (IRIX variant) */
+ fsparam_flag	("pquota",     Opt_pquota),    /* project quota (IRIX variant) */
+ fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota limit enforcement */
+ fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota limit enforcement */
+ fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project quota limit enforcement */
+ fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as uqnoenforce */
+ fsparam_flag_no("discard",    Opt_discard),   /* Do (or do not) not discard unused blocks */
+ fsparam_flag	("dax",	       Opt_dax),       /* Enable direct access to bdev pages */
+ {}
+};
+
+static const struct fs_parameter_description xfs_fs_parameters = {
+	.name		= "XFS",
+	.specs		= xfs_param_specs,
+};
 
 STATIC int
 suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)


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

* [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
  2019-08-23  0:59 ` [PATCH v2 01/15] vfs: Create fs_context-aware mount_bdev() replacement Ian Kent
  2019-08-23  0:59 ` [PATCH v2 02/15] xfs: mount-api - add fs parameter description Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-27 12:40   ` Brian Foster
  2019-08-23  0:59 ` [PATCH v2 04/15] xfs: mount-api - refactor xfs_parseags() Ian Kent
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

The mount-api doesn't have a "human unit" parse type yet so
the options that have values like "10k" etc. still need to
be converted by the fs.

But the value comes to the fs as a string (not a substring_t
type) so there's a need to change the conversion function to
take a character string instead.

After refactoring xfs_parseargs() and changing it to use
xfs_parse_param() match_kstrtoint() will no longer be used
and will be removed.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 74c88b92ce22..49c87fb921f1 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -153,13 +153,13 @@ static const struct fs_parameter_description xfs_fs_parameters = {
 };
 
 STATIC int
-suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
+suffix_kstrtoint(const char *s, unsigned int base, int *res)
 {
 	int	last, shift_left_factor = 0, _res;
 	char	*value;
 	int	ret = 0;
 
-	value = match_strdup(s);
+	value = kstrdup(s, GFP_KERNEL);
 	if (!value)
 		return -ENOMEM;
 
@@ -184,6 +184,20 @@ suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
 	return ret;
 }
 
+STATIC int
+match_kstrtoint(const substring_t *s, unsigned int base, int *res)
+{
+	const char	*value;
+	int ret;
+
+	value = match_strdup(s);
+	if (!value)
+		return -ENOMEM;
+	ret = suffix_kstrtoint(value, base, res);
+	kfree(value);
+	return ret;
+}
+
 /*
  * This function fills in xfs_mount_t fields based on mount args.
  * Note: the superblock has _not_ yet been read in.
@@ -255,7 +269,7 @@ xfs_parseargs(
 				return -EINVAL;
 			break;
 		case Opt_logbsize:
-			if (suffix_kstrtoint(args, 10, &mp->m_logbsize))
+			if (match_kstrtoint(args, 10, &mp->m_logbsize))
 				return -EINVAL;
 			break;
 		case Opt_logdev:
@@ -272,7 +286,7 @@ xfs_parseargs(
 			break;
 		case Opt_allocsize:
 		case Opt_biosize:
-			if (suffix_kstrtoint(args, 10, &iosize))
+			if (match_kstrtoint(args, 10, &iosize))
 				return -EINVAL;
 			iosizelog = ffs(iosize) - 1;
 			break;


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

* [PATCH v2 04/15] xfs: mount-api - refactor xfs_parseags()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (2 preceding siblings ...)
  2019-08-23  0:59 ` [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint() Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-27 12:40   ` Brian Foster
  2019-08-23  0:59 ` [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args Ian Kent
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Refactor xfs_parseags(), move the entire token case block to a
separate function in an attempt to highlight the code that
actually changes in converting to use the new mount api.

The only changes are what's needed to communicate the variables
dsunit, dswidth and iosizelog back to xfs_parseags().

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |  292 ++++++++++++++++++++++++++++------------------------
 1 file changed, 156 insertions(+), 136 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 49c87fb921f1..3ae29938dd89 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -198,6 +198,157 @@ match_kstrtoint(const substring_t *s, unsigned int base, int *res)
 	return ret;
 }
 
+STATIC int
+xfs_parse_param(
+	int 			token,
+	char			*p,
+	substring_t		*args,
+	struct xfs_mount	*mp,
+	int			*dsunit,
+	int			*dswidth,
+	uint8_t			*iosizelog)
+{
+	int			iosize = 0;
+
+	switch (token) {
+	case Opt_logbufs:
+		if (match_int(args, &mp->m_logbufs))
+			return -EINVAL;
+		break;
+	case Opt_logbsize:
+		if (match_kstrtoint(args, 10, &mp->m_logbsize))
+			return -EINVAL;
+		break;
+	case Opt_logdev:
+		kfree(mp->m_logname);
+		mp->m_logname = match_strdup(args);
+		if (!mp->m_logname)
+			return -ENOMEM;
+		break;
+	case Opt_rtdev:
+		kfree(mp->m_rtname);
+		mp->m_rtname = match_strdup(args);
+		if (!mp->m_rtname)
+			return -ENOMEM;
+		break;
+	case Opt_allocsize:
+	case Opt_biosize:
+		if (match_kstrtoint(args, 10, &iosize))
+			return -EINVAL;
+		*iosizelog = ffs(iosize) - 1;
+		break;
+	case Opt_grpid:
+	case Opt_bsdgroups:
+		mp->m_flags |= XFS_MOUNT_GRPID;
+		break;
+	case Opt_nogrpid:
+	case Opt_sysvgroups:
+		mp->m_flags &= ~XFS_MOUNT_GRPID;
+		break;
+	case Opt_wsync:
+		mp->m_flags |= XFS_MOUNT_WSYNC;
+		break;
+	case Opt_norecovery:
+		mp->m_flags |= XFS_MOUNT_NORECOVERY;
+		break;
+	case Opt_noalign:
+		mp->m_flags |= XFS_MOUNT_NOALIGN;
+		break;
+	case Opt_swalloc:
+		mp->m_flags |= XFS_MOUNT_SWALLOC;
+		break;
+	case Opt_sunit:
+		if (match_int(args, dsunit))
+			return -EINVAL;
+		break;
+	case Opt_swidth:
+		if (match_int(args, dswidth))
+			return -EINVAL;
+		break;
+	case Opt_inode32:
+		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
+		break;
+	case Opt_inode64:
+		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
+		break;
+	case Opt_nouuid:
+		mp->m_flags |= XFS_MOUNT_NOUUID;
+		break;
+	case Opt_ikeep:
+		mp->m_flags |= XFS_MOUNT_IKEEP;
+		break;
+	case Opt_noikeep:
+		mp->m_flags &= ~XFS_MOUNT_IKEEP;
+		break;
+	case Opt_largeio:
+		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
+		break;
+	case Opt_nolargeio:
+		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+		break;
+	case Opt_attr2:
+		mp->m_flags |= XFS_MOUNT_ATTR2;
+		break;
+	case Opt_noattr2:
+		mp->m_flags &= ~XFS_MOUNT_ATTR2;
+		mp->m_flags |= XFS_MOUNT_NOATTR2;
+		break;
+	case Opt_filestreams:
+		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
+		break;
+	case Opt_noquota:
+		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
+		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
+		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
+		break;
+	case Opt_quota:
+	case Opt_uquota:
+	case Opt_usrquota:
+		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
+				 XFS_UQUOTA_ENFD);
+		break;
+	case Opt_qnoenforce:
+	case Opt_uqnoenforce:
+		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
+		mp->m_qflags &= ~XFS_UQUOTA_ENFD;
+		break;
+	case Opt_pquota:
+	case Opt_prjquota:
+		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
+				 XFS_PQUOTA_ENFD);
+		break;
+	case Opt_pqnoenforce:
+		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
+		mp->m_qflags &= ~XFS_PQUOTA_ENFD;
+		break;
+	case Opt_gquota:
+	case Opt_grpquota:
+		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
+				 XFS_GQUOTA_ENFD);
+		break;
+	case Opt_gqnoenforce:
+		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
+		mp->m_qflags &= ~XFS_GQUOTA_ENFD;
+		break;
+	case Opt_discard:
+		mp->m_flags |= XFS_MOUNT_DISCARD;
+		break;
+	case Opt_nodiscard:
+		mp->m_flags &= ~XFS_MOUNT_DISCARD;
+		break;
+#ifdef CONFIG_FS_DAX
+	case Opt_dax:
+		mp->m_flags |= XFS_MOUNT_DAX;
+		break;
+#endif
+	default:
+		xfs_warn(mp, "unknown mount option [%s].", p);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /*
  * This function fills in xfs_mount_t fields based on mount args.
  * Note: the superblock has _not_ yet been read in.
@@ -219,7 +370,6 @@ xfs_parseargs(
 	substring_t		args[MAX_OPT_ARGS];
 	int			dsunit = 0;
 	int			dswidth = 0;
-	int			iosize = 0;
 	uint8_t			iosizelog = 0;
 
 	/*
@@ -258,146 +408,16 @@ xfs_parseargs(
 
 	while ((p = strsep(&options, ",")) != NULL) {
 		int		token;
+		int		ret;
 
 		if (!*p)
 			continue;
 
 		token = match_token(p, tokens, args);
-		switch (token) {
-		case Opt_logbufs:
-			if (match_int(args, &mp->m_logbufs))
-				return -EINVAL;
-			break;
-		case Opt_logbsize:
-			if (match_kstrtoint(args, 10, &mp->m_logbsize))
-				return -EINVAL;
-			break;
-		case Opt_logdev:
-			kfree(mp->m_logname);
-			mp->m_logname = match_strdup(args);
-			if (!mp->m_logname)
-				return -ENOMEM;
-			break;
-		case Opt_rtdev:
-			kfree(mp->m_rtname);
-			mp->m_rtname = match_strdup(args);
-			if (!mp->m_rtname)
-				return -ENOMEM;
-			break;
-		case Opt_allocsize:
-		case Opt_biosize:
-			if (match_kstrtoint(args, 10, &iosize))
-				return -EINVAL;
-			iosizelog = ffs(iosize) - 1;
-			break;
-		case Opt_grpid:
-		case Opt_bsdgroups:
-			mp->m_flags |= XFS_MOUNT_GRPID;
-			break;
-		case Opt_nogrpid:
-		case Opt_sysvgroups:
-			mp->m_flags &= ~XFS_MOUNT_GRPID;
-			break;
-		case Opt_wsync:
-			mp->m_flags |= XFS_MOUNT_WSYNC;
-			break;
-		case Opt_norecovery:
-			mp->m_flags |= XFS_MOUNT_NORECOVERY;
-			break;
-		case Opt_noalign:
-			mp->m_flags |= XFS_MOUNT_NOALIGN;
-			break;
-		case Opt_swalloc:
-			mp->m_flags |= XFS_MOUNT_SWALLOC;
-			break;
-		case Opt_sunit:
-			if (match_int(args, &dsunit))
-				return -EINVAL;
-			break;
-		case Opt_swidth:
-			if (match_int(args, &dswidth))
-				return -EINVAL;
-			break;
-		case Opt_inode32:
-			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
-			break;
-		case Opt_inode64:
-			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
-			break;
-		case Opt_nouuid:
-			mp->m_flags |= XFS_MOUNT_NOUUID;
-			break;
-		case Opt_ikeep:
-			mp->m_flags |= XFS_MOUNT_IKEEP;
-			break;
-		case Opt_noikeep:
-			mp->m_flags &= ~XFS_MOUNT_IKEEP;
-			break;
-		case Opt_largeio:
-			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
-			break;
-		case Opt_nolargeio:
-			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
-			break;
-		case Opt_attr2:
-			mp->m_flags |= XFS_MOUNT_ATTR2;
-			break;
-		case Opt_noattr2:
-			mp->m_flags &= ~XFS_MOUNT_ATTR2;
-			mp->m_flags |= XFS_MOUNT_NOATTR2;
-			break;
-		case Opt_filestreams:
-			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
-			break;
-		case Opt_noquota:
-			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
-			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
-			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
-			break;
-		case Opt_quota:
-		case Opt_uquota:
-		case Opt_usrquota:
-			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
-					 XFS_UQUOTA_ENFD);
-			break;
-		case Opt_qnoenforce:
-		case Opt_uqnoenforce:
-			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
-			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
-			break;
-		case Opt_pquota:
-		case Opt_prjquota:
-			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
-					 XFS_PQUOTA_ENFD);
-			break;
-		case Opt_pqnoenforce:
-			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
-			mp->m_qflags &= ~XFS_PQUOTA_ENFD;
-			break;
-		case Opt_gquota:
-		case Opt_grpquota:
-			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
-					 XFS_GQUOTA_ENFD);
-			break;
-		case Opt_gqnoenforce:
-			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
-			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
-			break;
-		case Opt_discard:
-			mp->m_flags |= XFS_MOUNT_DISCARD;
-			break;
-		case Opt_nodiscard:
-			mp->m_flags &= ~XFS_MOUNT_DISCARD;
-			break;
-#ifdef CONFIG_FS_DAX
-		case Opt_dax:
-			mp->m_flags |= XFS_MOUNT_DAX;
-			break;
-#endif
-		default:
-			xfs_warn(mp, "unknown mount option [%s].", p);
-			return -EINVAL;
-		}
+		ret = xfs_parse_param(token, p, args, mp,
+				      &dsunit, &dswidth, &iosizelog);
+		if (ret)
+			return ret;
 	}
 
 	/*


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

* [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (3 preceding siblings ...)
  2019-08-23  0:59 ` [PATCH v2 04/15] xfs: mount-api - refactor xfs_parseags() Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-26 19:19   ` Eric Sandeen
  2019-08-27 12:41   ` Brian Foster
  2019-08-23  0:59 ` [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper Ian Kent
                   ` (10 subsequent siblings)
  15 siblings, 2 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Make xfs_parse_param() take arguments of the fs context operation
.parse_param() in preperation for switching to use the file system
mount context for mount.

The function fc_parse() only uses the file system context (fc here)
when calling log macros warnf() and invalf() which in turn check
only the fc->log field to determine if the message should be saved
to a context buffer (for later retrival by userspace) or logged
using printk().

Also the temporary function match_kstrtoint() is now unused, remove it.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |  187 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 108 insertions(+), 79 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 3ae29938dd89..754d2ccfd960 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -184,64 +184,62 @@ suffix_kstrtoint(const char *s, unsigned int base, int *res)
 	return ret;
 }
 
-STATIC int
-match_kstrtoint(const substring_t *s, unsigned int base, int *res)
-{
-	const char	*value;
-	int ret;
-
-	value = match_strdup(s);
-	if (!value)
-		return -ENOMEM;
-	ret = suffix_kstrtoint(value, base, res);
-	kfree(value);
-	return ret;
-}
+struct xfs_fs_context {
+	int	dsunit;
+	int	dswidth;
+	uint8_t	iosizelog;
+};
 
 STATIC int
 xfs_parse_param(
-	int 			token,
-	char			*p,
-	substring_t		*args,
-	struct xfs_mount	*mp,
-	int			*dsunit,
-	int			*dswidth,
-	uint8_t			*iosizelog)
+	struct fs_context	*fc,
+	struct fs_parameter	*param)
 {
+	struct xfs_fs_context	*ctx = fc->fs_private;
+	struct xfs_mount	*mp = fc->s_fs_info;
+	struct fs_parse_result	result;
 	int			iosize = 0;
+	int			opt;
 
-	switch (token) {
+	opt = fs_parse(fc, &xfs_fs_parameters, param, &result);
+	if (opt < 0)
+		return opt;
+
+	switch (opt) {
 	case Opt_logbufs:
-		if (match_int(args, &mp->m_logbufs))
-			return -EINVAL;
+		mp->m_logbufs = result.uint_32;
 		break;
 	case Opt_logbsize:
-		if (match_kstrtoint(args, 10, &mp->m_logbsize))
+		if (suffix_kstrtoint(param->string, 10, &mp->m_logbsize))
 			return -EINVAL;
 		break;
 	case Opt_logdev:
 		kfree(mp->m_logname);
-		mp->m_logname = match_strdup(args);
+		mp->m_logname = kstrdup(param->string, GFP_KERNEL);
 		if (!mp->m_logname)
 			return -ENOMEM;
 		break;
 	case Opt_rtdev:
 		kfree(mp->m_rtname);
-		mp->m_rtname = match_strdup(args);
+		mp->m_rtname = kstrdup(param->string, GFP_KERNEL);
 		if (!mp->m_rtname)
 			return -ENOMEM;
 		break;
 	case Opt_allocsize:
 	case Opt_biosize:
-		if (match_kstrtoint(args, 10, &iosize))
+		if (suffix_kstrtoint(param->string, 10, &iosize))
 			return -EINVAL;
-		*iosizelog = ffs(iosize) - 1;
+		ctx->iosizelog = ffs(iosize) - 1;
 		break;
 	case Opt_grpid:
+		if (result.negated)
+			mp->m_flags &= ~XFS_MOUNT_GRPID;
+		else
+			mp->m_flags |= XFS_MOUNT_GRPID;
+		break;
 	case Opt_bsdgroups:
 		mp->m_flags |= XFS_MOUNT_GRPID;
 		break;
-	case Opt_nogrpid:
 	case Opt_sysvgroups:
 		mp->m_flags &= ~XFS_MOUNT_GRPID;
 		break;
@@ -258,12 +256,10 @@ xfs_parse_param(
 		mp->m_flags |= XFS_MOUNT_SWALLOC;
 		break;
 	case Opt_sunit:
-		if (match_int(args, dsunit))
-			return -EINVAL;
+		ctx->dsunit = result.uint_32;
 		break;
 	case Opt_swidth:
-		if (match_int(args, dswidth))
-			return -EINVAL;
+		ctx->dswidth = result.uint_32;
 		break;
 	case Opt_inode32:
 		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
@@ -275,33 +271,38 @@ xfs_parse_param(
 		mp->m_flags |= XFS_MOUNT_NOUUID;
 		break;
 	case Opt_ikeep:
-		mp->m_flags |= XFS_MOUNT_IKEEP;
-		break;
-	case Opt_noikeep:
-		mp->m_flags &= ~XFS_MOUNT_IKEEP;
+		if (result.negated)
+			mp->m_flags &= ~XFS_MOUNT_IKEEP;
+		else
+			mp->m_flags |= XFS_MOUNT_IKEEP;
 		break;
 	case Opt_largeio:
-		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
-		break;
-	case Opt_nolargeio:
-		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+		if (result.negated)
+			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+		else
+			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
 		break;
 	case Opt_attr2:
-		mp->m_flags |= XFS_MOUNT_ATTR2;
-		break;
-	case Opt_noattr2:
-		mp->m_flags &= ~XFS_MOUNT_ATTR2;
-		mp->m_flags |= XFS_MOUNT_NOATTR2;
+		if (!result.negated) {
+			mp->m_flags |= XFS_MOUNT_ATTR2;
+		} else {
+			mp->m_flags &= ~XFS_MOUNT_ATTR2;
+			mp->m_flags |= XFS_MOUNT_NOATTR2;
+		}
 		break;
 	case Opt_filestreams:
 		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
 		break;
-	case Opt_noquota:
-		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
-		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
-		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
-		break;
 	case Opt_quota:
+		if (!result.negated) {
+			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
+					 XFS_UQUOTA_ENFD);
+		} else {
+			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
+			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
+			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
+		}
+		break;
 	case Opt_uquota:
 	case Opt_usrquota:
 		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
@@ -331,10 +332,10 @@ xfs_parse_param(
 		mp->m_qflags &= ~XFS_GQUOTA_ENFD;
 		break;
 	case Opt_discard:
-		mp->m_flags |= XFS_MOUNT_DISCARD;
-		break;
-	case Opt_nodiscard:
-		mp->m_flags &= ~XFS_MOUNT_DISCARD;
+		if (result.negated)
+			mp->m_flags &= ~XFS_MOUNT_DISCARD;
+		else
+			mp->m_flags |= XFS_MOUNT_DISCARD;
 		break;
 #ifdef CONFIG_FS_DAX
 	case Opt_dax:
@@ -342,7 +343,7 @@ xfs_parse_param(
 		break;
 #endif
 	default:
-		xfs_warn(mp, "unknown mount option [%s].", p);
+		xfs_warn(mp, "unknown mount option [%s].", param->key);
 		return -EINVAL;
 	}
 
@@ -367,10 +368,10 @@ xfs_parseargs(
 {
 	const struct super_block *sb = mp->m_super;
 	char			*p;
-	substring_t		args[MAX_OPT_ARGS];
-	int			dsunit = 0;
-	int			dswidth = 0;
-	uint8_t			iosizelog = 0;
+
+	struct fs_context	fc;
+	struct xfs_fs_context	context;
+	struct xfs_fs_context	*ctx = &context;
 
 	/*
 	 * set up the mount name first so all the errors will refer to the
@@ -406,17 +407,41 @@ xfs_parseargs(
 	if (!options)
 		goto done;
 
+	memset(&fc, 0, sizeof(fc));
+	memset(&ctx, 0, sizeof(ctx));
+	fc.fs_private = ctx;
+	fc.s_fs_info = mp;
+
 	while ((p = strsep(&options, ",")) != NULL) {
-		int		token;
-		int		ret;
+		struct fs_parameter	param;
+		char			*value;
+		int			ret;
 
 		if (!*p)
 			continue;
 
-		token = match_token(p, tokens, args);
-		ret = xfs_parse_param(token, p, args, mp,
-				      &dsunit, &dswidth, &iosizelog);
-		if (ret)
+		param.key = p;
+		param.type = fs_value_is_string;
+		param.size = 0;
+
+		value = strchr(p, '=');
+		if (value) {
+			if (value == p)
+				continue;
+			*value++ = 0;
+			param.size = strlen(value);
+			if (param.size > 0) {
+				param.string = kmemdup_nul(value,
+							   param.size,
+							   GFP_KERNEL);
+				if (!param.string)
+					return -ENOMEM;
+			}
+		}
+
+		ret = xfs_parse_param(&fc, &param);
+		kfree(param.string);
+		if (ret < 0)
 			return ret;
 	}
 
@@ -429,7 +454,7 @@ xfs_parseargs(
 		return -EINVAL;
 	}
 
-	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
+	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (ctx->dsunit || ctx->dswidth)) {
 		xfs_warn(mp,
 	"sunit and swidth options incompatible with the noalign option");
 		return -EINVAL;
@@ -442,28 +467,28 @@ xfs_parseargs(
 	}
 #endif
 
-	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
+	if ((ctx->dsunit && !ctx->dswidth) || (!ctx->dsunit && ctx->dswidth)) {
 		xfs_warn(mp, "sunit and swidth must be specified together");
 		return -EINVAL;
 	}
 
-	if (dsunit && (dswidth % dsunit != 0)) {
+	if (ctx->dsunit && (ctx->dswidth % ctx->dsunit != 0)) {
 		xfs_warn(mp,
 	"stripe width (%d) must be a multiple of the stripe unit (%d)",
-			dswidth, dsunit);
+			ctx->dswidth, ctx->dsunit);
 		return -EINVAL;
 	}
 
 done:
-	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
+	if (ctx->dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
 		/*
 		 * At this point the superblock has not been read
 		 * in, therefore we do not know the block size.
 		 * Before the mount call ends we will convert
 		 * these to FSBs.
 		 */
-		mp->m_dalign = dsunit;
-		mp->m_swidth = dswidth;
+		mp->m_dalign = ctx->dsunit;
+		mp->m_swidth = ctx->dswidth;
 	}
 
 	if (mp->m_logbufs != -1 &&
@@ -485,18 +510,18 @@ xfs_parseargs(
 		return -EINVAL;
 	}
 
-	if (iosizelog) {
-		if (iosizelog > XFS_MAX_IO_LOG ||
-		    iosizelog < XFS_MIN_IO_LOG) {
+	if (ctx->iosizelog) {
+		if (ctx->iosizelog > XFS_MAX_IO_LOG ||
+		    ctx->iosizelog < XFS_MIN_IO_LOG) {
 			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
-				iosizelog, XFS_MIN_IO_LOG,
+				ctx->iosizelog, XFS_MIN_IO_LOG,
 				XFS_MAX_IO_LOG);
 			return -EINVAL;
 		}
 
 		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
-		mp->m_readio_log = iosizelog;
-		mp->m_writeio_log = iosizelog;
+		mp->m_readio_log = ctx->iosizelog;
+		mp->m_writeio_log = ctx->iosizelog;
 	}
 
 	return 0;
@@ -1914,6 +1939,10 @@ static const struct super_operations xfs_super_operations = {
 	.free_cached_objects	= xfs_fs_free_cached_objects,
 };
 
+static const struct fs_context_operations xfs_context_ops = {
+	.parse_param = xfs_parse_param,
+};
+
 static struct file_system_type xfs_fs_type = {
 	.owner			= THIS_MODULE,
 	.name			= "xfs",


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

* [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (4 preceding siblings ...)
  2019-08-23  0:59 ` [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-27 12:41   ` Brian Foster
  2019-08-23  0:59 ` [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super() Ian Kent
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Move the validation code of xfs_parseargs() into a helper for later
use within the mount context methods.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |  180 ++++++++++++++++++++++++++++------------------------
 1 file changed, 98 insertions(+), 82 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 754d2ccfd960..7cdda17ee0ff 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -350,6 +350,97 @@ xfs_parse_param(
 	return 0;
 }
 
+STATIC int
+xfs_validate_params(
+	struct xfs_mount        *mp,
+	struct xfs_fs_context   *ctx,
+	bool			nooptions)
+{
+	if (nooptions)
+		goto noopts;
+
+	/*
+	 * no recovery flag requires a read-only mount
+	 */
+	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
+	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
+		xfs_warn(mp, "no-recovery mounts must be read-only.");
+		return -EINVAL;
+	}
+
+	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (ctx->dsunit || ctx->dswidth)) {
+		xfs_warn(mp,
+	"sunit and swidth options incompatible with the noalign option");
+		return -EINVAL;
+	}
+
+#ifndef CONFIG_XFS_QUOTA
+	if (XFS_IS_QUOTA_RUNNING(mp)) {
+		xfs_warn(mp, "quota support not available in this kernel.");
+		return -EINVAL;
+	}
+#endif
+
+	if ((ctx->dsunit && !ctx->dswidth) || (!ctx->dsunit && ctx->dswidth)) {
+		xfs_warn(mp, "sunit and swidth must be specified together");
+		return -EINVAL;
+	}
+
+	if (ctx->dsunit && (ctx->dswidth % ctx->dsunit != 0)) {
+		xfs_warn(mp,
+	"stripe width (%d) must be a multiple of the stripe unit (%d)",
+			ctx->dswidth, ctx->dsunit);
+		return -EINVAL;
+	}
+
+noopts:
+	if (ctx->dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
+		/*
+		 * At this point the superblock has not been read
+		 * in, therefore we do not know the block size.
+		 * Before the mount call ends we will convert
+		 * these to FSBs.
+		 */
+		mp->m_dalign = ctx->dsunit;
+		mp->m_swidth = ctx->dswidth;
+	}
+
+	if (mp->m_logbufs != -1 &&
+	    mp->m_logbufs != 0 &&
+	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
+	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
+		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
+			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
+		return -EINVAL;
+	}
+	if (mp->m_logbsize != -1 &&
+	    mp->m_logbsize !=  0 &&
+	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
+	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
+	     !is_power_of_2(mp->m_logbsize))) {
+		xfs_warn(mp,
+			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
+			mp->m_logbsize);
+		return -EINVAL;
+	}
+
+	if (ctx->iosizelog) {
+		if (ctx->iosizelog > XFS_MAX_IO_LOG ||
+		    ctx->iosizelog < XFS_MIN_IO_LOG) {
+			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
+				ctx->iosizelog, XFS_MIN_IO_LOG,
+				XFS_MAX_IO_LOG);
+			return -EINVAL;
+		}
+
+		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
+		mp->m_readio_log = ctx->iosizelog;
+		mp->m_writeio_log = ctx->iosizelog;
+	}
+
+	return 0;
+}
+
 /*
  * This function fills in xfs_mount_t fields based on mount args.
  * Note: the superblock has _not_ yet been read in.
@@ -372,6 +463,7 @@ xfs_parseargs(
 	struct fs_context	fc;
 	struct xfs_fs_context	context;
 	struct xfs_fs_context	*ctx = &context;
+	int			ret;
 
 	/*
 	 * set up the mount name first so all the errors will refer to the
@@ -404,8 +496,10 @@ xfs_parseargs(
 	mp->m_logbufs = -1;
 	mp->m_logbsize = -1;
 
-	if (!options)
+	if (!options) {
+		ret = xfs_validate_params(mp, ctx, true);
 		goto done;
+	}
 
 	memset(&fc, 0, sizeof(fc));
 	memset(&ctx, 0, sizeof(ctx));
@@ -415,7 +509,6 @@ xfs_parseargs(
 	while ((p = strsep(&options, ",")) != NULL) {
 		struct fs_parameter	param;
 		char			*value;
-		int			ret;
 
 		if (!*p)
 			continue;
@@ -442,89 +535,12 @@ xfs_parseargs(
 		ret = xfs_parse_param(&fc, &param);
 		kfree(param.string);
 		if (ret < 0)
-			return ret;
-	}
-
-	/*
-	 * no recovery flag requires a read-only mount
-	 */
-	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
-	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
-		xfs_warn(mp, "no-recovery mounts must be read-only.");
-		return -EINVAL;
-	}
-
-	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (ctx->dsunit || ctx->dswidth)) {
-		xfs_warn(mp,
-	"sunit and swidth options incompatible with the noalign option");
-		return -EINVAL;
-	}
-
-#ifndef CONFIG_XFS_QUOTA
-	if (XFS_IS_QUOTA_RUNNING(mp)) {
-		xfs_warn(mp, "quota support not available in this kernel.");
-		return -EINVAL;
-	}
-#endif
-
-	if ((ctx->dsunit && !ctx->dswidth) || (!ctx->dsunit && ctx->dswidth)) {
-		xfs_warn(mp, "sunit and swidth must be specified together");
-		return -EINVAL;
-	}
-
-	if (ctx->dsunit && (ctx->dswidth % ctx->dsunit != 0)) {
-		xfs_warn(mp,
-	"stripe width (%d) must be a multiple of the stripe unit (%d)",
-			ctx->dswidth, ctx->dsunit);
-		return -EINVAL;
+			goto done;
 	}
 
+	ret = xfs_validate_params(mp, ctx, false);
 done:
-	if (ctx->dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
-		/*
-		 * At this point the superblock has not been read
-		 * in, therefore we do not know the block size.
-		 * Before the mount call ends we will convert
-		 * these to FSBs.
-		 */
-		mp->m_dalign = ctx->dsunit;
-		mp->m_swidth = ctx->dswidth;
-	}
-
-	if (mp->m_logbufs != -1 &&
-	    mp->m_logbufs != 0 &&
-	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
-	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
-		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
-			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
-		return -EINVAL;
-	}
-	if (mp->m_logbsize != -1 &&
-	    mp->m_logbsize !=  0 &&
-	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
-	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
-	     !is_power_of_2(mp->m_logbsize))) {
-		xfs_warn(mp,
-			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
-			mp->m_logbsize);
-		return -EINVAL;
-	}
-
-	if (ctx->iosizelog) {
-		if (ctx->iosizelog > XFS_MAX_IO_LOG ||
-		    ctx->iosizelog < XFS_MIN_IO_LOG) {
-			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
-				ctx->iosizelog, XFS_MIN_IO_LOG,
-				XFS_MAX_IO_LOG);
-			return -EINVAL;
-		}
-
-		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
-		mp->m_readio_log = ctx->iosizelog;
-		mp->m_writeio_log = ctx->iosizelog;
-	}
-
-	return 0;
+	return ret;
 }
 
 struct proc_xfs_info {


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

* [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (5 preceding siblings ...)
  2019-08-23  0:59 ` [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-27 12:42   ` Brian Foster
  2019-08-23  0:59 ` [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree() Ian Kent
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Much of the code in xfs_fs_fill_super() will be used by the fill super
function of the new mount-api.

So refactor the common code into a helper in an attempt to show what's
actually changed.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   65 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 23 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 7cdda17ee0ff..d3fc9938987d 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1690,27 +1690,14 @@ xfs_mount_alloc(
 
 
 STATIC int
-xfs_fs_fill_super(
-	struct super_block	*sb,
-	void			*data,
+__xfs_fs_fill_super(
+	struct xfs_mount	*mp,
 	int			silent)
 {
+	struct super_block	*sb = mp->m_super;
 	struct inode		*root;
-	struct xfs_mount	*mp = NULL;
-	int			flags = 0, error = -ENOMEM;
-
-	/*
-	 * allocate mp and do all low-level struct initializations before we
-	 * attach it to the super
-	 */
-	mp = xfs_mount_alloc(sb);
-	if (!mp)
-		goto out;
-	sb->s_fs_info = mp;
-
-	error = xfs_parseargs(mp, (char *)data);
-	if (error)
-		goto out_free_fsname;
+	int			flags = 0;
+	int			error;
 
 	sb_min_blocksize(sb, BBSIZE);
 	sb->s_xattr = xfs_xattr_handlers;
@@ -1737,7 +1724,7 @@ xfs_fs_fill_super(
 
 	error = xfs_open_devices(mp);
 	if (error)
-		goto out_free_fsname;
+		goto out;
 
 	error = xfs_init_mount_workqueues(mp);
 	if (error)
@@ -1872,10 +1859,6 @@ xfs_fs_fill_super(
 	xfs_destroy_mount_workqueues(mp);
  out_close_devices:
 	xfs_close_devices(mp);
- out_free_fsname:
-	sb->s_fs_info = NULL;
-	xfs_free_fsname(mp);
-	kfree(mp);
  out:
 	return error;
 
@@ -1885,6 +1868,42 @@ xfs_fs_fill_super(
 	goto out_free_sb;
 }
 
+STATIC int
+xfs_fs_fill_super(
+	struct super_block	*sb,
+	void			*data,
+	int			silent)
+{
+	struct xfs_mount	*mp = NULL;
+	int			error = -ENOMEM;
+
+	/*
+	 * allocate mp and do all low-level struct initializations before we
+	 * attach it to the super
+	 */
+	mp = xfs_mount_alloc(sb);
+	if (!mp)
+		goto out;
+	sb->s_fs_info = mp;
+
+	error = xfs_parseargs(mp, (char *)data);
+	if (error)
+		goto out_free_fsname;
+
+	error = __xfs_fs_fill_super(mp, silent);
+	if (error)
+		goto out_free_fsname;
+
+	return 0;
+
+ out_free_fsname:
+	sb->s_fs_info = NULL;
+	xfs_free_fsname(mp);
+	kfree(mp);
+out:
+	return error;
+}
+
 STATIC void
 xfs_fs_put_super(
 	struct super_block	*sb)


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

* [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (6 preceding siblings ...)
  2019-08-23  0:59 ` [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super() Ian Kent
@ 2019-08-23  0:59 ` Ian Kent
  2019-08-28 13:27   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 09/15] xfs: mount-api - add xfs_remount_rw() helper Ian Kent
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  0:59 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Add the fs_context_operations method .get_tree that validates
mount options and fills the super block as previously done
by the file_system_type .mount method.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index d3fc9938987d..7de64808eb00 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1904,6 +1904,52 @@ xfs_fs_fill_super(
 	return error;
 }
 
+STATIC int
+xfs_fill_super(
+	struct super_block	*sb,
+	struct fs_context	*fc)
+{
+	struct xfs_fs_context	*ctx = fc->fs_private;
+	struct xfs_mount	*mp = sb->s_fs_info;
+	int			silent = fc->sb_flags & SB_SILENT;
+	int			error = -ENOMEM;
+
+	mp->m_super = sb;
+
+	/*
+	 * set up the mount name first so all the errors will refer to the
+	 * correct device.
+	 */
+	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
+	if (!mp->m_fsname)
+		return -ENOMEM;
+	mp->m_fsname_len = strlen(mp->m_fsname) + 1;
+
+	error = xfs_validate_params(mp, ctx, false);
+	if (error)
+		goto out_free_fsname;
+
+	error = __xfs_fs_fill_super(mp, silent);
+	if (error)
+		goto out_free_fsname;
+
+	return 0;
+
+ out_free_fsname:
+	sb->s_fs_info = NULL;
+	xfs_free_fsname(mp);
+	kfree(mp);
+
+	return error;
+}
+
+STATIC int
+xfs_get_tree(
+	struct fs_context	*fc)
+{
+	return vfs_get_block_super(fc, xfs_fill_super);
+}
+
 STATIC void
 xfs_fs_put_super(
 	struct super_block	*sb)
@@ -1976,6 +2022,7 @@ static const struct super_operations xfs_super_operations = {
 
 static const struct fs_context_operations xfs_context_ops = {
 	.parse_param = xfs_parse_param,
+	.get_tree    = xfs_get_tree,
 };
 
 static struct file_system_type xfs_fs_type = {


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

* [PATCH v2 09/15] xfs: mount-api - add xfs_remount_rw() helper
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (7 preceding siblings ...)
  2019-08-23  0:59 ` [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree() Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-28 13:27   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 10/15] xfs: mount-api - add xfs_remount_ro() helper Ian Kent
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Factor the remount read write code into a helper to simplify the
subsequent change from the super block method .remount_fs to the
mount-api fs_context_operations method .reconfigure.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |  115 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 64 insertions(+), 51 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 7de64808eb00..9f7300958a38 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1341,6 +1341,68 @@ xfs_test_remount_options(
 	return error;
 }
 
+STATIC int
+xfs_remount_rw(
+	struct xfs_mount	*mp)
+{
+	xfs_sb_t		*sbp = &mp->m_sb;
+	int error;
+
+	if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
+		xfs_warn(mp,
+			"ro->rw transition prohibited on norecovery mount");
+		return -EINVAL;
+	}
+
+	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+	    xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
+		xfs_warn(mp,
+	"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
+			(sbp->sb_features_ro_compat &
+				XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
+		return -EINVAL;
+	}
+
+	mp->m_flags &= ~XFS_MOUNT_RDONLY;
+
+	/*
+	 * If this is the first remount to writeable state we
+	 * might have some superblock changes to update.
+	 */
+	if (mp->m_update_sb) {
+		error = xfs_sync_sb(mp, false);
+		if (error) {
+			xfs_warn(mp, "failed to write sb changes");
+			return error;
+		}
+		mp->m_update_sb = false;
+	}
+
+	/*
+	 * Fill out the reserve pool if it is empty. Use the stashed
+	 * value if it is non-zero, otherwise go with the default.
+	 */
+	xfs_restore_resvblks(mp);
+	xfs_log_work_queue(mp);
+
+	/* Recover any CoW blocks that never got remapped. */
+	error = xfs_reflink_recover_cow(mp);
+	if (error) {
+		xfs_err(mp,
+			"Error %d recovering leftover CoW allocations.", error);
+			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+		return error;
+	}
+	xfs_start_block_reaping(mp);
+
+	/* Create the per-AG metadata reservation pool .*/
+	error = xfs_fs_reserve_ag_blocks(mp);
+	if (error && error != -ENOSPC)
+		return error;
+
+	return 0;
+}
+
 STATIC int
 xfs_fs_remount(
 	struct super_block	*sb,
@@ -1404,57 +1466,8 @@ xfs_fs_remount(
 
 	/* ro -> rw */
 	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
-		if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
-			xfs_warn(mp,
-		"ro->rw transition prohibited on norecovery mount");
-			return -EINVAL;
-		}
-
-		if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
-		    xfs_sb_has_ro_compat_feature(sbp,
-					XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
-			xfs_warn(mp,
-"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
-				(sbp->sb_features_ro_compat &
-					XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
-			return -EINVAL;
-		}
-
-		mp->m_flags &= ~XFS_MOUNT_RDONLY;
-
-		/*
-		 * If this is the first remount to writeable state we
-		 * might have some superblock changes to update.
-		 */
-		if (mp->m_update_sb) {
-			error = xfs_sync_sb(mp, false);
-			if (error) {
-				xfs_warn(mp, "failed to write sb changes");
-				return error;
-			}
-			mp->m_update_sb = false;
-		}
-
-		/*
-		 * Fill out the reserve pool if it is empty. Use the stashed
-		 * value if it is non-zero, otherwise go with the default.
-		 */
-		xfs_restore_resvblks(mp);
-		xfs_log_work_queue(mp);
-
-		/* Recover any CoW blocks that never got remapped. */
-		error = xfs_reflink_recover_cow(mp);
-		if (error) {
-			xfs_err(mp,
-	"Error %d recovering leftover CoW allocations.", error);
-			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
-			return error;
-		}
-		xfs_start_block_reaping(mp);
-
-		/* Create the per-AG metadata reservation pool .*/
-		error = xfs_fs_reserve_ag_blocks(mp);
-		if (error && error != -ENOSPC)
+		error = xfs_remount_rw(mp);
+		if (error)
 			return error;
 	}
 


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

* [PATCH v2 10/15] xfs: mount-api - add xfs_remount_ro() helper
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (8 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 09/15] xfs: mount-api - add xfs_remount_rw() helper Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-28 13:27   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure() Ian Kent
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Factor the remount read only code into a helper to simplify the
subsequent change from the super block method .remount_fs to the
mount-api fs_context_operations method .reconfigure.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   73 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 30 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 9f7300958a38..76374d602257 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1403,6 +1403,47 @@ xfs_remount_rw(
 	return 0;
 }
 
+STATIC int
+xfs_remount_ro(
+	struct xfs_mount	*mp)
+{
+	int error;
+
+	/*
+	 * Cancel background eofb scanning so it cannot race with the
+	 * final log force+buftarg wait and deadlock the remount.
+	 */
+	xfs_stop_block_reaping(mp);
+
+	/* Get rid of any leftover CoW reservations... */
+	error = xfs_icache_free_cowblocks(mp, NULL);
+	if (error) {
+		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+		return error;
+	}
+
+	/* Free the per-AG metadata reservation pool. */
+	error = xfs_fs_unreserve_ag_blocks(mp);
+	if (error) {
+		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+		return error;
+	}
+
+	/*
+	 * Before we sync the metadata, we need to free up the reserve
+	 * block pool so that the used block count in the superblock on
+	 * disk is correct at the end of the remount. Stash the current
+	 * reserve pool size so that if we get remounted rw, we can
+	 * return it to the same size.
+	 */
+	xfs_save_resvblks(mp);
+
+	xfs_quiesce_attr(mp);
+	mp->m_flags |= XFS_MOUNT_RDONLY;
+
+	return 0;
+}
+
 STATIC int
 xfs_fs_remount(
 	struct super_block	*sb,
@@ -1473,37 +1514,9 @@ xfs_fs_remount(
 
 	/* rw -> ro */
 	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) {
-		/*
-		 * Cancel background eofb scanning so it cannot race with the
-		 * final log force+buftarg wait and deadlock the remount.
-		 */
-		xfs_stop_block_reaping(mp);
-
-		/* Get rid of any leftover CoW reservations... */
-		error = xfs_icache_free_cowblocks(mp, NULL);
-		if (error) {
-			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
-			return error;
-		}
-
-		/* Free the per-AG metadata reservation pool. */
-		error = xfs_fs_unreserve_ag_blocks(mp);
-		if (error) {
-			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+		error = xfs_remount_ro(mp);
+		if (error)
 			return error;
-		}
-
-		/*
-		 * Before we sync the metadata, we need to free up the reserve
-		 * block pool so that the used block count in the superblock on
-		 * disk is correct at the end of the remount. Stash the current
-		 * reserve pool size so that if we get remounted rw, we can
-		 * return it to the same size.
-		 */
-		xfs_save_resvblks(mp);
-
-		xfs_quiesce_attr(mp);
-		mp->m_flags |= XFS_MOUNT_RDONLY;
 	}
 
 	return 0;


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

* [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (9 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 10/15] xfs: mount-api - add xfs_remount_ro() helper Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-28 13:28   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free() Ian Kent
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Add the fs_context_operations method .reconfigure that performs
remount validation as previously done by the super_operations
.remount_fs method.

An attempt has also been made to update the comment about options
handling problems with mount(8) to reflect the current situation.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 76374d602257..aae0098fecab 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1522,6 +1522,89 @@ xfs_fs_remount(
 	return 0;
 }
 
+/*
+ * There have been problems in the past with options passed from mount(8).
+ *
+ * The problem being that options passed by mount(8) in the case where only
+ * the the mount point path is given would consist of the existing fstab
+ * options with the options from mtab for the current mount merged in and
+ * the options given on the command line last. But the result couldn't be
+ * relied upon to accurately reflect the current mount options so that
+ * rejecting options that can't be changed on reconfigure could erronously
+ * cause mount failure.
+ *
+ * The mount-api uses a legacy mount options handler in the VFS to handle
+ * mount(8) so these options will continue to be passed. Even if mount(8)
+ * is updated to use fsopen()/fsconfig()/fsmount() it's likely to continue
+ * to set the existing options so options problems with reconfigure could
+ * continue.
+ *
+ * For the longest time mtab locking was a problem and this could have been
+ * one possible cause. It's also possible there could have been options
+ * order problems.
+ *
+ * That has changed now as mtab is a link to the proc file system mount
+ * table so mtab options should be always accurate.
+ *
+ * Consulting the util-linux maintainer (Karel Zak) he is confident that,
+ * in this case, the options passed by mount(8) will be those of the current
+ * mount and the options order should be a correct merge of fstab and mtab
+ * options, and new options given on the command line.
+ *
+ * So, in theory, it should be possible to compare incoming options and
+ * return an error for options that differ from the current mount and can't
+ * be changed on reconfigure to prevent users from believing they might have
+ * changed mount options using remount which can't be changed.
+ *
+ * But for now continue to return success for every reconfigure request, and
+ * silently ignore all options that can't actually be changed.
+ */
+STATIC int
+xfs_reconfigure(
+	struct fs_context *fc)
+{
+	struct xfs_fs_context	*ctx = fc->fs_private;
+	struct xfs_mount	*mp = XFS_M(fc->root->d_sb);
+	struct xfs_mount        *new_mp = fc->s_fs_info;
+	xfs_sb_t		*sbp = &mp->m_sb;
+	int			flags = fc->sb_flags;
+	int			error;
+
+	error = xfs_validate_params(new_mp, ctx, false);
+	if (error)
+		return error;
+
+	/* inode32 -> inode64 */
+	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
+	    !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
+		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
+		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
+	}
+
+	/* inode64 -> inode32 */
+	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
+	    (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
+		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
+		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
+	}
+
+	/* ro -> rw */
+	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) {
+		error = xfs_remount_rw(mp);
+		if (error)
+			return error;
+	}
+
+	/* rw -> ro */
+	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) {
+		error = xfs_remount_ro(mp);
+		if (error)
+			return error;
+	}
+
+	return 0;
+}
+
 /*
  * Second stage of a freeze. The data is already frozen so we only
  * need to take care of the metadata. Once that's done sync the superblock
@@ -2049,6 +2132,7 @@ static const struct super_operations xfs_super_operations = {
 static const struct fs_context_operations xfs_context_ops = {
 	.parse_param = xfs_parse_param,
 	.get_tree    = xfs_get_tree,
+	.reconfigure = xfs_reconfigure,
 };
 
 static struct file_system_type xfs_fs_type = {


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

* [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (10 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure() Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-28 13:28   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 13/15] xfs: mount-api - dont set sb in xfs_mount_alloc() Ian Kent
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Add the fs_context_operations method .free that performs fs
context cleanup on context release.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index aae0098fecab..9976163dc537 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -2129,10 +2129,32 @@ static const struct super_operations xfs_super_operations = {
 	.free_cached_objects	= xfs_fs_free_cached_objects,
 };
 
+static void xfs_fc_free(struct fs_context *fc)
+{
+	struct xfs_fs_context	*ctx = fc->fs_private;
+	struct xfs_mount	*mp = fc->s_fs_info;
+
+	if (mp) {
+		/*
+		 * If an error occurs before ownership the xfs_mount
+		 * info struct is passed to xfs by the VFS (by assigning
+		 * it to sb->s_fs_info and clearing the corresponding
+		 * fs_context field, which is done before calling fill
+		 * super via .get_tree()) there may be some strings to
+		 * cleanup.
+		 */
+		kfree(mp->m_logname);
+		kfree(mp->m_rtname);
+		kfree(mp);
+	}
+	kfree(ctx);
+}
+
 static const struct fs_context_operations xfs_context_ops = {
 	.parse_param = xfs_parse_param,
 	.get_tree    = xfs_get_tree,
 	.reconfigure = xfs_reconfigure,
+	.free	     = xfs_fc_free,
 };
 
 static struct file_system_type xfs_fs_type = {


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

* [PATCH v2 13/15] xfs: mount-api - dont set sb in xfs_mount_alloc()
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (11 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free() Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-28 13:28   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 14/15] xfs: mount-api - switch to new mount-api Ian Kent
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

When changing to use the new mount api the super block won't be
available when the xfs_mount info struct is allocated so move
setting the super block in xfs_mount to xfs_fs_fill_super().

Also change xfs_mount_alloc() decalaration static -> STATIC.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 9976163dc537..d2a1a62a3edc 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1766,9 +1766,9 @@ xfs_destroy_percpu_counters(
 	percpu_counter_destroy(&mp->m_delalloc_blks);
 }
 
-static struct xfs_mount *
+STATIC struct xfs_mount *
 xfs_mount_alloc(
-	struct super_block	*sb)
+	void)
 {
 	struct xfs_mount	*mp;
 
@@ -1776,7 +1776,6 @@ xfs_mount_alloc(
 	if (!mp)
 		return NULL;
 
-	mp->m_super = sb;
 	spin_lock_init(&mp->m_sb_lock);
 	spin_lock_init(&mp->m_agirotor_lock);
 	INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
@@ -1990,9 +1989,10 @@ xfs_fs_fill_super(
 	 * allocate mp and do all low-level struct initializations before we
 	 * attach it to the super
 	 */
-	mp = xfs_mount_alloc(sb);
+	mp = xfs_mount_alloc();
 	if (!mp)
 		goto out;
+	mp->m_super = sb;
 	sb->s_fs_info = mp;
 
 	error = xfs_parseargs(mp, (char *)data);


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

* [PATCH v2 14/15] xfs: mount-api - switch to new mount-api
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (12 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 13/15] xfs: mount-api - dont set sb in xfs_mount_alloc() Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-28 13:29   ` Brian Foster
  2019-08-23  1:00 ` [PATCH v2 15/15] xfs: mount-api - remove legacy mount functions Ian Kent
  2019-08-26 19:33 ` [PATCH v2 00/15] xfs: mount API patch series Darrick J. Wong
  15 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

The infrastructure needed to use the new mount api is now
in place, switch over to use it.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index d2a1a62a3edc..fe7acd8ddd48 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -2123,7 +2123,6 @@ static const struct super_operations xfs_super_operations = {
 	.freeze_fs		= xfs_fs_freeze,
 	.unfreeze_fs		= xfs_fs_unfreeze,
 	.statfs			= xfs_fs_statfs,
-	.remount_fs		= xfs_fs_remount,
 	.show_options		= xfs_fs_show_options,
 	.nr_cached_objects	= xfs_fs_nr_cached_objects,
 	.free_cached_objects	= xfs_fs_free_cached_objects,
@@ -2157,10 +2156,58 @@ static const struct fs_context_operations xfs_context_ops = {
 	.free	     = xfs_fc_free,
 };
 
+/*
+ * Set up the filesystem mount context.
+ */
+int xfs_init_fs_context(struct fs_context *fc)
+{
+	struct xfs_fs_context	*ctx;
+	struct xfs_mount	*mp;
+
+	ctx = kzalloc(sizeof(struct xfs_fs_context), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	mp = xfs_mount_alloc();
+	if (!mp) {
+		kfree(ctx);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Set some default flags that could be cleared by the mount option
+	 * parsing.
+	 */
+	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
+
+	/*
+	 * These can be overridden by the mount option parsing.
+	 */
+	mp->m_logbufs = -1;
+	mp->m_logbsize = -1;
+
+	/*
+	 * Copy binary VFS mount flags we are interested in.
+	 */
+	if (fc->sb_flags & SB_RDONLY)
+		mp->m_flags |= XFS_MOUNT_RDONLY;
+	if (fc->sb_flags & SB_DIRSYNC)
+		mp->m_flags |= XFS_MOUNT_DIRSYNC;
+	if (fc->sb_flags & SB_SYNCHRONOUS)
+		mp->m_flags |= XFS_MOUNT_WSYNC;
+
+	fc->fs_private = ctx;
+	fc->s_fs_info = mp;
+	fc->ops = &xfs_context_ops;
+
+	return 0;
+}
+
 static struct file_system_type xfs_fs_type = {
 	.owner			= THIS_MODULE,
 	.name			= "xfs",
-	.mount			= xfs_fs_mount,
+	.init_fs_context	= xfs_init_fs_context,
+	.parameters		= &xfs_fs_parameters,
 	.kill_sb		= kill_block_super,
 	.fs_flags		= FS_REQUIRES_DEV,
 };


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

* [PATCH v2 15/15] xfs: mount-api - remove legacy mount functions
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (13 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 14/15] xfs: mount-api - switch to new mount-api Ian Kent
@ 2019-08-23  1:00 ` Ian Kent
  2019-08-26 19:33 ` [PATCH v2 00/15] xfs: mount API patch series Darrick J. Wong
  15 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-23  1:00 UTC (permalink / raw)
  To: linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro, Eric Sandeen

Now that the new mount api is being used the old mount functions
and parsing table can be removed.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 fs/xfs/xfs_super.c |  307 +---------------------------------------------------
 1 file changed, 6 insertions(+), 301 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index fe7acd8ddd48..ef649a485269 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -52,60 +52,12 @@ static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs attrs */
 enum {
 	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
 	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
-	Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups,
-	Opt_allocsize, Opt_norecovery, Opt_inode64, Opt_inode32, Opt_ikeep,
-	Opt_noikeep, Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2,
-	Opt_filestreams, Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota,
-	Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota,
-	Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
-	Opt_discard, Opt_nodiscard, Opt_dax, Opt_err,
-};
-
-static const match_table_t tokens = {
-	{Opt_logbufs,	"logbufs=%u"},	/* number of XFS log buffers */
-	{Opt_logbsize,	"logbsize=%s"},	/* size of XFS log buffers */
-	{Opt_logdev,	"logdev=%s"},	/* log device */
-	{Opt_rtdev,	"rtdev=%s"},	/* realtime I/O device */
-	{Opt_biosize,	"biosize=%u"},	/* log2 of preferred buffered io size */
-	{Opt_wsync,	"wsync"},	/* safe-mode nfs compatible mount */
-	{Opt_noalign,	"noalign"},	/* turn off stripe alignment */
-	{Opt_swalloc,	"swalloc"},	/* turn on stripe width allocation */
-	{Opt_sunit,	"sunit=%u"},	/* data volume stripe unit */
-	{Opt_swidth,	"swidth=%u"},	/* data volume stripe width */
-	{Opt_nouuid,	"nouuid"},	/* ignore filesystem UUID */
-	{Opt_grpid,	"grpid"},	/* group-ID from parent directory */
-	{Opt_nogrpid,	"nogrpid"},	/* group-ID from current process */
-	{Opt_bsdgroups,	"bsdgroups"},	/* group-ID from parent directory */
-	{Opt_sysvgroups,"sysvgroups"},	/* group-ID from current process */
-	{Opt_allocsize,	"allocsize=%s"},/* preferred allocation size */
-	{Opt_norecovery,"norecovery"},	/* don't run XFS recovery */
-	{Opt_inode64,	"inode64"},	/* inodes can be allocated anywhere */
-	{Opt_inode32,   "inode32"},	/* inode allocation limited to
-					 * XFS_MAXINUMBER_32 */
-	{Opt_ikeep,	"ikeep"},	/* do not free empty inode clusters */
-	{Opt_noikeep,	"noikeep"},	/* free empty inode clusters */
-	{Opt_largeio,	"largeio"},	/* report large I/O sizes in stat() */
-	{Opt_nolargeio,	"nolargeio"},	/* do not report large I/O sizes
-					 * in stat(). */
-	{Opt_attr2,	"attr2"},	/* do use attr2 attribute format */
-	{Opt_noattr2,	"noattr2"},	/* do not use attr2 attribute format */
-	{Opt_filestreams,"filestreams"},/* use filestreams allocator */
-	{Opt_quota,	"quota"},	/* disk quotas (user) */
-	{Opt_noquota,	"noquota"},	/* no quotas */
-	{Opt_usrquota,	"usrquota"},	/* user quota enabled */
-	{Opt_grpquota,	"grpquota"},	/* group quota enabled */
-	{Opt_prjquota,	"prjquota"},	/* project quota enabled */
-	{Opt_uquota,	"uquota"},	/* user quota (IRIX variant) */
-	{Opt_gquota,	"gquota"},	/* group quota (IRIX variant) */
-	{Opt_pquota,	"pquota"},	/* project quota (IRIX variant) */
-	{Opt_uqnoenforce,"uqnoenforce"},/* user quota limit enforcement */
-	{Opt_gqnoenforce,"gqnoenforce"},/* group quota limit enforcement */
-	{Opt_pqnoenforce,"pqnoenforce"},/* project quota limit enforcement */
-	{Opt_qnoenforce, "qnoenforce"},	/* same as uqnoenforce */
-	{Opt_discard,	"discard"},	/* Discard unused blocks */
-	{Opt_nodiscard,	"nodiscard"},	/* Do not discard unused blocks */
-	{Opt_dax,	"dax"},		/* Enable direct access to bdev pages */
-	{Opt_err,	NULL},
+	Opt_grpid, Opt_bsdgroups, Opt_sysvgroups, Opt_allocsize,
+	Opt_norecovery, Opt_inode64, Opt_inode32, Opt_ikeep, Opt_largeio,
+	Opt_attr2, Opt_filestreams, Opt_quota, Opt_usrquota, Opt_grpquota,
+	Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, Opt_uqnoenforce,
+	Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, Opt_discard,
+	Opt_dax,
 };
 
 static const struct fs_parameter_spec xfs_param_specs[] = {
@@ -441,108 +393,6 @@ xfs_validate_params(
 	return 0;
 }
 
-/*
- * This function fills in xfs_mount_t fields based on mount args.
- * Note: the superblock has _not_ yet been read in.
- *
- * Note that this function leaks the various device name allocations on
- * failure.  The caller takes care of them.
- *
- * *sb is const because this is also used to test options on the remount
- * path, and we don't want this to have any side effects at remount time.
- * Today this function does not change *sb, but just to future-proof...
- */
-STATIC int
-xfs_parseargs(
-	struct xfs_mount	*mp,
-	char			*options)
-{
-	const struct super_block *sb = mp->m_super;
-	char			*p;
-
-	struct fs_context	fc;
-	struct xfs_fs_context	context;
-	struct xfs_fs_context	*ctx = &context;
-	int			ret;
-
-	/*
-	 * set up the mount name first so all the errors will refer to the
-	 * correct device.
-	 */
-	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
-	if (!mp->m_fsname)
-		return -ENOMEM;
-	mp->m_fsname_len = strlen(mp->m_fsname) + 1;
-
-	/*
-	 * Copy binary VFS mount flags we are interested in.
-	 */
-	if (sb_rdonly(sb))
-		mp->m_flags |= XFS_MOUNT_RDONLY;
-	if (sb->s_flags & SB_DIRSYNC)
-		mp->m_flags |= XFS_MOUNT_DIRSYNC;
-	if (sb->s_flags & SB_SYNCHRONOUS)
-		mp->m_flags |= XFS_MOUNT_WSYNC;
-
-	/*
-	 * Set some default flags that could be cleared by the mount option
-	 * parsing.
-	 */
-	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
-
-	/*
-	 * These can be overridden by the mount option parsing.
-	 */
-	mp->m_logbufs = -1;
-	mp->m_logbsize = -1;
-
-	if (!options) {
-		ret = xfs_validate_params(mp, ctx, true);
-		goto done;
-	}
-
-	memset(&fc, 0, sizeof(fc));
-	memset(&ctx, 0, sizeof(ctx));
-	fc.fs_private = ctx;
-	fc.s_fs_info = mp;
-
-	while ((p = strsep(&options, ",")) != NULL) {
-		struct fs_parameter	param;
-		char			*value;
-
-		if (!*p)
-			continue;
-
-		param.key = p;
-		param.type = fs_value_is_string;
-		param.size = 0;
-
-		value = strchr(p, '=');
-		if (value) {
-			if (value == p)
-				continue;
-			*value++ = 0;
-			param.size = strlen(value);
-			if (param.size > 0) {
-				param.string = kmemdup_nul(value,
-							   param.size,
-							   GFP_KERNEL);
-				if (!param.string)
-					return -ENOMEM;
-			}
-		}
-
-		ret = xfs_parse_param(&fc, &param);
-		kfree(param.string);
-		if (ret < 0)
-			goto done;
-	}
-
-	ret = xfs_validate_params(mp, ctx, false);
-done:
-	return ret;
-}
-
 struct proc_xfs_info {
 	uint64_t	flag;
 	char		*str;
@@ -1321,26 +1171,6 @@ xfs_quiesce_attr(
 	xfs_log_quiesce(mp);
 }
 
-STATIC int
-xfs_test_remount_options(
-	struct super_block	*sb,
-	char			*options)
-{
-	int			error = 0;
-	struct xfs_mount	*tmp_mp;
-
-	tmp_mp = kmem_zalloc(sizeof(*tmp_mp), KM_MAYFAIL);
-	if (!tmp_mp)
-		return -ENOMEM;
-
-	tmp_mp->m_super = sb;
-	error = xfs_parseargs(tmp_mp, options);
-	xfs_free_fsname(tmp_mp);
-	kmem_free(tmp_mp);
-
-	return error;
-}
-
 STATIC int
 xfs_remount_rw(
 	struct xfs_mount	*mp)
@@ -1444,84 +1274,6 @@ xfs_remount_ro(
 	return 0;
 }
 
-STATIC int
-xfs_fs_remount(
-	struct super_block	*sb,
-	int			*flags,
-	char			*options)
-{
-	struct xfs_mount	*mp = XFS_M(sb);
-	xfs_sb_t		*sbp = &mp->m_sb;
-	substring_t		args[MAX_OPT_ARGS];
-	char			*p;
-	int			error;
-
-	/* First, check for complete junk; i.e. invalid options */
-	error = xfs_test_remount_options(sb, options);
-	if (error)
-		return error;
-
-	sync_filesystem(sb);
-	while ((p = strsep(&options, ",")) != NULL) {
-		int token;
-
-		if (!*p)
-			continue;
-
-		token = match_token(p, tokens, args);
-		switch (token) {
-		case Opt_inode64:
-			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
-			mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
-			break;
-		case Opt_inode32:
-			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
-			mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
-			break;
-		default:
-			/*
-			 * Logically we would return an error here to prevent
-			 * users from believing they might have changed
-			 * mount options using remount which can't be changed.
-			 *
-			 * But unfortunately mount(8) adds all options from
-			 * mtab and fstab to the mount arguments in some cases
-			 * so we can't blindly reject options, but have to
-			 * check for each specified option if it actually
-			 * differs from the currently set option and only
-			 * reject it if that's the case.
-			 *
-			 * Until that is implemented we return success for
-			 * every remount request, and silently ignore all
-			 * options that we can't actually change.
-			 */
-#if 0
-			xfs_info(mp,
-		"mount option \"%s\" not supported for remount", p);
-			return -EINVAL;
-#else
-			break;
-#endif
-		}
-	}
-
-	/* ro -> rw */
-	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
-		error = xfs_remount_rw(mp);
-		if (error)
-			return error;
-	}
-
-	/* rw -> ro */
-	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) {
-		error = xfs_remount_ro(mp);
-		if (error)
-			return error;
-	}
-
-	return 0;
-}
-
 /*
  * There have been problems in the past with options passed from mount(8).
  *
@@ -1976,43 +1728,6 @@ __xfs_fs_fill_super(
 	goto out_free_sb;
 }
 
-STATIC int
-xfs_fs_fill_super(
-	struct super_block	*sb,
-	void			*data,
-	int			silent)
-{
-	struct xfs_mount	*mp = NULL;
-	int			error = -ENOMEM;
-
-	/*
-	 * allocate mp and do all low-level struct initializations before we
-	 * attach it to the super
-	 */
-	mp = xfs_mount_alloc();
-	if (!mp)
-		goto out;
-	mp->m_super = sb;
-	sb->s_fs_info = mp;
-
-	error = xfs_parseargs(mp, (char *)data);
-	if (error)
-		goto out_free_fsname;
-
-	error = __xfs_fs_fill_super(mp, silent);
-	if (error)
-		goto out_free_fsname;
-
-	return 0;
-
- out_free_fsname:
-	sb->s_fs_info = NULL;
-	xfs_free_fsname(mp);
-	kfree(mp);
-out:
-	return error;
-}
-
 STATIC int
 xfs_fill_super(
 	struct super_block	*sb,
@@ -2084,16 +1799,6 @@ xfs_fs_put_super(
 	kfree(mp);
 }
 
-STATIC struct dentry *
-xfs_fs_mount(
-	struct file_system_type	*fs_type,
-	int			flags,
-	const char		*dev_name,
-	void			*data)
-{
-	return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
-}
-
 static long
 xfs_fs_nr_cached_objects(
 	struct super_block	*sb,


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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-23  0:59 ` [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args Ian Kent
@ 2019-08-26 19:19   ` Eric Sandeen
  2019-08-26 19:31     ` Eric Sandeen
  2019-08-27 12:41   ` Brian Foster
  1 sibling, 1 reply; 58+ messages in thread
From: Eric Sandeen @ 2019-08-26 19:19 UTC (permalink / raw)
  To: Ian Kent, linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro

On 8/22/19 7:59 PM, Ian Kent wrote:
> Make xfs_parse_param() take arguments of the fs context operation
> .parse_param() in preperation for switching to use the file system
> mount context for mount.
> 
> The function fc_parse() only uses the file system context (fc here)
> when calling log macros warnf() and invalf() which in turn check
> only the fc->log field to determine if the message should be saved
> to a context buffer (for later retrival by userspace) or logged
> using printk().
> 
> Also the temporary function match_kstrtoint() is now unused, remove it.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |  187 ++++++++++++++++++++++++++++++----------------------
>  1 file changed, 108 insertions(+), 79 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 3ae29938dd89..754d2ccfd960 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -184,64 +184,62 @@ suffix_kstrtoint(const char *s, unsigned int base, int *res)
>  	return ret;
>  }
>  
> -STATIC int
> -match_kstrtoint(const substring_t *s, unsigned int base, int *res)
> -{
> -	const char	*value;
> -	int ret;
> -
> -	value = match_strdup(s);
> -	if (!value)
> -		return -ENOMEM;
> -	ret = suffix_kstrtoint(value, base, res);
> -	kfree(value);
> -	return ret;
> -}
> +struct xfs_fs_context {
> +	int	dsunit;
> +	int	dswidth;
> +	uint8_t	iosizelog;
> +};
>  
>  STATIC int
>  xfs_parse_param(
> -	int 			token,
> -	char			*p,
> -	substring_t		*args,
> -	struct xfs_mount	*mp,
> -	int			*dsunit,
> -	int			*dswidth,
> -	uint8_t			*iosizelog)
> +	struct fs_context	*fc,
> +	struct fs_parameter	*param)
>  {
> +	struct xfs_fs_context	*ctx = fc->fs_private;
> +	struct xfs_mount	*mp = fc->s_fs_info;
> +	struct fs_parse_result	result;
>  	int			iosize = 0;
> +	int			opt;
>  
> -	switch (token) {
> +	opt = fs_parse(fc, &xfs_fs_parameters, param, &result);
> +	if (opt < 0)
> +		return opt;
> +
> +	switch (opt) {
>  	case Opt_logbufs:
> -		if (match_int(args, &mp->m_logbufs))
> -			return -EINVAL;
> +		mp->m_logbufs = result.uint_32;
>  		break;

I'm not all that excited about how xfs_fs_parameters defines Opt_logbufs
as a u32 result, but we still have to hard-code the grabbing of the u32
result after fs_parse().  I know that's a core API thing but I wonder if
there's any way to connect it more strongly so they don't have to stay in
sync.

Perhaps a new function,

   mp->m_logbufs = fs_parse_result(&xfs_fs_parameters, &result);

and let fs_parse_result() pick the right part of the union?

Would be an api enhancement not for this patch I guess.

>  	case Opt_logbsize:
> -		if (match_kstrtoint(args, 10, &mp->m_logbsize))
> +		if (suffix_kstrtoint(param->string, 10, &mp->m_logbsize))
>  			return -EINVAL;
>  		break;
>  	case Opt_logdev:
>  		kfree(mp->m_logname);
> -		mp->m_logname = match_strdup(args);
> +		mp->m_logname = kstrdup(param->string, GFP_KERNEL);
>  		if (!mp->m_logname)
>  			return -ENOMEM;
>  		break;
>  	case Opt_rtdev:
>  		kfree(mp->m_rtname);
> -		mp->m_rtname = match_strdup(args);
> +		mp->m_rtname = kstrdup(param->string, GFP_KERNEL);
>  		if (!mp->m_rtname)
>  			return -ENOMEM;
>  		break;
>  	case Opt_allocsize:
>  	case Opt_biosize:
> -		if (match_kstrtoint(args, 10, &iosize))
> +		if (suffix_kstrtoint(param->string, 10, &iosize))
>  			return -EINVAL;
> -		*iosizelog = ffs(iosize) - 1;
> +		ctx->iosizelog = ffs(iosize) - 1;
>  		break;
>  	case Opt_grpid:
> +		if (result.negated)
> +			mp->m_flags &= ~XFS_MOUNT_GRPID;
> +		else
> +			mp->m_flags |= XFS_MOUNT_GRPID;
> +		break;

Is there any real advantage to this "fsparam_flag_no" / negated stuff?
I don't see any other filesystem using it (yet) and I'm not totally convinced
that this is any better, more readable, or more efficient than just keeping
the "Opt_nogrpid" stuff around.  Not a dealbreaker but just thinking out
loud... seems like this interface was a solution in search of a problem?

>  	case Opt_bsdgroups:
>  		mp->m_flags |= XFS_MOUNT_GRPID;
>  		break;
> -	case Opt_nogrpid:
>  	case Opt_sysvgroups:
>  		mp->m_flags &= ~XFS_MOUNT_GRPID;
>  		break;
> @@ -258,12 +256,10 @@ xfs_parse_param(
>  		mp->m_flags |= XFS_MOUNT_SWALLOC;
>  		break;
>  	case Opt_sunit:
> -		if (match_int(args, dsunit))
> -			return -EINVAL;
> +		ctx->dsunit = result.uint_32;
>  		break;
>  	case Opt_swidth:
> -		if (match_int(args, dswidth))
> -			return -EINVAL;
> +		ctx->dswidth = result.uint_32;
>  		break;
>  	case Opt_inode32:
>  		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> @@ -275,33 +271,38 @@ xfs_parse_param(
>  		mp->m_flags |= XFS_MOUNT_NOUUID;
>  		break;
>  	case Opt_ikeep:
> -		mp->m_flags |= XFS_MOUNT_IKEEP;
> -		break;
> -	case Opt_noikeep:
> -		mp->m_flags &= ~XFS_MOUNT_IKEEP;
> +		if (result.negated)
> +			mp->m_flags &= ~XFS_MOUNT_IKEEP;
> +		else
> +			mp->m_flags |= XFS_MOUNT_IKEEP;
>  		break;
>  	case Opt_largeio:
> -		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> -		break;
> -	case Opt_nolargeio:
> -		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +		if (result.negated)
> +			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +		else
> +			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
>  		break;
>  	case Opt_attr2:
> -		mp->m_flags |= XFS_MOUNT_ATTR2;
> -		break;
> -	case Opt_noattr2:
> -		mp->m_flags &= ~XFS_MOUNT_ATTR2;
> -		mp->m_flags |= XFS_MOUNT_NOATTR2;
> +		if (!result.negated) {
> +			mp->m_flags |= XFS_MOUNT_ATTR2;
> +		} else {
> +			mp->m_flags &= ~XFS_MOUNT_ATTR2;
> +			mp->m_flags |= XFS_MOUNT_NOATTR2;
> +		}
>  		break
>  	case Opt_filestreams:
>  		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
>  		break;
> -	case Opt_noquota:
> -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> -		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> -		break;
>  	case Opt_quota:
> +		if (!result.negated) {
> +			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> +					 XFS_UQUOTA_ENFD);
> +		} else {
> +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> +			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> +		}
> +		break;
>  	case Opt_uquota:
>  	case Opt_usrquota:
>  		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> @@ -331,10 +332,10 @@ xfs_parse_param(
>  		mp->m_qflags &= ~XFS_GQUOTA_ENFD;
>  		break;
>  	case Opt_discard:
> -		mp->m_flags |= XFS_MOUNT_DISCARD;
> -		break;
> -	case Opt_nodiscard:
> -		mp->m_flags &= ~XFS_MOUNT_DISCARD;
> +		if (result.negated)
> +			mp->m_flags &= ~XFS_MOUNT_DISCARD;
> +		else
> +			mp->m_flags |= XFS_MOUNT_DISCARD;
>  		break;
>  #ifdef CONFIG_FS_DAX
>  	case Opt_dax:
> @@ -342,7 +343,7 @@ xfs_parse_param(
>  		break;
>  #endif
>  	default:
> -		xfs_warn(mp, "unknown mount option [%s].", p);
> +		xfs_warn(mp, "unknown mount option [%s].", param->key);

Hm, we don't ever seem to get here:

# mount -o fweeeep /dev/pmem0p1 /mnt/test
mount: mount /dev/pmem0p1 on /mnt/test failed: Unknown error 519
# 

and nothing in dmesg.

we never get a default because fs_parse() returns an error and
we never drop into the case statement at all.

(again maybe this all goes away by the last patch...)

<and now after testing this, the kernel paniced.... :( >

>  		return -EINVAL;
>  	}
>  
> @@ -367,10 +368,10 @@ xfs_parseargs(
>  {
>  	const struct super_block *sb = mp->m_super;
>  	char			*p;
> -	substring_t		args[MAX_OPT_ARGS];
> -	int			dsunit = 0;
> -	int			dswidth = 0;
> -	uint8_t			iosizelog = 0;
> +
> +	struct fs_context	fc;
> +	struct xfs_fs_context	context;
> +	struct xfs_fs_context	*ctx = &context;
>  
>  	/*
>  	 * set up the mount name first so all the errors will refer to the
> @@ -406,17 +407,41 @@ xfs_parseargs(
>  	if (!options)
>  		goto done;
>  
> +	memset(&fc, 0, sizeof(fc));
> +	memset(&ctx, 0, sizeof(ctx));

I think you mean:

+	memset(ctx, 0, sizeof(*ctx));

or maybe better, just:

+ memset(&context, 0, sizeof(context));

here? Otherwise you're essentially just doing ctx = NULL (thanks djwong
for looking over my shoulder there) which then means fs_private is NULL,
and ...

Well, I was going to demonstrate that it probably oopses with certain mount
options, but actually I couldn't boot with patches applied up to this point:

[   18.491901] SGI XFS with ACLs, security attributes, realtime, scrub, repair, debug enabled
[   18.502444] XFS (dm-0): invalid log iosize: 184 [not 12-30]

Fixing up the problem above (which I thought would lead to a null ptr deref
but did not ...) I still fail to boot with:

[   18.191504] XFS (dm-0): alignment check failed: sunit/swidth vs. blocksize(4096)

This is because if you goto done on no options you do it before you've
initialized the context structure, so it grabs uninitialized values for all
the context fields.  Probably best to move the structure init right to the top
for clarity.

I think this all goes away by the last patch but we still want to make it
bisectable...

> +	fc.fs_private = ctx;
> +	fc.s_fs_info = mp;
> +
>  	while ((p = strsep(&options, ",")) != NULL) {
> -		int		token;
> -		int		ret;
> +		struct fs_parameter	param;
> +		char			*value;
> +		int			ret;
>  
>  		if (!*p)
>  			continue;
>  
> -		token = match_token(p, tokens, args);
> -		ret = xfs_parse_param(token, p, args, mp,
> -				      &dsunit, &dswidth, &iosizelog);
> -		if (ret)
> +		param.key = p;
> +		param.type = fs_value_is_string;
> +		param.size = 0;
> +
> +		value = strchr(p, '=');
> +		if (value) {
> +			if (value == p)
> +				continue;
> +			*value++ = 0;
> +			param.size = strlen(value);
> +			if (param.size > 0) {
> +				param.string = kmemdup_nul(value,
> +							   param.size,
> +							   GFP_KERNEL);
> +				if (!param.string)
> +					return -ENOMEM;
> +			}
> +		}
> +
> +		ret = xfs_parse_param(&fc, &param);
> +		kfree(param.string);
> +		if (ret < 0)
>  			return ret;
>  	}
>  
> @@ -429,7 +454,7 @@ xfs_parseargs(
>  		return -EINVAL;
>  	}
>  
> -	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
> +	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (ctx->dsunit || ctx->dswidth)) {

it'd be nice to reflow this to 80 cols or less
(maybe just drop the last space, or break the line at the &&)

>  		xfs_warn(mp,
>  	"sunit and swidth options incompatible with the noalign option");
>  		return -EINVAL;
> @@ -442,28 +467,28 @@ xfs_parseargs(
>  	}
>  #endif
>  
> -	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
> +	if ((ctx->dsunit && !ctx->dswidth) || (!ctx->dsunit && ctx->dswidth)) {
>  		xfs_warn(mp, "sunit and swidth must be specified together");
>  		return -EINVAL;
>  	}
>  
> -	if (dsunit && (dswidth % dsunit != 0)) {
> +	if (ctx->dsunit && (ctx->dswidth % ctx->dsunit != 0)) {
>  		xfs_warn(mp,
>  	"stripe width (%d) must be a multiple of the stripe unit (%d)",
> -			dswidth, dsunit);
> +			ctx->dswidth, ctx->dsunit);
>  		return -EINVAL;
>  	}
>  
>  done:
> -	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
> +	if (ctx->dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
>  		/*
>  		 * At this point the superblock has not been read
>  		 * in, therefore we do not know the block size.
>  		 * Before the mount call ends we will convert
>  		 * these to FSBs.
>  		 */
> -		mp->m_dalign = dsunit;
> -		mp->m_swidth = dswidth;
> +		mp->m_dalign = ctx->dsunit;
> +		mp->m_swidth = ctx->dswidth;
>  	}
>  
>  	if (mp->m_logbufs != -1 &&
> @@ -485,18 +510,18 @@ xfs_parseargs(
>  		return -EINVAL;
>  	}
>  
> -	if (iosizelog) {
> -		if (iosizelog > XFS_MAX_IO_LOG ||
> -		    iosizelog < XFS_MIN_IO_LOG) {
> +	if (ctx->iosizelog) {
> +		if (ctx->iosizelog > XFS_MAX_IO_LOG ||
> +		    ctx->iosizelog < XFS_MIN_IO_LOG) {
>  			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
> -				iosizelog, XFS_MIN_IO_LOG,
> +				ctx->iosizelog, XFS_MIN_IO_LOG,
>  				XFS_MAX_IO_LOG);
>  			return -EINVAL;
>  		}
>  
>  		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
> -		mp->m_readio_log = iosizelog;
> -		mp->m_writeio_log = iosizelog;
> +		mp->m_readio_log = ctx->iosizelog;
> +		mp->m_writeio_log = ctx->iosizelog;
>  	}
>  
>  	return 0;
> @@ -1914,6 +1939,10 @@ static const struct super_operations xfs_super_operations = {
>  	.free_cached_objects	= xfs_fs_free_cached_objects,
>  };
>  
> +static const struct fs_context_operations xfs_context_ops = {
> +	.parse_param = xfs_parse_param,
> +};

This seems weird in this patch, it's not used until
"xfs: mount-api - switch to new mount-api" so might want to move it there?


ok after testing a little I paniced the box, gonna go off and see what that's
all about now.

-Eric

> +
>  static struct file_system_type xfs_fs_type = {
>  	.owner			= THIS_MODULE,
>  	.name			= "xfs",
> 

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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-26 19:19   ` Eric Sandeen
@ 2019-08-26 19:31     ` Eric Sandeen
  2019-08-26 19:32       ` Eric Sandeen
  2019-08-30 10:23       ` Ian Kent
  0 siblings, 2 replies; 58+ messages in thread
From: Eric Sandeen @ 2019-08-26 19:31 UTC (permalink / raw)
  To: Ian Kent, linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro

On 8/26/19 2:19 PM, Eric Sandeen wrote:
>>  	case Opt_biosize:
>> -		if (match_kstrtoint(args, 10, &iosize))
>> +		if (suffix_kstrtoint(param->string, 10, &iosize))
>>  			return -EINVAL;
>> -		*iosizelog = ffs(iosize) - 1;
>> +		ctx->iosizelog = ffs(iosize) - 1;
>>  		break;
>>  	case Opt_grpid:
>> +		if (result.negated)
>> +			mp->m_flags &= ~XFS_MOUNT_GRPID;
>> +		else
>> +			mp->m_flags |= XFS_MOUNT_GRPID;
>> +		break;
> Is there any real advantage to this "fsparam_flag_no" / negated stuff?
> I don't see any other filesystem using it (yet) and I'm not totally convinced
> that this is any better, more readable, or more efficient than just keeping
> the "Opt_nogrpid" stuff around.  Not a dealbreaker but just thinking out
> loud... seems like this interface was a solution in search of a problem?

Also, at least as of this patch, it seems broken:

[xfstests-dev]# mount -o noikeep /dev/pmem0p1 /mnt/test
mount: mount /dev/pmem0p1 on /mnt/test failed: Unknown error 519

<dmesg shows nothing>

[xfstests-dev]# mount -o ikeep /dev/pmem0p1 /mnt/test
mount: wrong fs type, bad option, bad superblock on /dev/pmem0p1,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
[xfstests-dev]# dmesg | tail -n 1
[  282.281557] XFS: Unexpected value for 'ikeep'


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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-26 19:31     ` Eric Sandeen
@ 2019-08-26 19:32       ` Eric Sandeen
  2019-08-30 10:23       ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Eric Sandeen @ 2019-08-26 19:32 UTC (permalink / raw)
  To: Ian Kent, linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro



On 8/26/19 2:31 PM, Eric Sandeen wrote:
> On 8/26/19 2:19 PM, Eric Sandeen wrote:
>>>  	case Opt_biosize:
>>> -		if (match_kstrtoint(args, 10, &iosize))
>>> +		if (suffix_kstrtoint(param->string, 10, &iosize))
>>>  			return -EINVAL;
>>> -		*iosizelog = ffs(iosize) - 1;
>>> +		ctx->iosizelog = ffs(iosize) - 1;
>>>  		break;
>>>  	case Opt_grpid:
>>> +		if (result.negated)
>>> +			mp->m_flags &= ~XFS_MOUNT_GRPID;
>>> +		else
>>> +			mp->m_flags |= XFS_MOUNT_GRPID;
>>> +		break;
>> Is there any real advantage to this "fsparam_flag_no" / negated stuff?
>> I don't see any other filesystem using it (yet) and I'm not totally convinced
>> that this is any better, more readable, or more efficient than just keeping
>> the "Opt_nogrpid" stuff around.  Not a dealbreaker but just thinking out
>> loud... seems like this interface was a solution in search of a problem?
> 
> Also, at least as of this patch, it seems broken:
> 
> [xfstests-dev]# mount -o noikeep /dev/pmem0p1 /mnt/test
> mount: mount /dev/pmem0p1 on /mnt/test failed: Unknown error 519
> 
> <dmesg shows nothing>
> 
> [xfstests-dev]# mount -o ikeep /dev/pmem0p1 /mnt/test
> mount: wrong fs type, bad option, bad superblock on /dev/pmem0p1,
>        missing codepage or helper program, or other error
> 
>        In some cases useful info is found in syslog - try
>        dmesg | tail or so.
> [xfstests-dev]# dmesg | tail -n 1
> [  282.281557] XFS: Unexpected value for 'ikeep'

and it panics shortly after these failures.

[  378.761698] WARNING: CPU: 8 PID: 12477 at kernel/rcu/tree.c:2498 __call_rcu+0x1e9/0x290
[  378.770633] Modules linked in: macsec tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag xt_CHECKSUM iptable_mangle xt_MASQUERADE iptable_nat nf_nat xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ipt_REJECT nf_reject_ipv4 tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter intel_rapl_msr intel_rapl_common sunrpc x86_pkg_temp_thermal intel_powerclamp coretemp kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel nd_pmem nd_btt iTCO_wdt intel_cstate ipmi_si iTCO_vendor_support mei_me ipmi_devintf intel_uncore intel_rapl_perf mei ipmi_msghandler wmi nd_e820 libnvdimm pcspkr sg i2c_i801 ioatdma lpc_ich binfmt_misc ip_tables xfs(O) libcrc32c sd_mod mgag200 drm_vram_helper ttm drm_kms_helper syscopyarea igb crc32c_intel sysfillrect sysimgblt isci fb_sys_fops ptp libsas ahci pps_core drm scsi_transport_sas libahci dca i2c_algo_bit libata i2c_core dm_mirror dm_region_hash dm_log dm_mod
[  378.863955] CPU: 8 PID: 12477 Comm: bash Kdump: loaded Tainted: G           O      5.3.0-rc2+ #12
[  378.873860] Hardware name: Intel Corporation LH Pass/SVRBD-ROW_P, BIOS SE5C600.86B.02.01.SP06.050920141054 05/09/2014
[  378.885696] RIP: 0010:__call_rcu+0x1e9/0x290
[  378.890460] Code: 0f 84 8d 00 00 00 48 89 83 b0 00 00 00 48 8b 83 98 00 00 00 48 89 83 a8 00 00 00 e9 b4 fe ff ff e8 2c c8 ff ff e9 5f ff ff ff <0f> 0b 0f 1f 44 00 00 e9 31 fe ff ff 83 fa ff 0f 1f 84 00 00 00 00
[  378.911418] RSP: 0018:ffffc900070a3de0 EFLAGS: 00010206
[  378.917247] RAX: 0000000080000000 RBX: ffff888ffc6eade5 RCX: 0000000000000000
[  378.925210] RDX: 00000000ffffffff RSI: ffffffff81747450 RDI: ffff888ffc6eafbd
[  378.933174] RBP: ffff888ffc6eafbd R08: 0000000000000000 R09: ffff888ffc6eaec5
[  378.941135] R10: ffff88901567c880 R11: ffff889000844a10 R12: ffff888ffc6eafb5
[  378.949098] R13: ffff888103e20750 R14: ffffffff81747450 R15: 0000000000000000
[  378.957062] FS:  00007f08a102b740(0000) GS:ffff88901ea00000(0000) knlGS:0000000000000000
[  378.966092] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  378.972505] CR2: 00007f08a1037000 CR3: 0000000ffc77a004 CR4: 00000000001606e0
[  378.980469] Call Trace:
[  378.983208]  netlink_release+0x2b1/0x540
[  378.987586]  __sock_release+0x3d/0xc0
[  378.991673]  sock_close+0x11/0x20
[  378.995373]  __fput+0xbe/0x250
[  378.998784]  task_work_run+0x88/0xa0
[  379.002775]  exit_to_usermode_loop+0x77/0xc7
[  379.007537]  do_syscall_64+0x1a1/0x1d0
[  379.011721]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  379.017361] RIP: 0033:0x7f08a0714620
[  379.021348] Code: 00 64 c7 00 0d 00 00 00 b8 ff ff ff ff eb 90 b8 ff ff ff ff eb 89 0f 1f 40 00 83 3d 7d c9 2d 00 00 75 10 b8 03 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 9e c5 01 00 48 89 04 24
[  379.042303] RSP: 002b:00007ffdef07c748 EFLAGS: 00000246 ORIG_RAX: 0000000000000003
[  379.050752] RAX: 0000000000000000 RBX: 0000000001e0cc70 RCX: 00007f08a0714620
[  379.058715] RDX: 0000000000000000 RSI: 00007ffdef07c790 RDI: 0000000000000003
[  379.066679] RBP: 0000000000000003 R08: 00007ffdef07c6a0 R09: 00007ffdef07c5f0
[  379.074640] R10: 0000000000000008 R11: 0000000000000246 R12: 000000000000001c
[  379.082602] R13: 0000000000000001 R14: 0000000000000002 R15: 00007ffdef07c930
[  379.090565] ---[ end trace 0146f578893eb498 ]---

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

* Re: [PATCH v2 00/15] xfs: mount API patch series
  2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
                   ` (14 preceding siblings ...)
  2019-08-23  1:00 ` [PATCH v2 15/15] xfs: mount-api - remove legacy mount functions Ian Kent
@ 2019-08-26 19:33 ` Darrick J. Wong
  15 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2019-08-26 19:33 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:16AM +0800, Ian Kent wrote:
> This patch series adds support to xfs for the new kernel mount API
> as described in the LWN article at https://lwn.net/Articles/780267/.
> 
> In the article there's a lengthy description of the reasons for
> adopting the API and problems expected to be resolved by using it.
> 
> The series has been applied to the repository located at
> git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git, and built, and
> the xfstests suite run against it.
> 
> I didn't see any failures that look like they are related to mounting.

I don't think there are any xfstests that test mount option parsing in
anger.

--D

> Changes from the initial posting of the series:
> - changed .name to uppercase in fs_parameter_description to ensure
>   consistent error log messages between the vfs parser and the xfs
>   parameter parser.
> - clearify comment above xfs_parse_param() about when possibly
>   allocated mp->m_logname or mp->m_rtname are freed.
> - factor out xfs_remount_rw() and xfs_remount_ro() from  xfs_remount().
> - changed xfs_mount_alloc() to not set super block in xfs_mount so it
>   can be re-used when switching to the mount-api.
> - fixed don't check for NULL when calling kfree() in xfs_fc_free().
> - refactored xfs_parseargs() in an attempt to highlight the code
>   that actually changes in converting to use the new mount api.
> - dropped xfs-mount-api-rename-xfs_fill_super.patch, it didn't seem
>   necessary.
> - move comment about remount difficulties above xfs_reconfigure()
>   and increase line length to try and make the comment managable.
> - add patch vfs-Create-fs_context-aware-mount_bdev-replacement.patch
>   that adds the vfs_get_block_super() needed by the series.
> 
> The patch "vfs: Create fs_context-aware mount_bdev() replacement" is
> currently included in linux-next so there will be conflicts if this
> series is merged in the next merge window so please be aware of it.
> 
> ---
> 
> David Howells (1):
>       vfs: Create fs_context-aware mount_bdev() replacement
> 
> Ian Kent (14):
>       xfs: mount-api - add fs parameter description
>       xfs: mount-api - refactor suffix_kstrtoint()
>       xfs: mount-api - refactor xfs_parseags()
>       xfs: mount-api - make xfs_parse_param() take context .parse_param() args
>       xfs: mount-api - move xfs_parseargs() validation to a helper
>       xfs: mount-api - refactor xfs_fs_fill_super()
>       xfs: mount-api - add xfs_get_tree()
>       xfs: mount-api - add xfs_remount_rw() helper
>       xfs: mount-api - add xfs_remount_ro() helper
>       xfs: mount api - add xfs_reconfigure()
>       xfs: mount-api - add xfs_fc_free()
>       xfs: mount-api - dont set sb in xfs_mount_alloc()
>       xfs: mount-api - switch to new mount-api
>       xfs: mount-api - remove legacy mount functions
> 
> 
>  fs/fs_context.c            |    2 
>  fs/super.c                 |  111 +++++
>  fs/xfs/xfs_super.c         |  949 ++++++++++++++++++++++++--------------------
>  include/linux/fs_context.h |    9 
>  4 files changed, 631 insertions(+), 440 deletions(-)
> 
> --
> Ian

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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-08-23  0:59 ` [PATCH v2 02/15] xfs: mount-api - add fs parameter description Ian Kent
@ 2019-08-27 12:39   ` Brian Foster
  2019-08-30 10:31     ` Ian Kent
  2019-09-17  3:13     ` Ian Kent
  0 siblings, 2 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-27 12:39 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> The new mount-api uses an array of struct fs_parameter_spec for
> parameter parsing, create this table populated with the xfs mount
> parameters.
> 
> The new mount-api table definition is wider than the token based
> parameter table and interleaving the option description comments
> between each table line is much less readable than adding them to
> the end of each table entry. So add the option description comment
> to each entry line even though it causes quite a few of the entries
> to be longer than 80 characters.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   48 +++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index f9450235533c..74c88b92ce22 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -38,6 +38,8 @@
>  
>  #include <linux/magic.h>
>  #include <linux/parser.h>
> +#include <linux/fs_context.h>
> +#include <linux/fs_parser.h>
>  
>  static const struct super_operations xfs_super_operations;
>  struct bio_set xfs_ioend_bioset;
> @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-level xfs sysfs dir */
>  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs attrs */
>  #endif
>  
> -/*
> - * Table driven mount option parser.
> - */

Not sure why this is comment is removed here if the associated code is
staying put in this patch..?

>  enum {
>  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
>  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
> @@ -109,6 +108,49 @@ static const match_table_t tokens = {
>  	{Opt_err,	NULL},
>  };
>  
> +static const struct fs_parameter_spec xfs_param_specs[] = {
> + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS log buffers */
> + fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS log buffers */
> + fsparam_string ("logdev",     Opt_logdev),    /* log device */
> + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O device */
> + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of preferred buffered io size */

Hmm.. it looks like the difference between numerical values as strings
vs. numeric types is whether we support things like unit suffixes (i.e.
"64k"). That said, Opt_biosize uses suffix_kstrtoint() similar to
Opt_logbsize yet is defined here as a u32 (and Opt_allocsize falls into
the same parsing code but is a string). Is that wrong or am I just
missing something wrt to the type specifiers here?

Brian

> + fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs compatible mount */
> + fsparam_flag	("noalign",    Opt_noalign),   /* turn off stripe alignment */
> + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on stripe width allocation */
> + fsparam_u32	("sunit",      Opt_sunit),     /* data volume stripe unit */
> + fsparam_u32	("swidth",     Opt_swidth),    /* data volume stripe width */
> + fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore filesystem UUID */
> + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID from parent directory (or not) */
> + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from parent directory */
> + fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from current process */
> + fsparam_string ("allocsize",  Opt_allocsize), /* preferred allocation size */
> + fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS recovery */
> + fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be allocated anywhere */
> + fsparam_flag	("inode32",    Opt_inode32),   /* inode allocation limited to XFS_MAXINUMBER_32 */
> + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free (or keep) empty inode clusters */
> + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or do not report) large I/O sizes in stat() */
> + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do not) use attr2 attribute format */
> + fsparam_flag	("filestreams",Opt_filestreams), /* use filestreams allocator */
> + fsparam_flag_no("quota",      Opt_quota),     /* disk quotas (user) */
> + fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota enabled */
> + fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota enabled */
> + fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota enabled */
> + fsparam_flag	("uquota",     Opt_uquota),    /* user quota (IRIX variant) */
> + fsparam_flag	("gquota",     Opt_gquota),    /* group quota (IRIX variant) */
> + fsparam_flag	("pquota",     Opt_pquota),    /* project quota (IRIX variant) */
> + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota limit enforcement */
> + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota limit enforcement */
> + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project quota limit enforcement */
> + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as uqnoenforce */
> + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do not) not discard unused blocks */
> + fsparam_flag	("dax",	       Opt_dax),       /* Enable direct access to bdev pages */
> + {}
> +};
> +
> +static const struct fs_parameter_description xfs_fs_parameters = {
> +	.name		= "XFS",
> +	.specs		= xfs_param_specs,
> +};
>  
>  STATIC int
>  suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
> 

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

* Re: [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint()
  2019-08-23  0:59 ` [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint() Ian Kent
@ 2019-08-27 12:40   ` Brian Foster
  2019-08-30 10:33     ` Ian Kent
  2019-09-17  4:31     ` Ian Kent
  0 siblings, 2 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-27 12:40 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:33AM +0800, Ian Kent wrote:
> The mount-api doesn't have a "human unit" parse type yet so
> the options that have values like "10k" etc. still need to
> be converted by the fs.
> 
> But the value comes to the fs as a string (not a substring_t
> type) so there's a need to change the conversion function to
> take a character string instead.
> 
> After refactoring xfs_parseargs() and changing it to use
> xfs_parse_param() match_kstrtoint() will no longer be used
> and will be removed.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   22 ++++++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 74c88b92ce22..49c87fb921f1 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -153,13 +153,13 @@ static const struct fs_parameter_description xfs_fs_parameters = {
>  };
>  
>  STATIC int
> -suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
> +suffix_kstrtoint(const char *s, unsigned int base, int *res)
>  {
>  	int	last, shift_left_factor = 0, _res;
>  	char	*value;
>  	int	ret = 0;
>  
> -	value = match_strdup(s);
> +	value = kstrdup(s, GFP_KERNEL);
>  	if (!value)
>  		return -ENOMEM;
>  
> @@ -184,6 +184,20 @@ suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
>  	return ret;
>  }
>  
> +STATIC int
> +match_kstrtoint(const substring_t *s, unsigned int base, int *res)
> +{
> +	const char	*value;
> +	int ret;
> +
> +	value = match_strdup(s);
> +	if (!value)
> +		return -ENOMEM;
> +	ret = suffix_kstrtoint(value, base, res);
> +	kfree(value);
> +	return ret;
> +}
> +

I guess the use case isn't clear to me yet and it's not critical if this
code is going away by the end of the series, but why not refactor into a
__suffix_kstrtoint(char *s, ...) variant that accepts an already
duplicated string so we don't have to duplicate each string twice in the
match_kstrtoint() case?

Brian

>  /*
>   * This function fills in xfs_mount_t fields based on mount args.
>   * Note: the superblock has _not_ yet been read in.
> @@ -255,7 +269,7 @@ xfs_parseargs(
>  				return -EINVAL;
>  			break;
>  		case Opt_logbsize:
> -			if (suffix_kstrtoint(args, 10, &mp->m_logbsize))
> +			if (match_kstrtoint(args, 10, &mp->m_logbsize))
>  				return -EINVAL;
>  			break;
>  		case Opt_logdev:
> @@ -272,7 +286,7 @@ xfs_parseargs(
>  			break;
>  		case Opt_allocsize:
>  		case Opt_biosize:
> -			if (suffix_kstrtoint(args, 10, &iosize))
> +			if (match_kstrtoint(args, 10, &iosize))
>  				return -EINVAL;
>  			iosizelog = ffs(iosize) - 1;
>  			break;
> 

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

* Re: [PATCH v2 04/15] xfs: mount-api - refactor xfs_parseags()
  2019-08-23  0:59 ` [PATCH v2 04/15] xfs: mount-api - refactor xfs_parseags() Ian Kent
@ 2019-08-27 12:40   ` Brian Foster
  0 siblings, 0 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-27 12:40 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:38AM +0800, Ian Kent wrote:
> Refactor xfs_parseags(), move the entire token case block to a
> separate function in an attempt to highlight the code that
> actually changes in converting to use the new mount api.
> 
> The only changes are what's needed to communicate the variables
> dsunit, dswidth and iosizelog back to xfs_parseags().
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---

Looks Ok:

Reviewed-by: Brian Foster <bfoster@redhat.com>

>  fs/xfs/xfs_super.c |  292 ++++++++++++++++++++++++++++------------------------
>  1 file changed, 156 insertions(+), 136 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 49c87fb921f1..3ae29938dd89 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -198,6 +198,157 @@ match_kstrtoint(const substring_t *s, unsigned int base, int *res)
>  	return ret;
>  }
>  
> +STATIC int
> +xfs_parse_param(
> +	int 			token,
> +	char			*p,
> +	substring_t		*args,
> +	struct xfs_mount	*mp,
> +	int			*dsunit,
> +	int			*dswidth,
> +	uint8_t			*iosizelog)
> +{
> +	int			iosize = 0;
> +
> +	switch (token) {
> +	case Opt_logbufs:
> +		if (match_int(args, &mp->m_logbufs))
> +			return -EINVAL;
> +		break;
> +	case Opt_logbsize:
> +		if (match_kstrtoint(args, 10, &mp->m_logbsize))
> +			return -EINVAL;
> +		break;
> +	case Opt_logdev:
> +		kfree(mp->m_logname);
> +		mp->m_logname = match_strdup(args);
> +		if (!mp->m_logname)
> +			return -ENOMEM;
> +		break;
> +	case Opt_rtdev:
> +		kfree(mp->m_rtname);
> +		mp->m_rtname = match_strdup(args);
> +		if (!mp->m_rtname)
> +			return -ENOMEM;
> +		break;
> +	case Opt_allocsize:
> +	case Opt_biosize:
> +		if (match_kstrtoint(args, 10, &iosize))
> +			return -EINVAL;
> +		*iosizelog = ffs(iosize) - 1;
> +		break;
> +	case Opt_grpid:
> +	case Opt_bsdgroups:
> +		mp->m_flags |= XFS_MOUNT_GRPID;
> +		break;
> +	case Opt_nogrpid:
> +	case Opt_sysvgroups:
> +		mp->m_flags &= ~XFS_MOUNT_GRPID;
> +		break;
> +	case Opt_wsync:
> +		mp->m_flags |= XFS_MOUNT_WSYNC;
> +		break;
> +	case Opt_norecovery:
> +		mp->m_flags |= XFS_MOUNT_NORECOVERY;
> +		break;
> +	case Opt_noalign:
> +		mp->m_flags |= XFS_MOUNT_NOALIGN;
> +		break;
> +	case Opt_swalloc:
> +		mp->m_flags |= XFS_MOUNT_SWALLOC;
> +		break;
> +	case Opt_sunit:
> +		if (match_int(args, dsunit))
> +			return -EINVAL;
> +		break;
> +	case Opt_swidth:
> +		if (match_int(args, dswidth))
> +			return -EINVAL;
> +		break;
> +	case Opt_inode32:
> +		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> +		break;
> +	case Opt_inode64:
> +		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> +		break;
> +	case Opt_nouuid:
> +		mp->m_flags |= XFS_MOUNT_NOUUID;
> +		break;
> +	case Opt_ikeep:
> +		mp->m_flags |= XFS_MOUNT_IKEEP;
> +		break;
> +	case Opt_noikeep:
> +		mp->m_flags &= ~XFS_MOUNT_IKEEP;
> +		break;
> +	case Opt_largeio:
> +		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> +		break;
> +	case Opt_nolargeio:
> +		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +		break;
> +	case Opt_attr2:
> +		mp->m_flags |= XFS_MOUNT_ATTR2;
> +		break;
> +	case Opt_noattr2:
> +		mp->m_flags &= ~XFS_MOUNT_ATTR2;
> +		mp->m_flags |= XFS_MOUNT_NOATTR2;
> +		break;
> +	case Opt_filestreams:
> +		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
> +		break;
> +	case Opt_noquota:
> +		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> +		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> +		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> +		break;
> +	case Opt_quota:
> +	case Opt_uquota:
> +	case Opt_usrquota:
> +		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> +				 XFS_UQUOTA_ENFD);
> +		break;
> +	case Opt_qnoenforce:
> +	case Opt_uqnoenforce:
> +		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
> +		mp->m_qflags &= ~XFS_UQUOTA_ENFD;
> +		break;
> +	case Opt_pquota:
> +	case Opt_prjquota:
> +		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
> +				 XFS_PQUOTA_ENFD);
> +		break;
> +	case Opt_pqnoenforce:
> +		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
> +		mp->m_qflags &= ~XFS_PQUOTA_ENFD;
> +		break;
> +	case Opt_gquota:
> +	case Opt_grpquota:
> +		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
> +				 XFS_GQUOTA_ENFD);
> +		break;
> +	case Opt_gqnoenforce:
> +		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
> +		mp->m_qflags &= ~XFS_GQUOTA_ENFD;
> +		break;
> +	case Opt_discard:
> +		mp->m_flags |= XFS_MOUNT_DISCARD;
> +		break;
> +	case Opt_nodiscard:
> +		mp->m_flags &= ~XFS_MOUNT_DISCARD;
> +		break;
> +#ifdef CONFIG_FS_DAX
> +	case Opt_dax:
> +		mp->m_flags |= XFS_MOUNT_DAX;
> +		break;
> +#endif
> +	default:
> +		xfs_warn(mp, "unknown mount option [%s].", p);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * This function fills in xfs_mount_t fields based on mount args.
>   * Note: the superblock has _not_ yet been read in.
> @@ -219,7 +370,6 @@ xfs_parseargs(
>  	substring_t		args[MAX_OPT_ARGS];
>  	int			dsunit = 0;
>  	int			dswidth = 0;
> -	int			iosize = 0;
>  	uint8_t			iosizelog = 0;
>  
>  	/*
> @@ -258,146 +408,16 @@ xfs_parseargs(
>  
>  	while ((p = strsep(&options, ",")) != NULL) {
>  		int		token;
> +		int		ret;
>  
>  		if (!*p)
>  			continue;
>  
>  		token = match_token(p, tokens, args);
> -		switch (token) {
> -		case Opt_logbufs:
> -			if (match_int(args, &mp->m_logbufs))
> -				return -EINVAL;
> -			break;
> -		case Opt_logbsize:
> -			if (match_kstrtoint(args, 10, &mp->m_logbsize))
> -				return -EINVAL;
> -			break;
> -		case Opt_logdev:
> -			kfree(mp->m_logname);
> -			mp->m_logname = match_strdup(args);
> -			if (!mp->m_logname)
> -				return -ENOMEM;
> -			break;
> -		case Opt_rtdev:
> -			kfree(mp->m_rtname);
> -			mp->m_rtname = match_strdup(args);
> -			if (!mp->m_rtname)
> -				return -ENOMEM;
> -			break;
> -		case Opt_allocsize:
> -		case Opt_biosize:
> -			if (match_kstrtoint(args, 10, &iosize))
> -				return -EINVAL;
> -			iosizelog = ffs(iosize) - 1;
> -			break;
> -		case Opt_grpid:
> -		case Opt_bsdgroups:
> -			mp->m_flags |= XFS_MOUNT_GRPID;
> -			break;
> -		case Opt_nogrpid:
> -		case Opt_sysvgroups:
> -			mp->m_flags &= ~XFS_MOUNT_GRPID;
> -			break;
> -		case Opt_wsync:
> -			mp->m_flags |= XFS_MOUNT_WSYNC;
> -			break;
> -		case Opt_norecovery:
> -			mp->m_flags |= XFS_MOUNT_NORECOVERY;
> -			break;
> -		case Opt_noalign:
> -			mp->m_flags |= XFS_MOUNT_NOALIGN;
> -			break;
> -		case Opt_swalloc:
> -			mp->m_flags |= XFS_MOUNT_SWALLOC;
> -			break;
> -		case Opt_sunit:
> -			if (match_int(args, &dsunit))
> -				return -EINVAL;
> -			break;
> -		case Opt_swidth:
> -			if (match_int(args, &dswidth))
> -				return -EINVAL;
> -			break;
> -		case Opt_inode32:
> -			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> -			break;
> -		case Opt_inode64:
> -			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> -			break;
> -		case Opt_nouuid:
> -			mp->m_flags |= XFS_MOUNT_NOUUID;
> -			break;
> -		case Opt_ikeep:
> -			mp->m_flags |= XFS_MOUNT_IKEEP;
> -			break;
> -		case Opt_noikeep:
> -			mp->m_flags &= ~XFS_MOUNT_IKEEP;
> -			break;
> -		case Opt_largeio:
> -			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> -			break;
> -		case Opt_nolargeio:
> -			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> -			break;
> -		case Opt_attr2:
> -			mp->m_flags |= XFS_MOUNT_ATTR2;
> -			break;
> -		case Opt_noattr2:
> -			mp->m_flags &= ~XFS_MOUNT_ATTR2;
> -			mp->m_flags |= XFS_MOUNT_NOATTR2;
> -			break;
> -		case Opt_filestreams:
> -			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
> -			break;
> -		case Opt_noquota:
> -			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> -			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> -			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> -			break;
> -		case Opt_quota:
> -		case Opt_uquota:
> -		case Opt_usrquota:
> -			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> -					 XFS_UQUOTA_ENFD);
> -			break;
> -		case Opt_qnoenforce:
> -		case Opt_uqnoenforce:
> -			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
> -			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
> -			break;
> -		case Opt_pquota:
> -		case Opt_prjquota:
> -			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
> -					 XFS_PQUOTA_ENFD);
> -			break;
> -		case Opt_pqnoenforce:
> -			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
> -			mp->m_qflags &= ~XFS_PQUOTA_ENFD;
> -			break;
> -		case Opt_gquota:
> -		case Opt_grpquota:
> -			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
> -					 XFS_GQUOTA_ENFD);
> -			break;
> -		case Opt_gqnoenforce:
> -			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
> -			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
> -			break;
> -		case Opt_discard:
> -			mp->m_flags |= XFS_MOUNT_DISCARD;
> -			break;
> -		case Opt_nodiscard:
> -			mp->m_flags &= ~XFS_MOUNT_DISCARD;
> -			break;
> -#ifdef CONFIG_FS_DAX
> -		case Opt_dax:
> -			mp->m_flags |= XFS_MOUNT_DAX;
> -			break;
> -#endif
> -		default:
> -			xfs_warn(mp, "unknown mount option [%s].", p);
> -			return -EINVAL;
> -		}
> +		ret = xfs_parse_param(token, p, args, mp,
> +				      &dsunit, &dswidth, &iosizelog);
> +		if (ret)
> +			return ret;
>  	}
>  
>  	/*
> 

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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-23  0:59 ` [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args Ian Kent
  2019-08-26 19:19   ` Eric Sandeen
@ 2019-08-27 12:41   ` Brian Foster
  2019-08-27 15:10     ` Darrick J. Wong
  2019-08-30 10:51     ` Ian Kent
  1 sibling, 2 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-27 12:41 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:43AM +0800, Ian Kent wrote:
> Make xfs_parse_param() take arguments of the fs context operation
> .parse_param() in preperation for switching to use the file system
> mount context for mount.
> 
> The function fc_parse() only uses the file system context (fc here)
> when calling log macros warnf() and invalf() which in turn check
> only the fc->log field to determine if the message should be saved
> to a context buffer (for later retrival by userspace) or logged
> using printk().
> 
> Also the temporary function match_kstrtoint() is now unused, remove it.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---

I see Eric had some feedback on this patch already. Some additional
notes (which may overlap)...

>  fs/xfs/xfs_super.c |  187 ++++++++++++++++++++++++++++++----------------------
>  1 file changed, 108 insertions(+), 79 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 3ae29938dd89..754d2ccfd960 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
...
> @@ -275,33 +271,38 @@ xfs_parse_param(
>  		mp->m_flags |= XFS_MOUNT_NOUUID;
>  		break;
>  	case Opt_ikeep:
> -		mp->m_flags |= XFS_MOUNT_IKEEP;
> -		break;
> -	case Opt_noikeep:
> -		mp->m_flags &= ~XFS_MOUNT_IKEEP;
> +		if (result.negated)
> +			mp->m_flags &= ~XFS_MOUNT_IKEEP;
> +		else
> +			mp->m_flags |= XFS_MOUNT_IKEEP;
>  		break;
>  	case Opt_largeio:
> -		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> -		break;
> -	case Opt_nolargeio:
> -		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +		if (result.negated)
> +			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> +		else
> +			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
>  		break;
>  	case Opt_attr2:
> -		mp->m_flags |= XFS_MOUNT_ATTR2;
> -		break;
> -	case Opt_noattr2:
> -		mp->m_flags &= ~XFS_MOUNT_ATTR2;
> -		mp->m_flags |= XFS_MOUNT_NOATTR2;
> +		if (!result.negated) {
> +			mp->m_flags |= XFS_MOUNT_ATTR2;
> +		} else {
> +			mp->m_flags &= ~XFS_MOUNT_ATTR2;
> +			mp->m_flags |= XFS_MOUNT_NOATTR2;
> +		}

Eric's comments aside, it would be nice to have some consistency between
the various result.negated checks (i.e. 'if (negated)' vs 'if
(!negated)').

>  		break;
>  	case Opt_filestreams:
>  		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
>  		break;
> -	case Opt_noquota:
> -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> -		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> -		break;
>  	case Opt_quota:
> +		if (!result.negated) {
> +			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> +					 XFS_UQUOTA_ENFD);
> +		} else {
> +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> +			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> +		}
> +		break;
>  	case Opt_uquota:
>  	case Opt_usrquota:
>  		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
...
> @@ -367,10 +368,10 @@ xfs_parseargs(
>  {
>  	const struct super_block *sb = mp->m_super;
>  	char			*p;
> -	substring_t		args[MAX_OPT_ARGS];
> -	int			dsunit = 0;
> -	int			dswidth = 0;
> -	uint8_t			iosizelog = 0;
> +
> +	struct fs_context	fc;
> +	struct xfs_fs_context	context;
> +	struct xfs_fs_context	*ctx = &context;

I don't really see the point for having a separate pointer variable
based on the code so far. Why not just do:

	struct xfs_fs_context	ctx = {0,};

... and pass by reference where necessary?

>  
>  	/*
>  	 * set up the mount name first so all the errors will refer to the
> @@ -406,17 +407,41 @@ xfs_parseargs(
>  	if (!options)
>  		goto done;
>  
> +	memset(&fc, 0, sizeof(fc));
> +	memset(&ctx, 0, sizeof(ctx));
> +	fc.fs_private = ctx;
> +	fc.s_fs_info = mp;
> +
>  	while ((p = strsep(&options, ",")) != NULL) {
> -		int		token;
> -		int		ret;
> +		struct fs_parameter	param;
> +		char			*value;
> +		int			ret;
>  
>  		if (!*p)
>  			continue;
>  
> -		token = match_token(p, tokens, args);
> -		ret = xfs_parse_param(token, p, args, mp,
> -				      &dsunit, &dswidth, &iosizelog);
> -		if (ret)
> +		param.key = p;
> +		param.type = fs_value_is_string;
> +		param.size = 0;
> +
> +		value = strchr(p, '=');
> +		if (value) {
> +			if (value == p)
> +				continue;

What's the purpose of the above check? Why do we skip the param as
opposed to return an error or something?

> +			*value++ = 0;
> +			param.size = strlen(value);
> +			if (param.size > 0) {
> +				param.string = kmemdup_nul(value,
> +							   param.size,
> +							   GFP_KERNEL);
> +				if (!param.string)
> +					return -ENOMEM;
> +			}
> +		}
> +
> +		ret = xfs_parse_param(&fc, &param);
> +		kfree(param.string);
> +		if (ret < 0)
>  			return ret;
>  	}
>  
...
> @@ -1914,6 +1939,10 @@ static const struct super_operations xfs_super_operations = {
>  	.free_cached_objects	= xfs_fs_free_cached_objects,
>  };
>  
> +static const struct fs_context_operations xfs_context_ops = {
> +	.parse_param = xfs_parse_param,
> +};
> +

It's probably better to introduce this in the first patch where it's used.

Brian

>  static struct file_system_type xfs_fs_type = {
>  	.owner			= THIS_MODULE,
>  	.name			= "xfs",
> 

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

* Re: [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper
  2019-08-23  0:59 ` [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper Ian Kent
@ 2019-08-27 12:41   ` Brian Foster
  2019-08-30 10:55     ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Brian Foster @ 2019-08-27 12:41 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:49AM +0800, Ian Kent wrote:
> Move the validation code of xfs_parseargs() into a helper for later
> use within the mount context methods.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |  180 ++++++++++++++++++++++++++++------------------------
>  1 file changed, 98 insertions(+), 82 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 754d2ccfd960..7cdda17ee0ff 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
...
> @@ -442,89 +535,12 @@ xfs_parseargs(
>  		ret = xfs_parse_param(&fc, &param);
>  		kfree(param.string);
>  		if (ret < 0)
> -			return ret;
> -	}
> -
> -	/*
> -	 * no recovery flag requires a read-only mount
> -	 */
> -	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
> -	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
> -		xfs_warn(mp, "no-recovery mounts must be read-only.");
> -		return -EINVAL;
> -	}
> -
> -	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (ctx->dsunit || ctx->dswidth)) {
> -		xfs_warn(mp,
> -	"sunit and swidth options incompatible with the noalign option");
> -		return -EINVAL;
> -	}
> -
> -#ifndef CONFIG_XFS_QUOTA
> -	if (XFS_IS_QUOTA_RUNNING(mp)) {
> -		xfs_warn(mp, "quota support not available in this kernel.");
> -		return -EINVAL;
> -	}
> -#endif
> -
> -	if ((ctx->dsunit && !ctx->dswidth) || (!ctx->dsunit && ctx->dswidth)) {
> -		xfs_warn(mp, "sunit and swidth must be specified together");
> -		return -EINVAL;
> -	}
> -
> -	if (ctx->dsunit && (ctx->dswidth % ctx->dsunit != 0)) {
> -		xfs_warn(mp,
> -	"stripe width (%d) must be a multiple of the stripe unit (%d)",
> -			ctx->dswidth, ctx->dsunit);
> -		return -EINVAL;
> +			goto done;
>  	}
>  
> +	ret = xfs_validate_params(mp, ctx, false);
>  done:

This label now directly returns, which means it's not that useful in its
current form. How about we move the validate call below the label
(and perhaps rename the label to validate or some such) and just return
directly from the other user of done?

Brian

> -	if (ctx->dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
> -		/*
> -		 * At this point the superblock has not been read
> -		 * in, therefore we do not know the block size.
> -		 * Before the mount call ends we will convert
> -		 * these to FSBs.
> -		 */
> -		mp->m_dalign = ctx->dsunit;
> -		mp->m_swidth = ctx->dswidth;
> -	}
> -
> -	if (mp->m_logbufs != -1 &&
> -	    mp->m_logbufs != 0 &&
> -	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
> -	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
> -		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
> -			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
> -		return -EINVAL;
> -	}
> -	if (mp->m_logbsize != -1 &&
> -	    mp->m_logbsize !=  0 &&
> -	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
> -	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
> -	     !is_power_of_2(mp->m_logbsize))) {
> -		xfs_warn(mp,
> -			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
> -			mp->m_logbsize);
> -		return -EINVAL;
> -	}
> -
> -	if (ctx->iosizelog) {
> -		if (ctx->iosizelog > XFS_MAX_IO_LOG ||
> -		    ctx->iosizelog < XFS_MIN_IO_LOG) {
> -			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
> -				ctx->iosizelog, XFS_MIN_IO_LOG,
> -				XFS_MAX_IO_LOG);
> -			return -EINVAL;
> -		}
> -
> -		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
> -		mp->m_readio_log = ctx->iosizelog;
> -		mp->m_writeio_log = ctx->iosizelog;
> -	}
> -
> -	return 0;
> +	return ret;
>  }
>  
>  struct proc_xfs_info {
> 

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

* Re: [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super()
  2019-08-23  0:59 ` [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super() Ian Kent
@ 2019-08-27 12:42   ` Brian Foster
  2019-08-30 10:56     ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Brian Foster @ 2019-08-27 12:42 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:54AM +0800, Ian Kent wrote:
> Much of the code in xfs_fs_fill_super() will be used by the fill super
> function of the new mount-api.
> 
> So refactor the common code into a helper in an attempt to show what's
> actually changed.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   65 ++++++++++++++++++++++++++++++++++------------------
>  1 file changed, 42 insertions(+), 23 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 7cdda17ee0ff..d3fc9938987d 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
...
> @@ -1885,6 +1868,42 @@ xfs_fs_fill_super(
>  	goto out_free_sb;
>  }
>  
> +STATIC int
> +xfs_fs_fill_super(
> +	struct super_block	*sb,
> +	void			*data,
> +	int			silent)
> +{
> +	struct xfs_mount	*mp = NULL;
> +	int			error = -ENOMEM;
> +
> +	/*
> +	 * allocate mp and do all low-level struct initializations before we
> +	 * attach it to the super
> +	 */
> +	mp = xfs_mount_alloc(sb);
> +	if (!mp)
> +		goto out;
> +	sb->s_fs_info = mp;
> +
> +	error = xfs_parseargs(mp, (char *)data);
> +	if (error)
> +		goto out_free_fsname;
> +
> +	error = __xfs_fs_fill_super(mp, silent);
> +	if (error)
> +		goto out_free_fsname;
> +
> +	return 0;
> +
> + out_free_fsname:
> +	sb->s_fs_info = NULL;
> +	xfs_free_fsname(mp);
> +	kfree(mp);
> +out:
> +	return error;

I know this is copied from the existing function, but there's really no
need for an out label here. We can just return -ENOMEM in the one user
above. Aside from that nit the rest looks fine to me.

Brian

> +}
> +
>  STATIC void
>  xfs_fs_put_super(
>  	struct super_block	*sb)
> 

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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-27 12:41   ` Brian Foster
@ 2019-08-27 15:10     ` Darrick J. Wong
  2019-08-27 15:15       ` Eric Sandeen
  2019-08-30 10:51     ` Ian Kent
  1 sibling, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2019-08-27 15:10 UTC (permalink / raw)
  To: Brian Foster
  Cc: Ian Kent, linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, Aug 27, 2019 at 08:41:20AM -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:43AM +0800, Ian Kent wrote:
> > Make xfs_parse_param() take arguments of the fs context operation
> > .parse_param() in preperation for switching to use the file system
> > mount context for mount.
> > 
> > The function fc_parse() only uses the file system context (fc here)
> > when calling log macros warnf() and invalf() which in turn check
> > only the fc->log field to determine if the message should be saved
> > to a context buffer (for later retrival by userspace) or logged
> > using printk().
> > 
> > Also the temporary function match_kstrtoint() is now unused, remove it.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> 
> I see Eric had some feedback on this patch already. Some additional
> notes (which may overlap)...
> 
> >  fs/xfs/xfs_super.c |  187 ++++++++++++++++++++++++++++++----------------------
> >  1 file changed, 108 insertions(+), 79 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 3ae29938dd89..754d2ccfd960 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> ...
> > @@ -275,33 +271,38 @@ xfs_parse_param(
> >  		mp->m_flags |= XFS_MOUNT_NOUUID;
> >  		break;
> >  	case Opt_ikeep:
> > -		mp->m_flags |= XFS_MOUNT_IKEEP;
> > -		break;
> > -	case Opt_noikeep:
> > -		mp->m_flags &= ~XFS_MOUNT_IKEEP;
> > +		if (result.negated)
> > +			mp->m_flags &= ~XFS_MOUNT_IKEEP;
> > +		else
> > +			mp->m_flags |= XFS_MOUNT_IKEEP;
> >  		break;
> >  	case Opt_largeio:
> > -		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> > -		break;
> > -	case Opt_nolargeio:
> > -		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> > +		if (result.negated)
> > +			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> > +		else
> > +			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> >  		break;
> >  	case Opt_attr2:
> > -		mp->m_flags |= XFS_MOUNT_ATTR2;
> > -		break;
> > -	case Opt_noattr2:
> > -		mp->m_flags &= ~XFS_MOUNT_ATTR2;
> > -		mp->m_flags |= XFS_MOUNT_NOATTR2;
> > +		if (!result.negated) {
> > +			mp->m_flags |= XFS_MOUNT_ATTR2;
> > +		} else {
> > +			mp->m_flags &= ~XFS_MOUNT_ATTR2;
> > +			mp->m_flags |= XFS_MOUNT_NOATTR2;
> > +		}
> 
> Eric's comments aside, it would be nice to have some consistency between
> the various result.negated checks (i.e. 'if (negated)' vs 'if
> (!negated)').

Frankly I'd prefer "if (result.enabled)" or something affirmative so I
don't have to twist my brain around !negated == MAIN SCREEN TURN ON.

--D

> >  		break;
> >  	case Opt_filestreams:
> >  		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
> >  		break;
> > -	case Opt_noquota:
> > -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> > -		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> > -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> > -		break;
> >  	case Opt_quota:
> > +		if (!result.negated) {
> > +			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> > +					 XFS_UQUOTA_ENFD);
> > +		} else {
> > +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> > +			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> > +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> > +		}
> > +		break;
> >  	case Opt_uquota:
> >  	case Opt_usrquota:
> >  		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> ...
> > @@ -367,10 +368,10 @@ xfs_parseargs(
> >  {
> >  	const struct super_block *sb = mp->m_super;
> >  	char			*p;
> > -	substring_t		args[MAX_OPT_ARGS];
> > -	int			dsunit = 0;
> > -	int			dswidth = 0;
> > -	uint8_t			iosizelog = 0;
> > +
> > +	struct fs_context	fc;
> > +	struct xfs_fs_context	context;
> > +	struct xfs_fs_context	*ctx = &context;
> 
> I don't really see the point for having a separate pointer variable
> based on the code so far. Why not just do:
> 
> 	struct xfs_fs_context	ctx = {0,};
> 
> ... and pass by reference where necessary?
> 
> >  
> >  	/*
> >  	 * set up the mount name first so all the errors will refer to the
> > @@ -406,17 +407,41 @@ xfs_parseargs(
> >  	if (!options)
> >  		goto done;
> >  
> > +	memset(&fc, 0, sizeof(fc));
> > +	memset(&ctx, 0, sizeof(ctx));
> > +	fc.fs_private = ctx;
> > +	fc.s_fs_info = mp;
> > +
> >  	while ((p = strsep(&options, ",")) != NULL) {
> > -		int		token;
> > -		int		ret;
> > +		struct fs_parameter	param;
> > +		char			*value;
> > +		int			ret;
> >  
> >  		if (!*p)
> >  			continue;
> >  
> > -		token = match_token(p, tokens, args);
> > -		ret = xfs_parse_param(token, p, args, mp,
> > -				      &dsunit, &dswidth, &iosizelog);
> > -		if (ret)
> > +		param.key = p;
> > +		param.type = fs_value_is_string;
> > +		param.size = 0;
> > +
> > +		value = strchr(p, '=');
> > +		if (value) {
> > +			if (value == p)
> > +				continue;
> 
> What's the purpose of the above check? Why do we skip the param as
> opposed to return an error or something?
> 
> > +			*value++ = 0;
> > +			param.size = strlen(value);
> > +			if (param.size > 0) {
> > +				param.string = kmemdup_nul(value,
> > +							   param.size,
> > +							   GFP_KERNEL);
> > +				if (!param.string)
> > +					return -ENOMEM;
> > +			}
> > +		}
> > +
> > +		ret = xfs_parse_param(&fc, &param);
> > +		kfree(param.string);
> > +		if (ret < 0)
> >  			return ret;
> >  	}
> >  
> ...
> > @@ -1914,6 +1939,10 @@ static const struct super_operations xfs_super_operations = {
> >  	.free_cached_objects	= xfs_fs_free_cached_objects,
> >  };
> >  
> > +static const struct fs_context_operations xfs_context_ops = {
> > +	.parse_param = xfs_parse_param,
> > +};
> > +
> 
> It's probably better to introduce this in the first patch where it's used.
> 
> Brian
> 
> >  static struct file_system_type xfs_fs_type = {
> >  	.owner			= THIS_MODULE,
> >  	.name			= "xfs",
> > 

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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-27 15:10     ` Darrick J. Wong
@ 2019-08-27 15:15       ` Eric Sandeen
  2019-08-28  0:55         ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Eric Sandeen @ 2019-08-27 15:15 UTC (permalink / raw)
  To: Darrick J. Wong, Brian Foster
  Cc: Ian Kent, linux-xfs, Dave Chinner, David Howells, Al Viro

On 8/27/19 10:10 AM, Darrick J. Wong wrote:
>> Eric's comments aside, it would be nice to have some consistency between
>> the various result.negated checks (i.e. 'if (negated)' vs 'if
>> (!negated)').
> Frankly I'd prefer "if (result.enabled)" or something affirmative so I
> don't have to twist my brain around !negated == MAIN SCREEN TURN ON.
> 
> --D

I think it's probably possible to just keep explicit Opt_ikeep / Opt_noikeep
and dispense with the whole negated/enabled parsing, unless there's a downside
to doing that.  Not quite sure what's best, but it also exposes the inconsistency
we have with flag-ish options - some have negation of defaults as well as ability
to restate defaults, others don't.  (i.e. we have nouuid but not "uuid,"
norecovery but not "recovery," but we have ikeep/noikeep, attr2/noattr2...)

-Eric

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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-27 15:15       ` Eric Sandeen
@ 2019-08-28  0:55         ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-28  0:55 UTC (permalink / raw)
  To: Eric Sandeen, Darrick J. Wong, Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro

On Tue, 2019-08-27 at 10:15 -0500, Eric Sandeen wrote:
> On 8/27/19 10:10 AM, Darrick J. Wong wrote:
> > > Eric's comments aside, it would be nice to have some consistency
> > > between
> > > the various result.negated checks (i.e. 'if (negated)' vs 'if
> > > (!negated)').
> > Frankly I'd prefer "if (result.enabled)" or something affirmative
> > so I
> > don't have to twist my brain around !negated == MAIN SCREEN TURN
> > ON.
> > 
> > --D
> 
> I think it's probably possible to just keep explicit Opt_ikeep /
> Opt_noikeep
> and dispense with the whole negated/enabled parsing, unless there's a
> downside
> to doing that.  Not quite sure what's best, but it also exposes the
> inconsistency
> we have with flag-ish options - some have negation of defaults as
> well as ability
> to restate defaults, others don't.  (i.e. we have nouuid but not
> "uuid,"
> norecovery but not "recovery," but we have ikeep/noikeep,
> attr2/noattr2...)

As far as I know there's nothing that mandates using the type
that marks these as having a corresponding "no" option.

Not using it would also eliminate my compultion to always have
the short block in "if () {} else {}" first (at least mostly).

I'll do that when I'm fixing up the problems Eric has described.
Thanks Eric and Brian (and for that matter, Darrick too) for spending
time looking at the patches.

btw, I will get around to replying to the comments that have been
made, just not straight away, since I want to have a look at the
option parsing problem that Eric has seen first.

Ian


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

* Re: [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree()
  2019-08-23  0:59 ` [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree() Ian Kent
@ 2019-08-28 13:27   ` Brian Foster
  2019-08-30 11:01     ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:27 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 08:59:59AM +0800, Ian Kent wrote:
> Add the fs_context_operations method .get_tree that validates
> mount options and fills the super block as previously done
> by the file_system_type .mount method.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index d3fc9938987d..7de64808eb00 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1904,6 +1904,52 @@ xfs_fs_fill_super(
>  	return error;
>  }
>  
> +STATIC int
> +xfs_fill_super(
> +	struct super_block	*sb,
> +	struct fs_context	*fc)
> +{
> +	struct xfs_fs_context	*ctx = fc->fs_private;
> +	struct xfs_mount	*mp = sb->s_fs_info;
> +	int			silent = fc->sb_flags & SB_SILENT;
> +	int			error = -ENOMEM;
> +
> +	mp->m_super = sb;
> +
> +	/*
> +	 * set up the mount name first so all the errors will refer to the
> +	 * correct device.
> +	 */
> +	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
> +	if (!mp->m_fsname)
> +		return -ENOMEM;
> +	mp->m_fsname_len = strlen(mp->m_fsname) + 1;
> +
> +	error = xfs_validate_params(mp, ctx, false);
> +	if (error)
> +		goto out_free_fsname;
> +
> +	error = __xfs_fs_fill_super(mp, silent);
> +	if (error)
> +		goto out_free_fsname;
> +
> +	return 0;
> +
> + out_free_fsname:
> +	sb->s_fs_info = NULL;
> +	xfs_free_fsname(mp);
> +	kfree(mp);

So where is mp allocated in the updated mount sequence? Has that code
been added yet or does this tie into the existing fill_super sequence?
It's hard to tell because xfs_context_ops is still unused. It looks a
little strange to free mp here when it's presumably been allocated
somewhere else. If that is separate code, perhaps some of the patches
should be combined (i.e. even if just setup/teardown bits) for easier
review.

Brian

> +
> +	return error;
> +}
> +
> +STATIC int
> +xfs_get_tree(
> +	struct fs_context	*fc)
> +{
> +	return vfs_get_block_super(fc, xfs_fill_super);
> +}
> +
>  STATIC void
>  xfs_fs_put_super(
>  	struct super_block	*sb)
> @@ -1976,6 +2022,7 @@ static const struct super_operations xfs_super_operations = {
>  
>  static const struct fs_context_operations xfs_context_ops = {
>  	.parse_param = xfs_parse_param,
> +	.get_tree    = xfs_get_tree,
>  };
>  
>  static struct file_system_type xfs_fs_type = {
> 

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

* Re: [PATCH v2 09/15] xfs: mount-api - add xfs_remount_rw() helper
  2019-08-23  1:00 ` [PATCH v2 09/15] xfs: mount-api - add xfs_remount_rw() helper Ian Kent
@ 2019-08-28 13:27   ` Brian Foster
  0 siblings, 0 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:27 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 09:00:06AM +0800, Ian Kent wrote:
> Factor the remount read write code into a helper to simplify the
> subsequent change from the super block method .remount_fs to the
> mount-api fs_context_operations method .reconfigure.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---

Seems fine:

Reviewed-by: Brian Foster <bfoster@redhat.com>

>  fs/xfs/xfs_super.c |  115 +++++++++++++++++++++++++++++-----------------------
>  1 file changed, 64 insertions(+), 51 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 7de64808eb00..9f7300958a38 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1341,6 +1341,68 @@ xfs_test_remount_options(
>  	return error;
>  }
>  
> +STATIC int
> +xfs_remount_rw(
> +	struct xfs_mount	*mp)
> +{
> +	xfs_sb_t		*sbp = &mp->m_sb;
> +	int error;
> +
> +	if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
> +		xfs_warn(mp,
> +			"ro->rw transition prohibited on norecovery mount");
> +		return -EINVAL;
> +	}
> +
> +	if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
> +	    xfs_sb_has_ro_compat_feature(sbp, XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
> +		xfs_warn(mp,
> +	"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
> +			(sbp->sb_features_ro_compat &
> +				XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
> +		return -EINVAL;
> +	}
> +
> +	mp->m_flags &= ~XFS_MOUNT_RDONLY;
> +
> +	/*
> +	 * If this is the first remount to writeable state we
> +	 * might have some superblock changes to update.
> +	 */
> +	if (mp->m_update_sb) {
> +		error = xfs_sync_sb(mp, false);
> +		if (error) {
> +			xfs_warn(mp, "failed to write sb changes");
> +			return error;
> +		}
> +		mp->m_update_sb = false;
> +	}
> +
> +	/*
> +	 * Fill out the reserve pool if it is empty. Use the stashed
> +	 * value if it is non-zero, otherwise go with the default.
> +	 */
> +	xfs_restore_resvblks(mp);
> +	xfs_log_work_queue(mp);
> +
> +	/* Recover any CoW blocks that never got remapped. */
> +	error = xfs_reflink_recover_cow(mp);
> +	if (error) {
> +		xfs_err(mp,
> +			"Error %d recovering leftover CoW allocations.", error);
> +			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
> +		return error;
> +	}
> +	xfs_start_block_reaping(mp);
> +
> +	/* Create the per-AG metadata reservation pool .*/
> +	error = xfs_fs_reserve_ag_blocks(mp);
> +	if (error && error != -ENOSPC)
> +		return error;
> +
> +	return 0;
> +}
> +
>  STATIC int
>  xfs_fs_remount(
>  	struct super_block	*sb,
> @@ -1404,57 +1466,8 @@ xfs_fs_remount(
>  
>  	/* ro -> rw */
>  	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
> -		if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
> -			xfs_warn(mp,
> -		"ro->rw transition prohibited on norecovery mount");
> -			return -EINVAL;
> -		}
> -
> -		if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
> -		    xfs_sb_has_ro_compat_feature(sbp,
> -					XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
> -			xfs_warn(mp,
> -"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
> -				(sbp->sb_features_ro_compat &
> -					XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
> -			return -EINVAL;
> -		}
> -
> -		mp->m_flags &= ~XFS_MOUNT_RDONLY;
> -
> -		/*
> -		 * If this is the first remount to writeable state we
> -		 * might have some superblock changes to update.
> -		 */
> -		if (mp->m_update_sb) {
> -			error = xfs_sync_sb(mp, false);
> -			if (error) {
> -				xfs_warn(mp, "failed to write sb changes");
> -				return error;
> -			}
> -			mp->m_update_sb = false;
> -		}
> -
> -		/*
> -		 * Fill out the reserve pool if it is empty. Use the stashed
> -		 * value if it is non-zero, otherwise go with the default.
> -		 */
> -		xfs_restore_resvblks(mp);
> -		xfs_log_work_queue(mp);
> -
> -		/* Recover any CoW blocks that never got remapped. */
> -		error = xfs_reflink_recover_cow(mp);
> -		if (error) {
> -			xfs_err(mp,
> -	"Error %d recovering leftover CoW allocations.", error);
> -			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
> -			return error;
> -		}
> -		xfs_start_block_reaping(mp);
> -
> -		/* Create the per-AG metadata reservation pool .*/
> -		error = xfs_fs_reserve_ag_blocks(mp);
> -		if (error && error != -ENOSPC)
> +		error = xfs_remount_rw(mp);
> +		if (error)
>  			return error;
>  	}
>  
> 

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

* Re: [PATCH v2 10/15] xfs: mount-api - add xfs_remount_ro() helper
  2019-08-23  1:00 ` [PATCH v2 10/15] xfs: mount-api - add xfs_remount_ro() helper Ian Kent
@ 2019-08-28 13:27   ` Brian Foster
  0 siblings, 0 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:27 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 09:00:11AM +0800, Ian Kent wrote:
> Factor the remount read only code into a helper to simplify the
> subsequent change from the super block method .remount_fs to the
> mount-api fs_context_operations method .reconfigure.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---

Reviewed-by: Brian Foster <bfoster@redhat.com>

>  fs/xfs/xfs_super.c |   73 +++++++++++++++++++++++++++++++---------------------
>  1 file changed, 43 insertions(+), 30 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 9f7300958a38..76374d602257 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1403,6 +1403,47 @@ xfs_remount_rw(
>  	return 0;
>  }
>  
> +STATIC int
> +xfs_remount_ro(
> +	struct xfs_mount	*mp)
> +{
> +	int error;
> +
> +	/*
> +	 * Cancel background eofb scanning so it cannot race with the
> +	 * final log force+buftarg wait and deadlock the remount.
> +	 */
> +	xfs_stop_block_reaping(mp);
> +
> +	/* Get rid of any leftover CoW reservations... */
> +	error = xfs_icache_free_cowblocks(mp, NULL);
> +	if (error) {
> +		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
> +		return error;
> +	}
> +
> +	/* Free the per-AG metadata reservation pool. */
> +	error = xfs_fs_unreserve_ag_blocks(mp);
> +	if (error) {
> +		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
> +		return error;
> +	}
> +
> +	/*
> +	 * Before we sync the metadata, we need to free up the reserve
> +	 * block pool so that the used block count in the superblock on
> +	 * disk is correct at the end of the remount. Stash the current
> +	 * reserve pool size so that if we get remounted rw, we can
> +	 * return it to the same size.
> +	 */
> +	xfs_save_resvblks(mp);
> +
> +	xfs_quiesce_attr(mp);
> +	mp->m_flags |= XFS_MOUNT_RDONLY;
> +
> +	return 0;
> +}
> +
>  STATIC int
>  xfs_fs_remount(
>  	struct super_block	*sb,
> @@ -1473,37 +1514,9 @@ xfs_fs_remount(
>  
>  	/* rw -> ro */
>  	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) {
> -		/*
> -		 * Cancel background eofb scanning so it cannot race with the
> -		 * final log force+buftarg wait and deadlock the remount.
> -		 */
> -		xfs_stop_block_reaping(mp);
> -
> -		/* Get rid of any leftover CoW reservations... */
> -		error = xfs_icache_free_cowblocks(mp, NULL);
> -		if (error) {
> -			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
> -			return error;
> -		}
> -
> -		/* Free the per-AG metadata reservation pool. */
> -		error = xfs_fs_unreserve_ag_blocks(mp);
> -		if (error) {
> -			xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
> +		error = xfs_remount_ro(mp);
> +		if (error)
>  			return error;
> -		}
> -
> -		/*
> -		 * Before we sync the metadata, we need to free up the reserve
> -		 * block pool so that the used block count in the superblock on
> -		 * disk is correct at the end of the remount. Stash the current
> -		 * reserve pool size so that if we get remounted rw, we can
> -		 * return it to the same size.
> -		 */
> -		xfs_save_resvblks(mp);
> -
> -		xfs_quiesce_attr(mp);
> -		mp->m_flags |= XFS_MOUNT_RDONLY;
>  	}
>  
>  	return 0;
> 

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

* Re: [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure()
  2019-08-23  1:00 ` [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure() Ian Kent
@ 2019-08-28 13:28   ` Brian Foster
  2019-08-30 11:10     ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:28 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 09:00:16AM +0800, Ian Kent wrote:
> Add the fs_context_operations method .reconfigure that performs
> remount validation as previously done by the super_operations
> .remount_fs method.
> 
> An attempt has also been made to update the comment about options
> handling problems with mount(8) to reflect the current situation.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 76374d602257..aae0098fecab 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1522,6 +1522,89 @@ xfs_fs_remount(
>  	return 0;
>  }
>  
> +/*
> + * There have been problems in the past with options passed from mount(8).
> + *
> + * The problem being that options passed by mount(8) in the case where only
> + * the the mount point path is given would consist of the existing fstab
> + * options with the options from mtab for the current mount merged in and
> + * the options given on the command line last. But the result couldn't be
> + * relied upon to accurately reflect the current mount options so that
> + * rejecting options that can't be changed on reconfigure could erronously
> + * cause mount failure.
> + *
> + * The mount-api uses a legacy mount options handler in the VFS to handle
> + * mount(8) so these options will continue to be passed. Even if mount(8)
> + * is updated to use fsopen()/fsconfig()/fsmount() it's likely to continue
> + * to set the existing options so options problems with reconfigure could
> + * continue.
> + *
> + * For the longest time mtab locking was a problem and this could have been
> + * one possible cause. It's also possible there could have been options
> + * order problems.
> + *
> + * That has changed now as mtab is a link to the proc file system mount
> + * table so mtab options should be always accurate.
> + *
> + * Consulting the util-linux maintainer (Karel Zak) he is confident that,
> + * in this case, the options passed by mount(8) will be those of the current
> + * mount and the options order should be a correct merge of fstab and mtab
> + * options, and new options given on the command line.
> + *
> + * So, in theory, it should be possible to compare incoming options and
> + * return an error for options that differ from the current mount and can't
> + * be changed on reconfigure to prevent users from believing they might have
> + * changed mount options using remount which can't be changed.
> + *
> + * But for now continue to return success for every reconfigure request, and
> + * silently ignore all options that can't actually be changed.
> + */

This seems like all good information for a commit log description or
perhaps to land in a common header where some of these fs context bits
are declared, but overly broad for a function header comment for an XFS
callback. I'd more expect some information around the fundamental
difference between 'mp' and 'new_mp,' where those come from, what they
mean, etc. From the code, it seems like new_mp is transient and reflects
changes that we need to incorporate in the original mp..?

Brian

> +STATIC int
> +xfs_reconfigure(
> +	struct fs_context *fc)
> +{
> +	struct xfs_fs_context	*ctx = fc->fs_private;
> +	struct xfs_mount	*mp = XFS_M(fc->root->d_sb);
> +	struct xfs_mount        *new_mp = fc->s_fs_info;
> +	xfs_sb_t		*sbp = &mp->m_sb;
> +	int			flags = fc->sb_flags;
> +	int			error;
> +
> +	error = xfs_validate_params(new_mp, ctx, false);
> +	if (error)
> +		return error;
> +
> +	/* inode32 -> inode64 */
> +	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> +	    !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> +		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
> +	}
> +
> +	/* inode64 -> inode32 */
> +	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> +	    (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> +		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
> +	}
> +
> +	/* ro -> rw */
> +	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) {
> +		error = xfs_remount_rw(mp);
> +		if (error)
> +			return error;
> +	}
> +
> +	/* rw -> ro */
> +	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) {
> +		error = xfs_remount_ro(mp);
> +		if (error)
> +			return error;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * Second stage of a freeze. The data is already frozen so we only
>   * need to take care of the metadata. Once that's done sync the superblock
> @@ -2049,6 +2132,7 @@ static const struct super_operations xfs_super_operations = {
>  static const struct fs_context_operations xfs_context_ops = {
>  	.parse_param = xfs_parse_param,
>  	.get_tree    = xfs_get_tree,
> +	.reconfigure = xfs_reconfigure,
>  };
>  
>  static struct file_system_type xfs_fs_type = {
> 

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

* Re: [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free()
  2019-08-23  1:00 ` [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free() Ian Kent
@ 2019-08-28 13:28   ` Brian Foster
  2019-08-30 11:19     ` Ian Kent
  2019-08-30 11:20     ` Ian Kent
  0 siblings, 2 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:28 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 09:00:22AM +0800, Ian Kent wrote:
> Add the fs_context_operations method .free that performs fs
> context cleanup on context release.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index aae0098fecab..9976163dc537 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -2129,10 +2129,32 @@ static const struct super_operations xfs_super_operations = {
>  	.free_cached_objects	= xfs_fs_free_cached_objects,
>  };
>  
> +static void xfs_fc_free(struct fs_context *fc)
> +{
> +	struct xfs_fs_context	*ctx = fc->fs_private;
> +	struct xfs_mount	*mp = fc->s_fs_info;
> +
> +	if (mp) {
> +		/*
> +		 * If an error occurs before ownership the xfs_mount
> +		 * info struct is passed to xfs by the VFS (by assigning
> +		 * it to sb->s_fs_info and clearing the corresponding
> +		 * fs_context field, which is done before calling fill
> +		 * super via .get_tree()) there may be some strings to
> +		 * cleanup.
> +		 */

The code looks straightforward but I find the comment confusing. How can
the VFS pass ownership of the xfs_mount if it's an XFS private data
structure?

> +		kfree(mp->m_logname);
> +		kfree(mp->m_rtname);
> +		kfree(mp);
> +	}
> +	kfree(ctx);

Also, should we at least reassign associated fc pointers to NULL if we
have multiple places to free things like ctx or mp?

Brian

> +}
> +
>  static const struct fs_context_operations xfs_context_ops = {
>  	.parse_param = xfs_parse_param,
>  	.get_tree    = xfs_get_tree,
>  	.reconfigure = xfs_reconfigure,
> +	.free	     = xfs_fc_free,
>  };
>  
>  static struct file_system_type xfs_fs_type = {
> 

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

* Re: [PATCH v2 13/15] xfs: mount-api - dont set sb in xfs_mount_alloc()
  2019-08-23  1:00 ` [PATCH v2 13/15] xfs: mount-api - dont set sb in xfs_mount_alloc() Ian Kent
@ 2019-08-28 13:28   ` Brian Foster
  0 siblings, 0 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:28 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 09:00:27AM +0800, Ian Kent wrote:
> When changing to use the new mount api the super block won't be
> available when the xfs_mount info struct is allocated so move
> setting the super block in xfs_mount to xfs_fs_fill_super().
> 
> Also change xfs_mount_alloc() decalaration static -> STATIC.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |    8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 9976163dc537..d2a1a62a3edc 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1766,9 +1766,9 @@ xfs_destroy_percpu_counters(
>  	percpu_counter_destroy(&mp->m_delalloc_blks);
>  }
>  
> -static struct xfs_mount *
> +STATIC struct xfs_mount *
>  xfs_mount_alloc(
> -	struct super_block	*sb)
> +	void)

No need to have the void on a separate line. With that fixed up:

Reviewed-by: Brian Foster <bfoster@redhat.com>

>  {
>  	struct xfs_mount	*mp;
>  
> @@ -1776,7 +1776,6 @@ xfs_mount_alloc(
>  	if (!mp)
>  		return NULL;
>  
> -	mp->m_super = sb;
>  	spin_lock_init(&mp->m_sb_lock);
>  	spin_lock_init(&mp->m_agirotor_lock);
>  	INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
> @@ -1990,9 +1989,10 @@ xfs_fs_fill_super(
>  	 * allocate mp and do all low-level struct initializations before we
>  	 * attach it to the super
>  	 */
> -	mp = xfs_mount_alloc(sb);
> +	mp = xfs_mount_alloc();
>  	if (!mp)
>  		goto out;
> +	mp->m_super = sb;
>  	sb->s_fs_info = mp;
>  
>  	error = xfs_parseargs(mp, (char *)data);
> 

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

* Re: [PATCH v2 14/15] xfs: mount-api - switch to new mount-api
  2019-08-23  1:00 ` [PATCH v2 14/15] xfs: mount-api - switch to new mount-api Ian Kent
@ 2019-08-28 13:29   ` Brian Foster
  2019-08-28 13:34     ` Eric Sandeen
  2019-08-30 11:27     ` Ian Kent
  0 siblings, 2 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-28 13:29 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 23, 2019 at 09:00:32AM +0800, Ian Kent wrote:
> The infrastructure needed to use the new mount api is now
> in place, switch over to use it.
> 
> Signed-off-by: Ian Kent <raven@themaw.net>
> ---
>  fs/xfs/xfs_super.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 49 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index d2a1a62a3edc..fe7acd8ddd48 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -2123,7 +2123,6 @@ static const struct super_operations xfs_super_operations = {
>  	.freeze_fs		= xfs_fs_freeze,
>  	.unfreeze_fs		= xfs_fs_unfreeze,
>  	.statfs			= xfs_fs_statfs,
> -	.remount_fs		= xfs_fs_remount,

Not clear why this needs to go away here, or at least why we don't
remove the function at the same time.

Indeed.. this patch actually throws a couple warnings:

...
  CC [M]  fs/xfs/xfs_super.o
fs/xfs/xfs_super.c:2088:1: warning: ‘xfs_fs_mount’ defined but not used [-Wunused-function]
 xfs_fs_mount(
 ^~~~~~~~~~~~
fs/xfs/xfs_super.c:1448:1: warning: ‘xfs_fs_remount’ defined but not used [-Wunused-function]
 xfs_fs_remount(
 ^~~~~~~~~~~~~~
...

>  	.show_options		= xfs_fs_show_options,
>  	.nr_cached_objects	= xfs_fs_nr_cached_objects,
>  	.free_cached_objects	= xfs_fs_free_cached_objects,
> @@ -2157,10 +2156,58 @@ static const struct fs_context_operations xfs_context_ops = {
...
>  static struct file_system_type xfs_fs_type = {
>  	.owner			= THIS_MODULE,
>  	.name			= "xfs",
> -	.mount			= xfs_fs_mount,
> +	.init_fs_context	= xfs_init_fs_context,
> +	.parameters		= &xfs_fs_parameters,

Just a random observation.. we have a .name == "xfs" field here and the
parameters struct has a .name == "XFS" field. Perhaps we should be
consistent?

Brian

>  	.kill_sb		= kill_block_super,
>  	.fs_flags		= FS_REQUIRES_DEV,
>  };
> 

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

* Re: [PATCH v2 14/15] xfs: mount-api - switch to new mount-api
  2019-08-28 13:29   ` Brian Foster
@ 2019-08-28 13:34     ` Eric Sandeen
  2019-08-30 11:30       ` Ian Kent
  2019-08-30 11:27     ` Ian Kent
  1 sibling, 1 reply; 58+ messages in thread
From: Eric Sandeen @ 2019-08-28 13:34 UTC (permalink / raw)
  To: Brian Foster, Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro



On 8/28/19 8:29 AM, Brian Foster wrote:
>>  static struct file_system_type xfs_fs_type = {
>>  	.owner			= THIS_MODULE,
>>  	.name			= "xfs",
>> -	.mount			= xfs_fs_mount,
>> +	.init_fs_context	= xfs_init_fs_context,
>> +	.parameters		= &xfs_fs_parameters,
> Just a random observation.. we have a .name == "xfs" field here and the
> parameters struct has a .name == "XFS" field. Perhaps we should be
> consistent?
> 
> Brian
> 

I sent a patch to fsdevel to just remove the .name from the new mount parameters
structure; it's not had any attention yet.  But I had the same concerns about
consistency if we have to copy the same name to multiple places.

[PATCH] fs: fs_parser: remove fs_parameter_description name field

-Eric

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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-26 19:31     ` Eric Sandeen
  2019-08-26 19:32       ` Eric Sandeen
@ 2019-08-30 10:23       ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 10:23 UTC (permalink / raw)
  To: Eric Sandeen, linux-xfs; +Cc: Dave Chinner, David Howells, Al Viro

On Mon, 2019-08-26 at 14:31 -0500, Eric Sandeen wrote:

Finally got time to start looking at this.

> On 8/26/19 2:19 PM, Eric Sandeen wrote:
> > >  	case Opt_biosize:
> > > -		if (match_kstrtoint(args, 10, &iosize))
> > > +		if (suffix_kstrtoint(param->string, 10, &iosize))
> > >  			return -EINVAL;
> > > -		*iosizelog = ffs(iosize) - 1;
> > > +		ctx->iosizelog = ffs(iosize) - 1;
> > >  		break;
> > >  	case Opt_grpid:
> > > +		if (result.negated)
> > > +			mp->m_flags &= ~XFS_MOUNT_GRPID;
> > > +		else
> > > +			mp->m_flags |= XFS_MOUNT_GRPID;
> > > +		break;
> > Is there any real advantage to this "fsparam_flag_no" / negated
> > stuff?
> > I don't see any other filesystem using it (yet) and I'm not totally
> > convinced
> > that this is any better, more readable, or more efficient than just
> > keeping
> > the "Opt_nogrpid" stuff around.  Not a dealbreaker but just
> > thinking out
> > loud... seems like this interface was a solution in search of a
> > problem?
> 
> Also, at least as of this patch, it seems broken:
> 
> [xfstests-dev]# mount -o noikeep /dev/pmem0p1 /mnt/test
> mount: mount /dev/pmem0p1 on /mnt/test failed: Unknown error 519
> 
> <dmesg shows nothing>
> 
> [xfstests-dev]# mount -o ikeep /dev/pmem0p1 /mnt/test
> mount: wrong fs type, bad option, bad superblock on /dev/pmem0p1,
>        missing codepage or helper program, or other error
> 
>        In some cases useful info is found in syslog - try
>        dmesg | tail or so.
> [xfstests-dev]# dmesg | tail -n 1
> [  282.281557] XFS: Unexpected value for 'ikeep'

Bizare, everything I'm looking at says this case shouldn't trigger!
Think I'm going to need to burn some grey cells on this, ;)

Ian


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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-08-27 12:39   ` Brian Foster
@ 2019-08-30 10:31     ` Ian Kent
  2019-08-30 11:56       ` Brian Foster
  2019-09-17  3:13     ` Ian Kent
  1 sibling, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-30 10:31 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:39 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> > The new mount-api uses an array of struct fs_parameter_spec for
> > parameter parsing, create this table populated with the xfs mount
> > parameters.
> > 
> > The new mount-api table definition is wider than the token based
> > parameter table and interleaving the option description comments
> > between each table line is much less readable than adding them to
> > the end of each table entry. So add the option description comment
> > to each entry line even though it causes quite a few of the entries
> > to be longer than 80 characters.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   48
> > +++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 45 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index f9450235533c..74c88b92ce22 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -38,6 +38,8 @@
> >  
> >  #include <linux/magic.h>
> >  #include <linux/parser.h>
> > +#include <linux/fs_context.h>
> > +#include <linux/fs_parser.h>
> >  
> >  static const struct super_operations xfs_super_operations;
> >  struct bio_set xfs_ioend_bioset;
> > @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-
> > level xfs sysfs dir */
> >  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs
> > attrs */
> >  #endif
> >  
> > -/*
> > - * Table driven mount option parser.
> > - */

You would rather it be kept?

Strictly speaking it's still a table driven parser so it
could be kept.

I just thought it was a useles comment since it doesn't add
value in terms of understanding what's going on, IOW I think
it's just noise.

> 
> Not sure why this is comment is removed here if the associated code
> is
> staying put in this patch..?
> 
> >  enum {
> >  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
> >  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth,
> > Opt_nouuid,
> > @@ -109,6 +108,49 @@ static const match_table_t tokens = {
> >  	{Opt_err,	NULL},
> >  };
> >  
> > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS
> > log buffers */
> > + fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS log
> > buffers */
> > + fsparam_string ("logdev",     Opt_logdev),    /* log device */
> > + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O
> > device */
> > + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of
> > preferred buffered io size */
> 
> Hmm.. it looks like the difference between numerical values as
> strings
> vs. numeric types is whether we support things like unit suffixes
> (i.e.
> "64k"). That said, Opt_biosize uses suffix_kstrtoint() similar to
> Opt_logbsize yet is defined here as a u32 (and Opt_allocsize falls
> into
> the same parsing code but is a string). Is that wrong or am I just
> missing something wrt to the type specifiers here?

Dave Chinner (and IIRC Darrick) made roughly comments about the
need for human unit values in the parser.

I know David has some patches to implement this but I hadn't
seen anything posted, he's probably over loaded with higher
priority work atm. so this is probably follow up patch fodder.

> 
> Brian
> 
> > + fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs
> > compatible mount */
> > + fsparam_flag	("noalign",    Opt_noalign),   /* turn off
> > stripe alignment */
> > + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on
> > stripe width allocation */
> > + fsparam_u32	("sunit",      Opt_sunit),     /* data volume
> > stripe unit */
> > + fsparam_u32	("swidth",     Opt_swidth),    /* data volume
> > stripe width */
> > + fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore
> > filesystem UUID */
> > + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID from
> > parent directory (or not) */
> > + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from
> > parent directory */
> > + fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from
> > current process */
> > + fsparam_string ("allocsize",  Opt_allocsize), /* preferred
> > allocation size */
> > + fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS
> > recovery */
> > + fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be
> > allocated anywhere */
> > + fsparam_flag	("inode32",    Opt_inode32),   /* inode
> > allocation limited to XFS_MAXINUMBER_32 */
> > + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free (or
> > keep) empty inode clusters */
> > + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or do
> > not report) large I/O sizes in stat() */
> > + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do not)
> > use attr2 attribute format */
> > + fsparam_flag	("filestreams",Opt_filestreams), /* use
> > filestreams allocator */
> > + fsparam_flag_no("quota",      Opt_quota),     /* disk quotas
> > (user) */
> > + fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota
> > enabled */
> > + fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota
> > enabled */
> > + fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota
> > enabled */
> > + fsparam_flag	("uquota",     Opt_uquota),    /* user quota
> > (IRIX variant) */
> > + fsparam_flag	("gquota",     Opt_gquota),    /* group quota
> > (IRIX variant) */
> > + fsparam_flag	("pquota",     Opt_pquota),    /* project quota
> > (IRIX variant) */
> > + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota
> > limit enforcement */
> > + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota
> > limit enforcement */
> > + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project
> > quota limit enforcement */
> > + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as
> > uqnoenforce */
> > + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do not)
> > not discard unused blocks */
> > + fsparam_flag	("dax",	       Opt_dax),       /* Enable
> > direct access to bdev pages */
> > + {}
> > +};
> > +
> > +static const struct fs_parameter_description xfs_fs_parameters = {
> > +	.name		= "XFS",
> > +	.specs		= xfs_param_specs,
> > +};
> >  
> >  STATIC int
> >  suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > *res)
> > 


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

* Re: [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint()
  2019-08-27 12:40   ` Brian Foster
@ 2019-08-30 10:33     ` Ian Kent
  2019-09-17  4:31     ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 10:33 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:40 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:33AM +0800, Ian Kent wrote:
> > The mount-api doesn't have a "human unit" parse type yet so
> > the options that have values like "10k" etc. still need to
> > be converted by the fs.
> > 
> > But the value comes to the fs as a string (not a substring_t
> > type) so there's a need to change the conversion function to
> > take a character string instead.
> > 
> > After refactoring xfs_parseargs() and changing it to use
> > xfs_parse_param() match_kstrtoint() will no longer be used
> > and will be removed.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   22 ++++++++++++++++++----
> >  1 file changed, 18 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 74c88b92ce22..49c87fb921f1 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -153,13 +153,13 @@ static const struct fs_parameter_description
> > xfs_fs_parameters = {
> >  };
> >  
> >  STATIC int
> > -suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > *res)
> > +suffix_kstrtoint(const char *s, unsigned int base, int *res)
> >  {
> >  	int	last, shift_left_factor = 0, _res;
> >  	char	*value;
> >  	int	ret = 0;
> >  
> > -	value = match_strdup(s);
> > +	value = kstrdup(s, GFP_KERNEL);
> >  	if (!value)
> >  		return -ENOMEM;
> >  
> > @@ -184,6 +184,20 @@ suffix_kstrtoint(const substring_t *s,
> > unsigned int base, int *res)
> >  	return ret;
> >  }
> >  
> > +STATIC int
> > +match_kstrtoint(const substring_t *s, unsigned int base, int *res)
> > +{
> > +	const char	*value;
> > +	int ret;
> > +
> > +	value = match_strdup(s);
> > +	if (!value)
> > +		return -ENOMEM;
> > +	ret = suffix_kstrtoint(value, base, res);
> > +	kfree(value);
> > +	return ret;
> > +}
> > +
> 
> I guess the use case isn't clear to me yet and it's not critical if
> this
> code is going away by the end of the series, but why not refactor
> into a
> __suffix_kstrtoint(char *s, ...) variant that accepts an already
> duplicated string so we don't have to duplicate each string twice in
> the
> match_kstrtoint() case?

Yeah, sounds good, I'll have a go at that for v3.

> 
> Brian
> 
> >  /*
> >   * This function fills in xfs_mount_t fields based on mount args.
> >   * Note: the superblock has _not_ yet been read in.
> > @@ -255,7 +269,7 @@ xfs_parseargs(
> >  				return -EINVAL;
> >  			break;
> >  		case Opt_logbsize:
> > -			if (suffix_kstrtoint(args, 10, &mp-
> > >m_logbsize))
> > +			if (match_kstrtoint(args, 10, &mp->m_logbsize))
> >  				return -EINVAL;
> >  			break;
> >  		case Opt_logdev:
> > @@ -272,7 +286,7 @@ xfs_parseargs(
> >  			break;
> >  		case Opt_allocsize:
> >  		case Opt_biosize:
> > -			if (suffix_kstrtoint(args, 10, &iosize))
> > +			if (match_kstrtoint(args, 10, &iosize))
> >  				return -EINVAL;
> >  			iosizelog = ffs(iosize) - 1;
> >  			break;
> > 


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

* Re: [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args
  2019-08-27 12:41   ` Brian Foster
  2019-08-27 15:10     ` Darrick J. Wong
@ 2019-08-30 10:51     ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 10:51 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:41 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:43AM +0800, Ian Kent wrote:
> > Make xfs_parse_param() take arguments of the fs context operation
> > .parse_param() in preperation for switching to use the file system
> > mount context for mount.
> > 
> > The function fc_parse() only uses the file system context (fc here)
> > when calling log macros warnf() and invalf() which in turn check
> > only the fc->log field to determine if the message should be saved
> > to a context buffer (for later retrival by userspace) or logged
> > using printk().
> > 
> > Also the temporary function match_kstrtoint() is now unused, remove
> > it.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> 
> I see Eric had some feedback on this patch already. Some additional
> notes (which may overlap)...
> 
> >  fs/xfs/xfs_super.c |  187 ++++++++++++++++++++++++++++++--------
> > --------------
> >  1 file changed, 108 insertions(+), 79 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 3ae29938dd89..754d2ccfd960 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> ...
> > @@ -275,33 +271,38 @@ xfs_parse_param(
> >  		mp->m_flags |= XFS_MOUNT_NOUUID;
> >  		break;
> >  	case Opt_ikeep:
> > -		mp->m_flags |= XFS_MOUNT_IKEEP;
> > -		break;
> > -	case Opt_noikeep:
> > -		mp->m_flags &= ~XFS_MOUNT_IKEEP;
> > +		if (result.negated)
> > +			mp->m_flags &= ~XFS_MOUNT_IKEEP;
> > +		else
> > +			mp->m_flags |= XFS_MOUNT_IKEEP;
> >  		break;
> >  	case Opt_largeio:
> > -		mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> > -		break;
> > -	case Opt_nolargeio:
> > -		mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> > +		if (result.negated)
> > +			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
> > +		else
> > +			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
> >  		break;
> >  	case Opt_attr2:
> > -		mp->m_flags |= XFS_MOUNT_ATTR2;
> > -		break;
> > -	case Opt_noattr2:
> > -		mp->m_flags &= ~XFS_MOUNT_ATTR2;
> > -		mp->m_flags |= XFS_MOUNT_NOATTR2;
> > +		if (!result.negated) {
> > +			mp->m_flags |= XFS_MOUNT_ATTR2;
> > +		} else {
> > +			mp->m_flags &= ~XFS_MOUNT_ATTR2;
> > +			mp->m_flags |= XFS_MOUNT_NOATTR2;
> > +		}
> 
> Eric's comments aside, it would be nice to have some consistency
> between
> the various result.negated checks (i.e. 'if (negated)' vs 'if
> (!negated)').

Right, that's my "the smallest block must always be first 'ism"
cutting in there. I always feel that a larger block before a
smaller block makes the later (partially) invisible in reading
the code. But the fact is that seeing this annoys me so I always
see the hanging code so what I'm saying is kind-off nonsence!

I'll try and overcome my 'ism and make this consistent, ;)

> 
> >  		break;
> >  	case Opt_filestreams:
> >  		mp->m_flags |= XFS_MOUNT_FILESTREAMS;
> >  		break;
> > -	case Opt_noquota:
> > -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> > -		mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> > -		mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> > -		break;
> >  	case Opt_quota:
> > +		if (!result.negated) {
> > +			mp->m_qflags |= (XFS_UQUOTA_ACCT |
> > XFS_UQUOTA_ACTIVE |
> > +					 XFS_UQUOTA_ENFD);
> > +		} else {
> > +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
> > +			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
> > +			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
> > +		}
> > +		break;
> >  	case Opt_uquota:
> >  	case Opt_usrquota:
> >  		mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
> ...
> > @@ -367,10 +368,10 @@ xfs_parseargs(
> >  {
> >  	const struct super_block *sb = mp->m_super;
> >  	char			*p;
> > -	substring_t		args[MAX_OPT_ARGS];
> > -	int			dsunit = 0;
> > -	int			dswidth = 0;
> > -	uint8_t			iosizelog = 0;
> > +
> > +	struct fs_context	fc;
> > +	struct xfs_fs_context	context;
> > +	struct xfs_fs_context	*ctx = &context;
> 
> I don't really see the point for having a separate pointer variable
> based on the code so far. Why not just do:
> 
> 	struct xfs_fs_context	ctx = {0,};
> 
> ... and pass by reference where necessary?

Yep, it was a stupid mistake to begin with.
I'm using only the context variable now.

> 
> >  
> >  	/*
> >  	 * set up the mount name first so all the errors will refer to
> > the
> > @@ -406,17 +407,41 @@ xfs_parseargs(
> >  	if (!options)
> >  		goto done;
> >  
> > +	memset(&fc, 0, sizeof(fc));
> > +	memset(&ctx, 0, sizeof(ctx));
> > +	fc.fs_private = ctx;
> > +	fc.s_fs_info = mp;
> > +
> >  	while ((p = strsep(&options, ",")) != NULL) {
> > -		int		token;
> > -		int		ret;
> > +		struct fs_parameter	param;
> > +		char			*value;
> > +		int			ret;
> >  
> >  		if (!*p)
> >  			continue;
> >  
> > -		token = match_token(p, tokens, args);
> > -		ret = xfs_parse_param(token, p, args, mp,
> > -				      &dsunit, &dswidth, &iosizelog);
> > -		if (ret)
> > +		param.key = p;
> > +		param.type = fs_value_is_string;
> > +		param.size = 0;
> > +
> > +		value = strchr(p, '=');
> > +		if (value) {
> > +			if (value == p)
> > +				continue;
> 
> What's the purpose of the above check? Why do we skip the param as
> opposed to return an error or something?

Well, that's a good question, there's a thought in the back
of my mind that if the char isn't found the whole string
is returned but that's not the way strchr(3) works so I was
thinking of something different.

Maybe I'm not the only one to think this way because it looks
like the VFS code does the same thing (and that's where this
came from altough I think it was slightly different when I
did that).

But I'm probably miss-reading the VFS code ...
I'll need to look closer at it.

> 
> > +			*value++ = 0;
> > +			param.size = strlen(value);
> > +			if (param.size > 0) {
> > +				param.string = kmemdup_nul(value,
> > +							   param.size,
> > +							   GFP_KERNEL);
> > +				if (!param.string)
> > +					return -ENOMEM;
> > +			}
> > +		}
> > +
> > +		ret = xfs_parse_param(&fc, &param);
> > +		kfree(param.string);
> > +		if (ret < 0)
> >  			return ret;
> >  	}
> >  
> ...
> > @@ -1914,6 +1939,10 @@ static const struct super_operations
> > xfs_super_operations = {
> >  	.free_cached_objects	= xfs_fs_free_cached_objects,
> >  };
> >  
> > +static const struct fs_context_operations xfs_context_ops = {
> > +	.parse_param = xfs_parse_param,
> > +};
> > +
> 
> It's probably better to introduce this in the first patch where it's
> used.

Either or, I thought that building up the operations structure
as we go gave insight into the context of where the change is
headed.

But if doing this irritates your sensibilities I can change
it as long as no-one else has strong preferences against it.
 
> 
> Brian
> 
> >  static struct file_system_type xfs_fs_type = {
> >  	.owner			= THIS_MODULE,
> >  	.name			= "xfs",
> > 


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

* Re: [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper
  2019-08-27 12:41   ` Brian Foster
@ 2019-08-30 10:55     ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 10:55 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:41 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:49AM +0800, Ian Kent wrote:
> > Move the validation code of xfs_parseargs() into a helper for later
> > use within the mount context methods.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |  180 ++++++++++++++++++++++++++++----------
> > --------------
> >  1 file changed, 98 insertions(+), 82 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 754d2ccfd960..7cdda17ee0ff 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> ...
> > @@ -442,89 +535,12 @@ xfs_parseargs(
> >  		ret = xfs_parse_param(&fc, &param);
> >  		kfree(param.string);
> >  		if (ret < 0)
> > -			return ret;
> > -	}
> > -
> > -	/*
> > -	 * no recovery flag requires a read-only mount
> > -	 */
> > -	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
> > -	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
> > -		xfs_warn(mp, "no-recovery mounts must be read-only.");
> > -		return -EINVAL;
> > -	}
> > -
> > -	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (ctx->dsunit || ctx-
> > >dswidth)) {
> > -		xfs_warn(mp,
> > -	"sunit and swidth options incompatible with the noalign
> > option");
> > -		return -EINVAL;
> > -	}
> > -
> > -#ifndef CONFIG_XFS_QUOTA
> > -	if (XFS_IS_QUOTA_RUNNING(mp)) {
> > -		xfs_warn(mp, "quota support not available in this
> > kernel.");
> > -		return -EINVAL;
> > -	}
> > -#endif
> > -
> > -	if ((ctx->dsunit && !ctx->dswidth) || (!ctx->dsunit && ctx-
> > >dswidth)) {
> > -		xfs_warn(mp, "sunit and swidth must be specified
> > together");
> > -		return -EINVAL;
> > -	}
> > -
> > -	if (ctx->dsunit && (ctx->dswidth % ctx->dsunit != 0)) {
> > -		xfs_warn(mp,
> > -	"stripe width (%d) must be a multiple of the stripe unit (%d)",
> > -			ctx->dswidth, ctx->dsunit);
> > -		return -EINVAL;
> > +			goto done;
> >  	}
> >  
> > +	ret = xfs_validate_params(mp, ctx, false);
> >  done:
> 
> This label now directly returns, which means it's not that useful in
> its
> current form. How about we move the validate call below the label
> (and perhaps rename the label to validate or some such) and just
> return
> directly from the other user of done?

Yes, I saw that too.

But I was trying to duplicate the existing logic, I thought
maybe I got that wrong but couldn't see it and I probably
have since you don't see the correspondence to the original
code.

I'll need re-look at that logic.

> 
> Brian
> 
> > -	if (ctx->dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
> > -		/*
> > -		 * At this point the superblock has not been read
> > -		 * in, therefore we do not know the block size.
> > -		 * Before the mount call ends we will convert
> > -		 * these to FSBs.
> > -		 */
> > -		mp->m_dalign = ctx->dsunit;
> > -		mp->m_swidth = ctx->dswidth;
> > -	}
> > -
> > -	if (mp->m_logbufs != -1 &&
> > -	    mp->m_logbufs != 0 &&
> > -	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
> > -	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
> > -		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
> > -			mp->m_logbufs, XLOG_MIN_ICLOGS,
> > XLOG_MAX_ICLOGS);
> > -		return -EINVAL;
> > -	}
> > -	if (mp->m_logbsize != -1 &&
> > -	    mp->m_logbsize !=  0 &&
> > -	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
> > -	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
> > -	     !is_power_of_2(mp->m_logbsize))) {
> > -		xfs_warn(mp,
> > -			"invalid logbufsize: %d [not 16k,32k,64k,128k
> > or 256k]",
> > -			mp->m_logbsize);
> > -		return -EINVAL;
> > -	}
> > -
> > -	if (ctx->iosizelog) {
> > -		if (ctx->iosizelog > XFS_MAX_IO_LOG ||
> > -		    ctx->iosizelog < XFS_MIN_IO_LOG) {
> > -			xfs_warn(mp, "invalid log iosize: %d [not %d-
> > %d]",
> > -				ctx->iosizelog, XFS_MIN_IO_LOG,
> > -				XFS_MAX_IO_LOG);
> > -			return -EINVAL;
> > -		}
> > -
> > -		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
> > -		mp->m_readio_log = ctx->iosizelog;
> > -		mp->m_writeio_log = ctx->iosizelog;
> > -	}
> > -
> > -	return 0;
> > +	return ret;
> >  }
> >  
> >  struct proc_xfs_info {
> > 


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

* Re: [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super()
  2019-08-27 12:42   ` Brian Foster
@ 2019-08-30 10:56     ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 10:56 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:42 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:54AM +0800, Ian Kent wrote:
> > Much of the code in xfs_fs_fill_super() will be used by the fill
> > super
> > function of the new mount-api.
> > 
> > So refactor the common code into a helper in an attempt to show
> > what's
> > actually changed.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   65 ++++++++++++++++++++++++++++++++++----
> > --------------
> >  1 file changed, 42 insertions(+), 23 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 7cdda17ee0ff..d3fc9938987d 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> ...
> > @@ -1885,6 +1868,42 @@ xfs_fs_fill_super(
> >  	goto out_free_sb;
> >  }
> >  
> > +STATIC int
> > +xfs_fs_fill_super(
> > +	struct super_block	*sb,
> > +	void			*data,
> > +	int			silent)
> > +{
> > +	struct xfs_mount	*mp = NULL;
> > +	int			error = -ENOMEM;
> > +
> > +	/*
> > +	 * allocate mp and do all low-level struct initializations
> > before we
> > +	 * attach it to the super
> > +	 */
> > +	mp = xfs_mount_alloc(sb);
> > +	if (!mp)
> > +		goto out;
> > +	sb->s_fs_info = mp;
> > +
> > +	error = xfs_parseargs(mp, (char *)data);
> > +	if (error)
> > +		goto out_free_fsname;
> > +
> > +	error = __xfs_fs_fill_super(mp, silent);
> > +	if (error)
> > +		goto out_free_fsname;
> > +
> > +	return 0;
> > +
> > + out_free_fsname:
> > +	sb->s_fs_info = NULL;
> > +	xfs_free_fsname(mp);
> > +	kfree(mp);
> > +out:
> > +	return error;
> 
> I know this is copied from the existing function, but there's really
> no
> need for an out label here. We can just return -ENOMEM in the one
> user
> above. Aside from that nit the rest looks fine to me.

That's sensible, I'll do that.

And btw, thanks for spending the time to look at the patches.

Ian
> 
> Brian
> 
> > +}
> > +
> >  STATIC void
> >  xfs_fs_put_super(
> >  	struct super_block	*sb)
> > 


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

* Re: [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree()
  2019-08-28 13:27   ` Brian Foster
@ 2019-08-30 11:01     ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 11:01 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Wed, 2019-08-28 at 09:27 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:59AM +0800, Ian Kent wrote:
> > Add the fs_context_operations method .get_tree that validates
> > mount options and fills the super block as previously done
> > by the file_system_type .mount method.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   47
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 47 insertions(+)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index d3fc9938987d..7de64808eb00 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -1904,6 +1904,52 @@ xfs_fs_fill_super(
> >  	return error;
> >  }
> >  
> > +STATIC int
> > +xfs_fill_super(
> > +	struct super_block	*sb,
> > +	struct fs_context	*fc)
> > +{
> > +	struct xfs_fs_context	*ctx = fc->fs_private;
> > +	struct xfs_mount	*mp = sb->s_fs_info;
> > +	int			silent = fc->sb_flags & SB_SILENT;
> > +	int			error = -ENOMEM;
> > +
> > +	mp->m_super = sb;
> > +
> > +	/*
> > +	 * set up the mount name first so all the errors will refer to
> > the
> > +	 * correct device.
> > +	 */
> > +	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
> > +	if (!mp->m_fsname)
> > +		return -ENOMEM;
> > +	mp->m_fsname_len = strlen(mp->m_fsname) + 1;
> > +
> > +	error = xfs_validate_params(mp, ctx, false);
> > +	if (error)
> > +		goto out_free_fsname;
> > +
> > +	error = __xfs_fs_fill_super(mp, silent);
> > +	if (error)
> > +		goto out_free_fsname;
> > +
> > +	return 0;
> > +
> > + out_free_fsname:
> > +	sb->s_fs_info = NULL;
> > +	xfs_free_fsname(mp);
> > +	kfree(mp);
> 
> So where is mp allocated in the updated mount sequence? Has that code
> been added yet or does this tie into the existing fill_super
> sequence?
> It's hard to tell because xfs_context_ops is still unused. It looks a
> little strange to free mp here when it's presumably been allocated
> somewhere else. If that is separate code, perhaps some of the patches
> should be combined (i.e. even if just setup/teardown bits) for easier
> review.

Umm, good question, and good suggestion.

I haven't looked at what I'm doing there so I'll keep your
suggestion in mind when I'm working through it.

> 
> Brian
> 
> > +
> > +	return error;
> > +}
> > +
> > +STATIC int
> > +xfs_get_tree(
> > +	struct fs_context	*fc)
> > +{
> > +	return vfs_get_block_super(fc, xfs_fill_super);
> > +}
> > +
> >  STATIC void
> >  xfs_fs_put_super(
> >  	struct super_block	*sb)
> > @@ -1976,6 +2022,7 @@ static const struct super_operations
> > xfs_super_operations = {
> >  
> >  static const struct fs_context_operations xfs_context_ops = {
> >  	.parse_param = xfs_parse_param,
> > +	.get_tree    = xfs_get_tree,
> >  };
> >  
> >  static struct file_system_type xfs_fs_type = {
> > 


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

* Re: [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure()
  2019-08-28 13:28   ` Brian Foster
@ 2019-08-30 11:10     ` Ian Kent
  2019-08-30 11:56       ` Brian Foster
  0 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-08-30 11:10 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Wed, 2019-08-28 at 09:28 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 09:00:16AM +0800, Ian Kent wrote:
> > Add the fs_context_operations method .reconfigure that performs
> > remount validation as previously done by the super_operations
> > .remount_fs method.
> > 
> > An attempt has also been made to update the comment about options
> > handling problems with mount(8) to reflect the current situation.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   84
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 84 insertions(+)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 76374d602257..aae0098fecab 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -1522,6 +1522,89 @@ xfs_fs_remount(
> >  	return 0;
> >  }
> >  
> > +/*
> > + * There have been problems in the past with options passed from
> > mount(8).
> > + *
> > + * The problem being that options passed by mount(8) in the case
> > where only
> > + * the the mount point path is given would consist of the existing
> > fstab
> > + * options with the options from mtab for the current mount merged
> > in and
> > + * the options given on the command line last. But the result
> > couldn't be
> > + * relied upon to accurately reflect the current mount options so
> > that
> > + * rejecting options that can't be changed on reconfigure could
> > erronously
> > + * cause mount failure.
> > + *
> > + * The mount-api uses a legacy mount options handler in the VFS to
> > handle
> > + * mount(8) so these options will continue to be passed. Even if
> > mount(8)
> > + * is updated to use fsopen()/fsconfig()/fsmount() it's likely to
> > continue
> > + * to set the existing options so options problems with
> > reconfigure could
> > + * continue.
> > + *
> > + * For the longest time mtab locking was a problem and this could
> > have been
> > + * one possible cause. It's also possible there could have been
> > options
> > + * order problems.
> > + *
> > + * That has changed now as mtab is a link to the proc file system
> > mount
> > + * table so mtab options should be always accurate.
> > + *
> > + * Consulting the util-linux maintainer (Karel Zak) he is
> > confident that,
> > + * in this case, the options passed by mount(8) will be those of
> > the current
> > + * mount and the options order should be a correct merge of fstab
> > and mtab
> > + * options, and new options given on the command line.
> > + *
> > + * So, in theory, it should be possible to compare incoming
> > options and
> > + * return an error for options that differ from the current mount
> > and can't
> > + * be changed on reconfigure to prevent users from believing they
> > might have
> > + * changed mount options using remount which can't be changed.
> > + *
> > + * But for now continue to return success for every reconfigure
> > request, and
> > + * silently ignore all options that can't actually be changed.
> > + */
> 
> This seems like all good information for a commit log description or
> perhaps to land in a common header where some of these fs context
> bits
> are declared, but overly broad for a function header comment for an
> XFS
> callback. I'd more expect some information around the fundamental
> difference between 'mp' and 'new_mp,' where those come from, what
> they
> mean, etc. From the code, it seems like new_mp is transient and
> reflects
> changes that we need to incorporate in the original mp..?

The reason I looked into this is becuase of a fairly lengthy
comment in the original source and that lead to this rather
verbose tail about what I found.

It's not so much a mount context problem becuase it's due
to the way user space constructs the mount options from
various sources where options are present.

So I don't think it's something that the mount context
code can resolve.

Which leaves a bunch of (I think) useful information
without a palce to live so it can be referred to ...
suggestions?

> 
> Brian
> 
> > +STATIC int
> > +xfs_reconfigure(
> > +	struct fs_context *fc)
> > +{
> > +	struct xfs_fs_context	*ctx = fc->fs_private;
> > +	struct xfs_mount	*mp = XFS_M(fc->root->d_sb);
> > +	struct xfs_mount        *new_mp = fc->s_fs_info;
> > +	xfs_sb_t		*sbp = &mp->m_sb;
> > +	int			flags = fc->sb_flags;
> > +	int			error;
> > +
> > +	error = xfs_validate_params(new_mp, ctx, false);
> > +	if (error)
> > +		return error;
> > +
> > +	/* inode32 -> inode64 */
> > +	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> > +	    !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> > +		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> > +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp-
> > >sb_agcount);
> > +	}
> > +
> > +	/* inode64 -> inode32 */
> > +	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> > +	    (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> > +		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> > +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp-
> > >sb_agcount);
> > +	}
> > +
> > +	/* ro -> rw */
> > +	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) {
> > +		error = xfs_remount_rw(mp);
> > +		if (error)
> > +			return error;
> > +	}
> > +
> > +	/* rw -> ro */
> > +	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) {
> > +		error = xfs_remount_ro(mp);
> > +		if (error)
> > +			return error;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /*
> >   * Second stage of a freeze. The data is already frozen so we only
> >   * need to take care of the metadata. Once that's done sync the
> > superblock
> > @@ -2049,6 +2132,7 @@ static const struct super_operations
> > xfs_super_operations = {
> >  static const struct fs_context_operations xfs_context_ops = {
> >  	.parse_param = xfs_parse_param,
> >  	.get_tree    = xfs_get_tree,
> > +	.reconfigure = xfs_reconfigure,
> >  };
> >  
> >  static struct file_system_type xfs_fs_type = {
> > 


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

* Re: [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free()
  2019-08-28 13:28   ` Brian Foster
@ 2019-08-30 11:19     ` Ian Kent
  2019-08-30 11:20     ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 11:19 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Wed, 2019-08-28 at 09:28 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 09:00:22AM +0800, Ian Kent wrote:
> > Add the fs_context_operations method .free that performs fs
> > context cleanup on context release.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   22 ++++++++++++++++++++++
> >  1 file changed, 22 insertions(+)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index aae0098fecab..9976163dc537 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -2129,10 +2129,32 @@ static const struct super_operations
> > xfs_super_operations = {
> >  	.free_cached_objects	= xfs_fs_free_cached_objects,
> >  };
> >  
> > +static void xfs_fc_free(struct fs_context *fc)
> > +{
> > +	struct xfs_fs_context	*ctx = fc->fs_private;
> > +	struct xfs_mount	*mp = fc->s_fs_info;
> > +
> > +	if (mp) {
> > +		/*
> > +		 * If an error occurs before ownership the xfs_mount
> > +		 * info struct is passed to xfs by the VFS (by
> > assigning
> > +		 * it to sb->s_fs_info and clearing the corresponding
> > +		 * fs_context field, which is done before calling fill
> > +		 * super via .get_tree()) there may be some strings to
> > +		 * cleanup.
> > +		 */
> 
> The code looks straightforward but I find the comment confusing. How
> can
> the VFS pass ownership of the xfs_mount if it's an XFS private data
> structure?

*sigh*, Darrick was similarly confused about my original
comment so it seems it's still not good enough.

The mount context holds values for various things as the
VFS allocates/constructs them and when they get assigned
to an object owned by the file system they are NULLed in
the moun t context structure.

I'm calling that process "ownership" in the above comment
and, perhaps mistenly, extending that to the xfs_mount
object which might never actually make it to the "file
system" in term of that ownership, such as when an error
occurs in the VFS during the mount procedure before the
mount context is realeased.

I can try and re-word the comment again, clearly it's
still not good enough ...

> 
> > +		kfree(mp->m_logname);
> > +		kfree(mp->m_rtname);
> > +		kfree(mp);
> > +	}
> > +	kfree(ctx);
> 
> Also, should we at least reassign associated fc pointers to NULL if
> we
> have multiple places to free things like ctx or mp?
> 
> Brian
> 
> > +}
> > +
> >  static const struct fs_context_operations xfs_context_ops = {
> >  	.parse_param = xfs_parse_param,
> >  	.get_tree    = xfs_get_tree,
> >  	.reconfigure = xfs_reconfigure,
> > +	.free	     = xfs_fc_free,
> >  };
> >  
> >  static struct file_system_type xfs_fs_type = {
> > 


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

* Re: [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free()
  2019-08-28 13:28   ` Brian Foster
  2019-08-30 11:19     ` Ian Kent
@ 2019-08-30 11:20     ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 11:20 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Wed, 2019-08-28 at 09:28 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 09:00:22AM +0800, Ian Kent wrote:
> > Add the fs_context_operations method .free that performs fs
> > context cleanup on context release.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   22 ++++++++++++++++++++++
> >  1 file changed, 22 insertions(+)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index aae0098fecab..9976163dc537 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -2129,10 +2129,32 @@ static const struct super_operations
> > xfs_super_operations = {
> >  	.free_cached_objects	= xfs_fs_free_cached_objects,
> >  };
> >  
> > +static void xfs_fc_free(struct fs_context *fc)
> > +{
> > +	struct xfs_fs_context	*ctx = fc->fs_private;
> > +	struct xfs_mount	*mp = fc->s_fs_info;
> > +
> > +	if (mp) {
> > +		/*
> > +		 * If an error occurs before ownership the xfs_mount
> > +		 * info struct is passed to xfs by the VFS (by
> > assigning
> > +		 * it to sb->s_fs_info and clearing the corresponding
> > +		 * fs_context field, which is done before calling fill
> > +		 * super via .get_tree()) there may be some strings to
> > +		 * cleanup.
> > +		 */
> 
> The code looks straightforward but I find the comment confusing. How
> can
> the VFS pass ownership of the xfs_mount if it's an XFS private data
> structure?
> 
> > +		kfree(mp->m_logname);
> > +		kfree(mp->m_rtname);
> > +		kfree(mp);
> > +	}
> > +	kfree(ctx);
> 
> Also, should we at least reassign associated fc pointers to NULL if
> we
> have multiple places to free things like ctx or mp?

Not sure about that, I think the next thing to happen
here is the mount context is freed by the VFS.

I'll check.

> 
> Brian
> 
> > +}
> > +
> >  static const struct fs_context_operations xfs_context_ops = {
> >  	.parse_param = xfs_parse_param,
> >  	.get_tree    = xfs_get_tree,
> >  	.reconfigure = xfs_reconfigure,
> > +	.free	     = xfs_fc_free,
> >  };
> >  
> >  static struct file_system_type xfs_fs_type = {
> > 


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

* Re: [PATCH v2 14/15] xfs: mount-api - switch to new mount-api
  2019-08-28 13:29   ` Brian Foster
  2019-08-28 13:34     ` Eric Sandeen
@ 2019-08-30 11:27     ` Ian Kent
  1 sibling, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 11:27 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Wed, 2019-08-28 at 09:29 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 09:00:32AM +0800, Ian Kent wrote:
> > The infrastructure needed to use the new mount api is now
> > in place, switch over to use it.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   51
> > +++++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 49 insertions(+), 2 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index d2a1a62a3edc..fe7acd8ddd48 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -2123,7 +2123,6 @@ static const struct super_operations
> > xfs_super_operations = {
> >  	.freeze_fs		= xfs_fs_freeze,
> >  	.unfreeze_fs		= xfs_fs_unfreeze,
> >  	.statfs			= xfs_fs_statfs,
> > -	.remount_fs		= xfs_fs_remount,
> 
> Not clear why this needs to go away here, or at least why we don't
> remove the function at the same time.
> 
> Indeed.. this patch actually throws a couple warnings:
> 
> ...
>   CC [M]  fs/xfs/xfs_super.o
> fs/xfs/xfs_super.c:2088:1: warning: ‘xfs_fs_mount’ defined but not
> used [-Wunused-function]
>  xfs_fs_mount(
>  ^~~~~~~~~~~~
> fs/xfs/xfs_super.c:1448:1: warning: ‘xfs_fs_remount’ defined but not
> used [-Wunused-function]
>  xfs_fs_remount(
>  ^~~~~~~~~~~~~~
> ...

Yes I saw those too and I was very tempted to remove those
functions at the time.

But I decided the warning was preferable to obsuring what
the change was really doing.

I think now you find this a problem I'll just remove the
functions.

IIRC .remount_fs is removed so it won't be called.

But to be honest I'm not certain that needs to be done.

In any case it really should go away when changing to
use the mount api so I think it needs to be done.

> 
> >  	.show_options		= xfs_fs_show_options,
> >  	.nr_cached_objects	= xfs_fs_nr_cached_objects,
> >  	.free_cached_objects	= xfs_fs_free_cached_objects,
> > @@ -2157,10 +2156,58 @@ static const struct fs_context_operations
> > xfs_context_ops = {
> ...
> >  static struct file_system_type xfs_fs_type = {
> >  	.owner			= THIS_MODULE,
> >  	.name			= "xfs",
> > -	.mount			= xfs_fs_mount,
> > +	.init_fs_context	= xfs_init_fs_context,
> > +	.parameters		= &xfs_fs_parameters,
> 
> Just a random observation.. we have a .name == "xfs" field here and
> the
> parameters struct has a .name == "XFS" field. Perhaps we should be
> consistent?

Yeah, others are seeing similar inconsistencies.

Not sure what I'll do about these yet but it is a problem I think
so I'll need to come up with something sensible.

> 
> Brian
> 
> >  	.kill_sb		= kill_block_super,
> >  	.fs_flags		= FS_REQUIRES_DEV,
> >  };
> > 


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

* Re: [PATCH v2 14/15] xfs: mount-api - switch to new mount-api
  2019-08-28 13:34     ` Eric Sandeen
@ 2019-08-30 11:30       ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-08-30 11:30 UTC (permalink / raw)
  To: Eric Sandeen, Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro

On Wed, 2019-08-28 at 08:34 -0500, Eric Sandeen wrote:
> 
> On 8/28/19 8:29 AM, Brian Foster wrote:
> > >  static struct file_system_type xfs_fs_type = {
> > >  	.owner			= THIS_MODULE,
> > >  	.name			= "xfs",
> > > -	.mount			= xfs_fs_mount,
> > > +	.init_fs_context	= xfs_init_fs_context,
> > > +	.parameters		= &xfs_fs_parameters,
> > Just a random observation.. we have a .name == "xfs" field here and
> > the
> > parameters struct has a .name == "XFS" field. Perhaps we should be
> > consistent?
> > 
> > Brian
> > 
> 
> I sent a patch to fsdevel to just remove the .name from the new mount
> parameters
> structure; it's not had any attention yet.  But I had the same
> concerns about
> consistency if we have to copy the same name to multiple places.
> 
> [PATCH] fs: fs_parser: remove fs_parameter_description name field

I didn't see that yet (ha, I haven't really looked yet so no
surprize there), I'll add it to the series if David hasn't
got time to deal with it and see if we can get comments on it
later on in the process.

Ian


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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-08-30 10:31     ` Ian Kent
@ 2019-08-30 11:56       ` Brian Foster
  0 siblings, 0 replies; 58+ messages in thread
From: Brian Foster @ 2019-08-30 11:56 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 30, 2019 at 06:31:58PM +0800, Ian Kent wrote:
> On Tue, 2019-08-27 at 08:39 -0400, Brian Foster wrote:
> > On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> > > The new mount-api uses an array of struct fs_parameter_spec for
> > > parameter parsing, create this table populated with the xfs mount
> > > parameters.
> > > 
> > > The new mount-api table definition is wider than the token based
> > > parameter table and interleaving the option description comments
> > > between each table line is much less readable than adding them to
> > > the end of each table entry. So add the option description comment
> > > to each entry line even though it causes quite a few of the entries
> > > to be longer than 80 characters.
> > > 
> > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > ---
> > >  fs/xfs/xfs_super.c |   48
> > > +++++++++++++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 45 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > index f9450235533c..74c88b92ce22 100644
> > > --- a/fs/xfs/xfs_super.c
> > > +++ b/fs/xfs/xfs_super.c
> > > @@ -38,6 +38,8 @@
> > >  
> > >  #include <linux/magic.h>
> > >  #include <linux/parser.h>
> > > +#include <linux/fs_context.h>
> > > +#include <linux/fs_parser.h>
> > >  
> > >  static const struct super_operations xfs_super_operations;
> > >  struct bio_set xfs_ioend_bioset;
> > > @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-
> > > level xfs sysfs dir */
> > >  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs
> > > attrs */
> > >  #endif
> > >  
> > > -/*
> > > - * Table driven mount option parser.
> > > - */
> 
> You would rather it be kept?
> 

No, it just seems unrelated to this patch because you're leaving the
associated code around. Why not remove it when the rest of the code is
ripped out?

> Strictly speaking it's still a table driven parser so it
> could be kept.
> 
> I just thought it was a useles comment since it doesn't add
> value in terms of understanding what's going on, IOW I think
> it's just noise.
> 
> > 
> > Not sure why this is comment is removed here if the associated code
> > is
> > staying put in this patch..?
> > 
> > >  enum {
> > >  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
> > >  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth,
> > > Opt_nouuid,
> > > @@ -109,6 +108,49 @@ static const match_table_t tokens = {
> > >  	{Opt_err,	NULL},
> > >  };
> > >  
> > > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > > + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS
> > > log buffers */
> > > + fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS log
> > > buffers */
> > > + fsparam_string ("logdev",     Opt_logdev),    /* log device */
> > > + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O
> > > device */
> > > + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of
> > > preferred buffered io size */
> > 
> > Hmm.. it looks like the difference between numerical values as
> > strings
> > vs. numeric types is whether we support things like unit suffixes
> > (i.e.
> > "64k"). That said, Opt_biosize uses suffix_kstrtoint() similar to
> > Opt_logbsize yet is defined here as a u32 (and Opt_allocsize falls
> > into
> > the same parsing code but is a string). Is that wrong or am I just
> > missing something wrt to the type specifiers here?
> 
> Dave Chinner (and IIRC Darrick) made roughly comments about the
> need for human unit values in the parser.
> 
> I know David has some patches to implement this but I hadn't
> seen anything posted, he's probably over loaded with higher
> priority work atm. so this is probably follow up patch fodder.
> 

Ok, but why are we using different types for Opt_biosize and
Opt_allocsize when they're backed by the same underlying field? I.e.,
from the current code:

		...
                case Opt_allocsize:
                case Opt_biosize:
                        if (suffix_kstrtoint(args, 10, &iosize))
                                return -EINVAL;
                        iosizelog = ffs(iosize) - 1;
                        break;
		...

Brian

> > 
> > Brian
> > 
> > > + fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs
> > > compatible mount */
> > > + fsparam_flag	("noalign",    Opt_noalign),   /* turn off
> > > stripe alignment */
> > > + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on
> > > stripe width allocation */
> > > + fsparam_u32	("sunit",      Opt_sunit),     /* data volume
> > > stripe unit */
> > > + fsparam_u32	("swidth",     Opt_swidth),    /* data volume
> > > stripe width */
> > > + fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore
> > > filesystem UUID */
> > > + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID from
> > > parent directory (or not) */
> > > + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from
> > > parent directory */
> > > + fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from
> > > current process */
> > > + fsparam_string ("allocsize",  Opt_allocsize), /* preferred
> > > allocation size */
> > > + fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS
> > > recovery */
> > > + fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be
> > > allocated anywhere */
> > > + fsparam_flag	("inode32",    Opt_inode32),   /* inode
> > > allocation limited to XFS_MAXINUMBER_32 */
> > > + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free (or
> > > keep) empty inode clusters */
> > > + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or do
> > > not report) large I/O sizes in stat() */
> > > + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do not)
> > > use attr2 attribute format */
> > > + fsparam_flag	("filestreams",Opt_filestreams), /* use
> > > filestreams allocator */
> > > + fsparam_flag_no("quota",      Opt_quota),     /* disk quotas
> > > (user) */
> > > + fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota
> > > enabled */
> > > + fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota
> > > enabled */
> > > + fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota
> > > enabled */
> > > + fsparam_flag	("uquota",     Opt_uquota),    /* user quota
> > > (IRIX variant) */
> > > + fsparam_flag	("gquota",     Opt_gquota),    /* group quota
> > > (IRIX variant) */
> > > + fsparam_flag	("pquota",     Opt_pquota),    /* project quota
> > > (IRIX variant) */
> > > + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota
> > > limit enforcement */
> > > + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota
> > > limit enforcement */
> > > + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project
> > > quota limit enforcement */
> > > + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as
> > > uqnoenforce */
> > > + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do not)
> > > not discard unused blocks */
> > > + fsparam_flag	("dax",	       Opt_dax),       /* Enable
> > > direct access to bdev pages */
> > > + {}
> > > +};
> > > +
> > > +static const struct fs_parameter_description xfs_fs_parameters = {
> > > +	.name		= "XFS",
> > > +	.specs		= xfs_param_specs,
> > > +};
> > >  
> > >  STATIC int
> > >  suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > > *res)
> > > 
> 

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

* Re: [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure()
  2019-08-30 11:10     ` Ian Kent
@ 2019-08-30 11:56       ` Brian Foster
  2019-09-02  2:41         ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Brian Foster @ 2019-08-30 11:56 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, Aug 30, 2019 at 07:10:44PM +0800, Ian Kent wrote:
> On Wed, 2019-08-28 at 09:28 -0400, Brian Foster wrote:
> > On Fri, Aug 23, 2019 at 09:00:16AM +0800, Ian Kent wrote:
> > > Add the fs_context_operations method .reconfigure that performs
> > > remount validation as previously done by the super_operations
> > > .remount_fs method.
> > > 
> > > An attempt has also been made to update the comment about options
> > > handling problems with mount(8) to reflect the current situation.
> > > 
> > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > ---
> > >  fs/xfs/xfs_super.c |   84
> > > ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 84 insertions(+)
> > > 
> > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > index 76374d602257..aae0098fecab 100644
> > > --- a/fs/xfs/xfs_super.c
> > > +++ b/fs/xfs/xfs_super.c
> > > @@ -1522,6 +1522,89 @@ xfs_fs_remount(
> > >  	return 0;
> > >  }
> > >  
> > > +/*
> > > + * There have been problems in the past with options passed from
> > > mount(8).
> > > + *
> > > + * The problem being that options passed by mount(8) in the case
> > > where only
> > > + * the the mount point path is given would consist of the existing
> > > fstab
> > > + * options with the options from mtab for the current mount merged
> > > in and
> > > + * the options given on the command line last. But the result
> > > couldn't be
> > > + * relied upon to accurately reflect the current mount options so
> > > that
> > > + * rejecting options that can't be changed on reconfigure could
> > > erronously
> > > + * cause mount failure.
> > > + *
> > > + * The mount-api uses a legacy mount options handler in the VFS to
> > > handle
> > > + * mount(8) so these options will continue to be passed. Even if
> > > mount(8)
> > > + * is updated to use fsopen()/fsconfig()/fsmount() it's likely to
> > > continue
> > > + * to set the existing options so options problems with
> > > reconfigure could
> > > + * continue.
> > > + *
> > > + * For the longest time mtab locking was a problem and this could
> > > have been
> > > + * one possible cause. It's also possible there could have been
> > > options
> > > + * order problems.
> > > + *
> > > + * That has changed now as mtab is a link to the proc file system
> > > mount
> > > + * table so mtab options should be always accurate.
> > > + *
> > > + * Consulting the util-linux maintainer (Karel Zak) he is
> > > confident that,
> > > + * in this case, the options passed by mount(8) will be those of
> > > the current
> > > + * mount and the options order should be a correct merge of fstab
> > > and mtab
> > > + * options, and new options given on the command line.
> > > + *
> > > + * So, in theory, it should be possible to compare incoming
> > > options and
> > > + * return an error for options that differ from the current mount
> > > and can't
> > > + * be changed on reconfigure to prevent users from believing they
> > > might have
> > > + * changed mount options using remount which can't be changed.
> > > + *
> > > + * But for now continue to return success for every reconfigure
> > > request, and
> > > + * silently ignore all options that can't actually be changed.
> > > + */
> > 
> > This seems like all good information for a commit log description or
> > perhaps to land in a common header where some of these fs context
> > bits
> > are declared, but overly broad for a function header comment for an
> > XFS
> > callback. I'd more expect some information around the fundamental
> > difference between 'mp' and 'new_mp,' where those come from, what
> > they
> > mean, etc. From the code, it seems like new_mp is transient and
> > reflects
> > changes that we need to incorporate in the original mp..?
> 
> The reason I looked into this is becuase of a fairly lengthy
> comment in the original source and that lead to this rather
> verbose tail about what I found.
> 
> It's not so much a mount context problem becuase it's due
> to the way user space constructs the mount options from
> various sources where options are present.
> 
> So I don't think it's something that the mount context
> code can resolve.
> 
> Which leaves a bunch of (I think) useful information
> without a palce to live so it can be referred to ...
> suggestions?
> 

I suppose there's always the commit log description if there isn't a
suitable place in the code.

Brian

> > 
> > Brian
> > 
> > > +STATIC int
> > > +xfs_reconfigure(
> > > +	struct fs_context *fc)
> > > +{
> > > +	struct xfs_fs_context	*ctx = fc->fs_private;
> > > +	struct xfs_mount	*mp = XFS_M(fc->root->d_sb);
> > > +	struct xfs_mount        *new_mp = fc->s_fs_info;
> > > +	xfs_sb_t		*sbp = &mp->m_sb;
> > > +	int			flags = fc->sb_flags;
> > > +	int			error;
> > > +
> > > +	error = xfs_validate_params(new_mp, ctx, false);
> > > +	if (error)
> > > +		return error;
> > > +
> > > +	/* inode32 -> inode64 */
> > > +	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> > > +	    !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> > > +		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> > > +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp-
> > > >sb_agcount);
> > > +	}
> > > +
> > > +	/* inode64 -> inode32 */
> > > +	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> > > +	    (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> > > +		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> > > +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp-
> > > >sb_agcount);
> > > +	}
> > > +
> > > +	/* ro -> rw */
> > > +	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags & SB_RDONLY)) {
> > > +		error = xfs_remount_rw(mp);
> > > +		if (error)
> > > +			return error;
> > > +	}
> > > +
> > > +	/* rw -> ro */
> > > +	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags & SB_RDONLY)) {
> > > +		error = xfs_remount_ro(mp);
> > > +		if (error)
> > > +			return error;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  /*
> > >   * Second stage of a freeze. The data is already frozen so we only
> > >   * need to take care of the metadata. Once that's done sync the
> > > superblock
> > > @@ -2049,6 +2132,7 @@ static const struct super_operations
> > > xfs_super_operations = {
> > >  static const struct fs_context_operations xfs_context_ops = {
> > >  	.parse_param = xfs_parse_param,
> > >  	.get_tree    = xfs_get_tree,
> > > +	.reconfigure = xfs_reconfigure,
> > >  };
> > >  
> > >  static struct file_system_type xfs_fs_type = {
> > > 
> 

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

* Re: [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure()
  2019-08-30 11:56       ` Brian Foster
@ 2019-09-02  2:41         ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-09-02  2:41 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Fri, 2019-08-30 at 07:56 -0400, Brian Foster wrote:
> On Fri, Aug 30, 2019 at 07:10:44PM +0800, Ian Kent wrote:
> > On Wed, 2019-08-28 at 09:28 -0400, Brian Foster wrote:
> > > On Fri, Aug 23, 2019 at 09:00:16AM +0800, Ian Kent wrote:
> > > > Add the fs_context_operations method .reconfigure that performs
> > > > remount validation as previously done by the super_operations
> > > > .remount_fs method.
> > > > 
> > > > An attempt has also been made to update the comment about
> > > > options
> > > > handling problems with mount(8) to reflect the current
> > > > situation.
> > > > 
> > > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > > ---
> > > >  fs/xfs/xfs_super.c |   84
> > > > ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 84 insertions(+)
> > > > 
> > > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > > index 76374d602257..aae0098fecab 100644
> > > > --- a/fs/xfs/xfs_super.c
> > > > +++ b/fs/xfs/xfs_super.c
> > > > @@ -1522,6 +1522,89 @@ xfs_fs_remount(
> > > >  	return 0;
> > > >  }
> > > >  
> > > > +/*
> > > > + * There have been problems in the past with options passed
> > > > from
> > > > mount(8).
> > > > + *
> > > > + * The problem being that options passed by mount(8) in the
> > > > case
> > > > where only
> > > > + * the the mount point path is given would consist of the
> > > > existing
> > > > fstab
> > > > + * options with the options from mtab for the current mount
> > > > merged
> > > > in and
> > > > + * the options given on the command line last. But the result
> > > > couldn't be
> > > > + * relied upon to accurately reflect the current mount options
> > > > so
> > > > that
> > > > + * rejecting options that can't be changed on reconfigure
> > > > could
> > > > erronously
> > > > + * cause mount failure.
> > > > + *
> > > > + * The mount-api uses a legacy mount options handler in the
> > > > VFS to
> > > > handle
> > > > + * mount(8) so these options will continue to be passed. Even
> > > > if
> > > > mount(8)
> > > > + * is updated to use fsopen()/fsconfig()/fsmount() it's likely
> > > > to
> > > > continue
> > > > + * to set the existing options so options problems with
> > > > reconfigure could
> > > > + * continue.
> > > > + *
> > > > + * For the longest time mtab locking was a problem and this
> > > > could
> > > > have been
> > > > + * one possible cause. It's also possible there could have
> > > > been
> > > > options
> > > > + * order problems.
> > > > + *
> > > > + * That has changed now as mtab is a link to the proc file
> > > > system
> > > > mount
> > > > + * table so mtab options should be always accurate.
> > > > + *
> > > > + * Consulting the util-linux maintainer (Karel Zak) he is
> > > > confident that,
> > > > + * in this case, the options passed by mount(8) will be those
> > > > of
> > > > the current
> > > > + * mount and the options order should be a correct merge of
> > > > fstab
> > > > and mtab
> > > > + * options, and new options given on the command line.
> > > > + *
> > > > + * So, in theory, it should be possible to compare incoming
> > > > options and
> > > > + * return an error for options that differ from the current
> > > > mount
> > > > and can't
> > > > + * be changed on reconfigure to prevent users from believing
> > > > they
> > > > might have
> > > > + * changed mount options using remount which can't be changed.
> > > > + *
> > > > + * But for now continue to return success for every
> > > > reconfigure
> > > > request, and
> > > > + * silently ignore all options that can't actually be changed.
> > > > + */
> > > 
> > > This seems like all good information for a commit log description
> > > or
> > > perhaps to land in a common header where some of these fs context
> > > bits
> > > are declared, but overly broad for a function header comment for
> > > an
> > > XFS
> > > callback. I'd more expect some information around the fundamental
> > > difference between 'mp' and 'new_mp,' where those come from, what
> > > they
> > > mean, etc. From the code, it seems like new_mp is transient and
> > > reflects
> > > changes that we need to incorporate in the original mp..?
> > 
> > The reason I looked into this is becuase of a fairly lengthy
> > comment in the original source and that lead to this rather
> > verbose tail about what I found.
> > 
> > It's not so much a mount context problem becuase it's due
> > to the way user space constructs the mount options from
> > various sources where options are present.
> > 
> > So I don't think it's something that the mount context
> > code can resolve.
> > 
> > Which leaves a bunch of (I think) useful information
> > without a palce to live so it can be referred to ...
> > suggestions?
> > 
> 
> I suppose there's always the commit log description if there isn't a
> suitable place in the code.

Ok, I'll try and cut it down to a more reasonable size while
keeping the gist of what it describes and move the detail
to the changelog entry.

> 
> Brian
> 
> > > Brian
> > > 
> > > > +STATIC int
> > > > +xfs_reconfigure(
> > > > +	struct fs_context *fc)
> > > > +{
> > > > +	struct xfs_fs_context	*ctx = fc->fs_private;
> > > > +	struct xfs_mount	*mp = XFS_M(fc->root->d_sb);
> > > > +	struct xfs_mount        *new_mp = fc->s_fs_info;
> > > > +	xfs_sb_t		*sbp = &mp->m_sb;
> > > > +	int			flags = fc->sb_flags;
> > > > +	int			error;
> > > > +
> > > > +	error = xfs_validate_params(new_mp, ctx, false);
> > > > +	if (error)
> > > > +		return error;
> > > > +
> > > > +	/* inode32 -> inode64 */
> > > > +	if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> > > > +	    !(new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> > > > +		mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
> > > > +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp-
> > > > > sb_agcount);
> > > > +	}
> > > > +
> > > > +	/* inode64 -> inode32 */
> > > > +	if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS) &&
> > > > +	    (new_mp->m_flags & XFS_MOUNT_SMALL_INUMS)) {
> > > > +		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> > > > +		mp->m_maxagi = xfs_set_inode_alloc(mp, sbp-
> > > > > sb_agcount);
> > > > +	}
> > > > +
> > > > +	/* ro -> rw */
> > > > +	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(flags &
> > > > SB_RDONLY)) {
> > > > +		error = xfs_remount_rw(mp);
> > > > +		if (error)
> > > > +			return error;
> > > > +	}
> > > > +
> > > > +	/* rw -> ro */
> > > > +	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags &
> > > > SB_RDONLY)) {
> > > > +		error = xfs_remount_ro(mp);
> > > > +		if (error)
> > > > +			return error;
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >  /*
> > > >   * Second stage of a freeze. The data is already frozen so we
> > > > only
> > > >   * need to take care of the metadata. Once that's done sync
> > > > the
> > > > superblock
> > > > @@ -2049,6 +2132,7 @@ static const struct super_operations
> > > > xfs_super_operations = {
> > > >  static const struct fs_context_operations xfs_context_ops = {
> > > >  	.parse_param = xfs_parse_param,
> > > >  	.get_tree    = xfs_get_tree,
> > > > +	.reconfigure = xfs_reconfigure,
> > > >  };
> > > >  
> > > >  static struct file_system_type xfs_fs_type = {
> > > > 


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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-08-27 12:39   ` Brian Foster
  2019-08-30 10:31     ` Ian Kent
@ 2019-09-17  3:13     ` Ian Kent
  2019-09-17 12:10       ` Brian Foster
  1 sibling, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-09-17  3:13 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:39 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> > The new mount-api uses an array of struct fs_parameter_spec for
> > parameter parsing, create this table populated with the xfs mount
> > parameters.
> > 
> > The new mount-api table definition is wider than the token based
> > parameter table and interleaving the option description comments
> > between each table line is much less readable than adding them to
> > the end of each table entry. So add the option description comment
> > to each entry line even though it causes quite a few of the entries
> > to be longer than 80 characters.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   48
> > +++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 45 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index f9450235533c..74c88b92ce22 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -38,6 +38,8 @@
> >  
> >  #include <linux/magic.h>
> >  #include <linux/parser.h>
> > +#include <linux/fs_context.h>
> > +#include <linux/fs_parser.h>
> >  
> >  static const struct super_operations xfs_super_operations;
> >  struct bio_set xfs_ioend_bioset;
> > @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-
> > level xfs sysfs dir */
> >  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs
> > attrs */
> >  #endif
> >  
> > -/*
> > - * Table driven mount option parser.
> > - */
> 
> Not sure why this is comment is removed here if the associated code
> is
> staying put in this patch..?
> 
> >  enum {
> >  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
> >  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth,
> > Opt_nouuid,
> > @@ -109,6 +108,49 @@ static const match_table_t tokens = {
> >  	{Opt_err,	NULL},
> >  };
> >  
> > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS
> > log buffers */
> > + fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS log
> > buffers */
> > + fsparam_string ("logdev",     Opt_logdev),    /* log device */
> > + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O
> > device */
> > + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of
> > preferred buffered io size */
> 
> Hmm.. it looks like the difference between numerical values as
> strings
> vs. numeric types is whether we support things like unit suffixes
> (i.e.
> "64k"). That said, Opt_biosize uses suffix_kstrtoint() similar to
> Opt_logbsize yet is defined here as a u32 (and Opt_allocsize falls
> into
> the same parsing code but is a string). Is that wrong or am I just
> missing something wrt to the type specifiers here?

Right, the distinction appeared to be between those that use a human
unit (like 64k etc.) and those that don't.

Opt_biosize looked different in that it's described to be "log2 of
preferred buffered io size" so I don't think it can be given as a
human unit and that also appeared to be the case from the original
options table.

Do I need to change this somehow?

> 
> Brian
> 
> > + fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs
> > compatible mount */
> > + fsparam_flag	("noalign",    Opt_noalign),   /* turn off
> > stripe alignment */
> > + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on
> > stripe width allocation */
> > + fsparam_u32	("sunit",      Opt_sunit),     /* data volume
> > stripe unit */
> > + fsparam_u32	("swidth",     Opt_swidth),    /* data volume
> > stripe width */
> > + fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore
> > filesystem UUID */
> > + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID from
> > parent directory (or not) */
> > + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from
> > parent directory */
> > + fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from
> > current process */
> > + fsparam_string ("allocsize",  Opt_allocsize), /* preferred
> > allocation size */
> > + fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS
> > recovery */
> > + fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be
> > allocated anywhere */
> > + fsparam_flag	("inode32",    Opt_inode32),   /* inode
> > allocation limited to XFS_MAXINUMBER_32 */
> > + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free (or
> > keep) empty inode clusters */
> > + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or do
> > not report) large I/O sizes in stat() */
> > + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do not)
> > use attr2 attribute format */
> > + fsparam_flag	("filestreams",Opt_filestreams), /* use
> > filestreams allocator */
> > + fsparam_flag_no("quota",      Opt_quota),     /* disk quotas
> > (user) */
> > + fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota
> > enabled */
> > + fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota
> > enabled */
> > + fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota
> > enabled */
> > + fsparam_flag	("uquota",     Opt_uquota),    /* user quota
> > (IRIX variant) */
> > + fsparam_flag	("gquota",     Opt_gquota),    /* group quota
> > (IRIX variant) */
> > + fsparam_flag	("pquota",     Opt_pquota),    /* project quota
> > (IRIX variant) */
> > + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota
> > limit enforcement */
> > + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota
> > limit enforcement */
> > + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project
> > quota limit enforcement */
> > + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as
> > uqnoenforce */
> > + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do not)
> > not discard unused blocks */
> > + fsparam_flag	("dax",	       Opt_dax),       /* Enable
> > direct access to bdev pages */
> > + {}
> > +};
> > +
> > +static const struct fs_parameter_description xfs_fs_parameters = {
> > +	.name		= "XFS",
> > +	.specs		= xfs_param_specs,
> > +};
> >  
> >  STATIC int
> >  suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > *res)
> > 


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

* Re: [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint()
  2019-08-27 12:40   ` Brian Foster
  2019-08-30 10:33     ` Ian Kent
@ 2019-09-17  4:31     ` Ian Kent
  2019-09-17 12:10       ` Brian Foster
  1 sibling, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-09-17  4:31 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-08-27 at 08:40 -0400, Brian Foster wrote:
> On Fri, Aug 23, 2019 at 08:59:33AM +0800, Ian Kent wrote:
> > The mount-api doesn't have a "human unit" parse type yet so
> > the options that have values like "10k" etc. still need to
> > be converted by the fs.
> > 
> > But the value comes to the fs as a string (not a substring_t
> > type) so there's a need to change the conversion function to
> > take a character string instead.
> > 
> > After refactoring xfs_parseargs() and changing it to use
> > xfs_parse_param() match_kstrtoint() will no longer be used
> > and will be removed.
> > 
> > Signed-off-by: Ian Kent <raven@themaw.net>
> > ---
> >  fs/xfs/xfs_super.c |   22 ++++++++++++++++++----
> >  1 file changed, 18 insertions(+), 4 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 74c88b92ce22..49c87fb921f1 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -153,13 +153,13 @@ static const struct fs_parameter_description
> > xfs_fs_parameters = {
> >  };
> >  
> >  STATIC int
> > -suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > *res)
> > +suffix_kstrtoint(const char *s, unsigned int base, int *res)
> >  {
> >  	int	last, shift_left_factor = 0, _res;
> >  	char	*value;
> >  	int	ret = 0;
> >  
> > -	value = match_strdup(s);
> > +	value = kstrdup(s, GFP_KERNEL);
> >  	if (!value)
> >  		return -ENOMEM;
> >  
> > @@ -184,6 +184,20 @@ suffix_kstrtoint(const substring_t *s,
> > unsigned int base, int *res)
> >  	return ret;
> >  }
> >  
> > +STATIC int
> > +match_kstrtoint(const substring_t *s, unsigned int base, int *res)
> > +{
> > +	const char	*value;
> > +	int ret;
> > +
> > +	value = match_strdup(s);
> > +	if (!value)
> > +		return -ENOMEM;
> > +	ret = suffix_kstrtoint(value, base, res);
> > +	kfree(value);
> > +	return ret;
> > +}
> > +
> 
> I guess the use case isn't clear to me yet and it's not critical if
> this
> code is going away by the end of the series, but why not refactor
> into a
> __suffix_kstrtoint(char *s, ...) variant that accepts an already
> duplicated string so we don't have to duplicate each string twice in
> the
> match_kstrtoint() case?

I guess, it seemed sensible to me to create the needed function (that
doesn't take the substring_t returned by the existing tokenizer) and
just adapt the replacement to work with that, essentially because it
is going to go away fairly soon after ...

Also I think your suggestion would require creating a helper that
would be used by both and then would later need to be merged back
into the caller, having only one caller left at that point which
is, I think, unnecessary code churn.

Not sure I'm terribly worried about this one myself but if it really
bugs you I will change it.

> 
> Brian
> 
> >  /*
> >   * This function fills in xfs_mount_t fields based on mount args.
> >   * Note: the superblock has _not_ yet been read in.
> > @@ -255,7 +269,7 @@ xfs_parseargs(
> >  				return -EINVAL;
> >  			break;
> >  		case Opt_logbsize:
> > -			if (suffix_kstrtoint(args, 10, &mp-
> > >m_logbsize))
> > +			if (match_kstrtoint(args, 10, &mp->m_logbsize))
> >  				return -EINVAL;
> >  			break;
> >  		case Opt_logdev:
> > @@ -272,7 +286,7 @@ xfs_parseargs(
> >  			break;
> >  		case Opt_allocsize:
> >  		case Opt_biosize:
> > -			if (suffix_kstrtoint(args, 10, &iosize))
> > +			if (match_kstrtoint(args, 10, &iosize))
> >  				return -EINVAL;
> >  			iosizelog = ffs(iosize) - 1;
> >  			break;
> > 


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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-09-17  3:13     ` Ian Kent
@ 2019-09-17 12:10       ` Brian Foster
  2019-09-18  3:43         ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Brian Foster @ 2019-09-17 12:10 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, Sep 17, 2019 at 11:13:20AM +0800, Ian Kent wrote:
> On Tue, 2019-08-27 at 08:39 -0400, Brian Foster wrote:
> > On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> > > The new mount-api uses an array of struct fs_parameter_spec for
> > > parameter parsing, create this table populated with the xfs mount
> > > parameters.
> > > 
> > > The new mount-api table definition is wider than the token based
> > > parameter table and interleaving the option description comments
> > > between each table line is much less readable than adding them to
> > > the end of each table entry. So add the option description comment
> > > to each entry line even though it causes quite a few of the entries
> > > to be longer than 80 characters.
> > > 
> > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > ---
> > >  fs/xfs/xfs_super.c |   48
> > > +++++++++++++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 45 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > index f9450235533c..74c88b92ce22 100644
> > > --- a/fs/xfs/xfs_super.c
> > > +++ b/fs/xfs/xfs_super.c
> > > @@ -38,6 +38,8 @@
> > >  
> > >  #include <linux/magic.h>
> > >  #include <linux/parser.h>
> > > +#include <linux/fs_context.h>
> > > +#include <linux/fs_parser.h>
> > >  
> > >  static const struct super_operations xfs_super_operations;
> > >  struct bio_set xfs_ioend_bioset;
> > > @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-
> > > level xfs sysfs dir */
> > >  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs
> > > attrs */
> > >  #endif
> > >  
> > > -/*
> > > - * Table driven mount option parser.
> > > - */
> > 
> > Not sure why this is comment is removed here if the associated code
> > is
> > staying put in this patch..?
> > 
> > >  enum {
> > >  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
> > >  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth,
> > > Opt_nouuid,
> > > @@ -109,6 +108,49 @@ static const match_table_t tokens = {
> > >  	{Opt_err,	NULL},
> > >  };
> > >  
> > > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > > + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS
> > > log buffers */
> > > + fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS log
> > > buffers */
> > > + fsparam_string ("logdev",     Opt_logdev),    /* log device */
> > > + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O
> > > device */
> > > + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of
> > > preferred buffered io size */
> > 
> > Hmm.. it looks like the difference between numerical values as
> > strings
> > vs. numeric types is whether we support things like unit suffixes
> > (i.e.
> > "64k"). That said, Opt_biosize uses suffix_kstrtoint() similar to
> > Opt_logbsize yet is defined here as a u32 (and Opt_allocsize falls
> > into
> > the same parsing code but is a string). Is that wrong or am I just
> > missing something wrt to the type specifiers here?
> 
> Right, the distinction appeared to be between those that use a human
> unit (like 64k etc.) and those that don't.
> 
> Opt_biosize looked different in that it's described to be "log2 of
> preferred buffered io size" so I don't think it can be given as a
> human unit and that also appeared to be the case from the original
> options table.
> 
> Do I need to change this somehow?
> 

I'm not sure. Can you respond to the question in my most recent reply[1]
to this patch please?

Brian

[1] https://lore.kernel.org/linux-xfs/20190830115611.GA25927@bfoster/

> > 
> > Brian
> > 
> > > + fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs
> > > compatible mount */
> > > + fsparam_flag	("noalign",    Opt_noalign),   /* turn off
> > > stripe alignment */
> > > + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on
> > > stripe width allocation */
> > > + fsparam_u32	("sunit",      Opt_sunit),     /* data volume
> > > stripe unit */
> > > + fsparam_u32	("swidth",     Opt_swidth),    /* data volume
> > > stripe width */
> > > + fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore
> > > filesystem UUID */
> > > + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID from
> > > parent directory (or not) */
> > > + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from
> > > parent directory */
> > > + fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from
> > > current process */
> > > + fsparam_string ("allocsize",  Opt_allocsize), /* preferred
> > > allocation size */
> > > + fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS
> > > recovery */
> > > + fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be
> > > allocated anywhere */
> > > + fsparam_flag	("inode32",    Opt_inode32),   /* inode
> > > allocation limited to XFS_MAXINUMBER_32 */
> > > + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free (or
> > > keep) empty inode clusters */
> > > + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or do
> > > not report) large I/O sizes in stat() */
> > > + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do not)
> > > use attr2 attribute format */
> > > + fsparam_flag	("filestreams",Opt_filestreams), /* use
> > > filestreams allocator */
> > > + fsparam_flag_no("quota",      Opt_quota),     /* disk quotas
> > > (user) */
> > > + fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota
> > > enabled */
> > > + fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota
> > > enabled */
> > > + fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota
> > > enabled */
> > > + fsparam_flag	("uquota",     Opt_uquota),    /* user quota
> > > (IRIX variant) */
> > > + fsparam_flag	("gquota",     Opt_gquota),    /* group quota
> > > (IRIX variant) */
> > > + fsparam_flag	("pquota",     Opt_pquota),    /* project quota
> > > (IRIX variant) */
> > > + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota
> > > limit enforcement */
> > > + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota
> > > limit enforcement */
> > > + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project
> > > quota limit enforcement */
> > > + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as
> > > uqnoenforce */
> > > + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do not)
> > > not discard unused blocks */
> > > + fsparam_flag	("dax",	       Opt_dax),       /* Enable
> > > direct access to bdev pages */
> > > + {}
> > > +};
> > > +
> > > +static const struct fs_parameter_description xfs_fs_parameters = {
> > > +	.name		= "XFS",
> > > +	.specs		= xfs_param_specs,
> > > +};
> > >  
> > >  STATIC int
> > >  suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > > *res)
> > > 
> 

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

* Re: [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint()
  2019-09-17  4:31     ` Ian Kent
@ 2019-09-17 12:10       ` Brian Foster
  0 siblings, 0 replies; 58+ messages in thread
From: Brian Foster @ 2019-09-17 12:10 UTC (permalink / raw)
  To: Ian Kent; +Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, Sep 17, 2019 at 12:31:32PM +0800, Ian Kent wrote:
> On Tue, 2019-08-27 at 08:40 -0400, Brian Foster wrote:
> > On Fri, Aug 23, 2019 at 08:59:33AM +0800, Ian Kent wrote:
> > > The mount-api doesn't have a "human unit" parse type yet so
> > > the options that have values like "10k" etc. still need to
> > > be converted by the fs.
> > > 
> > > But the value comes to the fs as a string (not a substring_t
> > > type) so there's a need to change the conversion function to
> > > take a character string instead.
> > > 
> > > After refactoring xfs_parseargs() and changing it to use
> > > xfs_parse_param() match_kstrtoint() will no longer be used
> > > and will be removed.
> > > 
> > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > ---
> > >  fs/xfs/xfs_super.c |   22 ++++++++++++++++++----
> > >  1 file changed, 18 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > index 74c88b92ce22..49c87fb921f1 100644
> > > --- a/fs/xfs/xfs_super.c
> > > +++ b/fs/xfs/xfs_super.c
> > > @@ -153,13 +153,13 @@ static const struct fs_parameter_description
> > > xfs_fs_parameters = {
> > >  };
> > >  
> > >  STATIC int
> > > -suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > > *res)
> > > +suffix_kstrtoint(const char *s, unsigned int base, int *res)
> > >  {
> > >  	int	last, shift_left_factor = 0, _res;
> > >  	char	*value;
> > >  	int	ret = 0;
> > >  
> > > -	value = match_strdup(s);
> > > +	value = kstrdup(s, GFP_KERNEL);
> > >  	if (!value)
> > >  		return -ENOMEM;
> > >  
> > > @@ -184,6 +184,20 @@ suffix_kstrtoint(const substring_t *s,
> > > unsigned int base, int *res)
> > >  	return ret;
> > >  }
> > >  
> > > +STATIC int
> > > +match_kstrtoint(const substring_t *s, unsigned int base, int *res)
> > > +{
> > > +	const char	*value;
> > > +	int ret;
> > > +
> > > +	value = match_strdup(s);
> > > +	if (!value)
> > > +		return -ENOMEM;
> > > +	ret = suffix_kstrtoint(value, base, res);
> > > +	kfree(value);
> > > +	return ret;
> > > +}
> > > +
> > 
> > I guess the use case isn't clear to me yet and it's not critical if
> > this
> > code is going away by the end of the series, but why not refactor
> > into a
> > __suffix_kstrtoint(char *s, ...) variant that accepts an already
> > duplicated string so we don't have to duplicate each string twice in
> > the
> > match_kstrtoint() case?
> 
> I guess, it seemed sensible to me to create the needed function (that
> doesn't take the substring_t returned by the existing tokenizer) and
> just adapt the replacement to work with that, essentially because it
> is going to go away fairly soon after ...
> 
> Also I think your suggestion would require creating a helper that
> would be used by both and then would later need to be merged back
> into the caller, having only one caller left at that point which
> is, I think, unnecessary code churn.
> 
> Not sure I'm terribly worried about this one myself but if it really
> bugs you I will change it.
> 

Ok, not a big deal. I don't think I was aware of the transient nature on
the first review pass..

Brian

> > 
> > Brian
> > 
> > >  /*
> > >   * This function fills in xfs_mount_t fields based on mount args.
> > >   * Note: the superblock has _not_ yet been read in.
> > > @@ -255,7 +269,7 @@ xfs_parseargs(
> > >  				return -EINVAL;
> > >  			break;
> > >  		case Opt_logbsize:
> > > -			if (suffix_kstrtoint(args, 10, &mp-
> > > >m_logbsize))
> > > +			if (match_kstrtoint(args, 10, &mp->m_logbsize))
> > >  				return -EINVAL;
> > >  			break;
> > >  		case Opt_logdev:
> > > @@ -272,7 +286,7 @@ xfs_parseargs(
> > >  			break;
> > >  		case Opt_allocsize:
> > >  		case Opt_biosize:
> > > -			if (suffix_kstrtoint(args, 10, &iosize))
> > > +			if (match_kstrtoint(args, 10, &iosize))
> > >  				return -EINVAL;
> > >  			iosizelog = ffs(iosize) - 1;
> > >  			break;
> > > 
> 

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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-09-17 12:10       ` Brian Foster
@ 2019-09-18  3:43         ` Ian Kent
  2019-09-18  3:49           ` Ian Kent
  0 siblings, 1 reply; 58+ messages in thread
From: Ian Kent @ 2019-09-18  3:43 UTC (permalink / raw)
  To: Brian Foster
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Tue, 2019-09-17 at 08:10 -0400, Brian Foster wrote:
> On Tue, Sep 17, 2019 at 11:13:20AM +0800, Ian Kent wrote:
> > On Tue, 2019-08-27 at 08:39 -0400, Brian Foster wrote:
> > > On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> > > > The new mount-api uses an array of struct fs_parameter_spec for
> > > > parameter parsing, create this table populated with the xfs
> > > > mount
> > > > parameters.
> > > > 
> > > > The new mount-api table definition is wider than the token
> > > > based
> > > > parameter table and interleaving the option description
> > > > comments
> > > > between each table line is much less readable than adding them
> > > > to
> > > > the end of each table entry. So add the option description
> > > > comment
> > > > to each entry line even though it causes quite a few of the
> > > > entries
> > > > to be longer than 80 characters.
> > > > 
> > > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > > ---
> > > >  fs/xfs/xfs_super.c |   48
> > > > +++++++++++++++++++++++++++++++++++++++++++++---
> > > >  1 file changed, 45 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > > index f9450235533c..74c88b92ce22 100644
> > > > --- a/fs/xfs/xfs_super.c
> > > > +++ b/fs/xfs/xfs_super.c
> > > > @@ -38,6 +38,8 @@
> > > >  
> > > >  #include <linux/magic.h>
> > > >  #include <linux/parser.h>
> > > > +#include <linux/fs_context.h>
> > > > +#include <linux/fs_parser.h>
> > > >  
> > > >  static const struct super_operations xfs_super_operations;
> > > >  struct bio_set xfs_ioend_bioset;
> > > > @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		/* top-
> > > > level xfs sysfs dir */
> > > >  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs
> > > > attrs */
> > > >  #endif
> > > >  
> > > > -/*
> > > > - * Table driven mount option parser.
> > > > - */
> > > 
> > > Not sure why this is comment is removed here if the associated
> > > code
> > > is
> > > staying put in this patch..?
> > > 
> > > >  enum {
> > > >  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev,
> > > > Opt_biosize,
> > > >  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit,
> > > > Opt_swidth,
> > > > Opt_nouuid,
> > > > @@ -109,6 +108,49 @@ static const match_table_t tokens = {
> > > >  	{Opt_err,	NULL},
> > > >  };
> > > >  
> > > > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > > > + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS
> > > > log buffers */
> > > > + fsparam_string ("logbsize",   Opt_logbsize),  /* size of XFS
> > > > log
> > > > buffers */
> > > > + fsparam_string ("logdev",     Opt_logdev),    /* log device
> > > > */
> > > > + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime I/O
> > > > device */
> > > > + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of
> > > > preferred buffered io size */
> > > 
> > > Hmm.. it looks like the difference between numerical values as
> > > strings
> > > vs. numeric types is whether we support things like unit suffixes
> > > (i.e.
> > > "64k"). That said, Opt_biosize uses suffix_kstrtoint() similar to
> > > Opt_logbsize yet is defined here as a u32 (and Opt_allocsize
> > > falls
> > > into
> > > the same parsing code but is a string). Is that wrong or am I
> > > just
> > > missing something wrt to the type specifiers here?
> > 
> > Right, the distinction appeared to be between those that use a
> > human
> > unit (like 64k etc.) and those that don't.
> > 
> > Opt_biosize looked different in that it's described to be "log2 of
> > preferred buffered io size" so I don't think it can be given as a
> > human unit and that also appeared to be the case from the original
> > options table.
> > 
> > Do I need to change this somehow?
> > 
> 
> I'm not sure. Can you respond to the question in my most recent
> reply[1]
> to this patch please?
> 
> Brian
> 
> [1] https://lore.kernel.org/linux-xfs/20190830115611.GA25927@bfoster/

I see, yes, they are different in the unchanged source.

It seems to me that the handling of these should be changed since
it looks like Opt_allocsize can have a human unit value while
Opt_biosize, given it's listed as a log2 value, it doesn't make
sense to call suffix_kstrtoint() on it.

Maybe that should be corrected as a pre-patch in the series or
forwarded separately ... although I can see how this has gone 
unnoticed.

> 
> > > Brian
> > > 
> > > > + fsparam_flag	("wsync",      Opt_wsync),     /* safe-mode nfs
> > > > compatible mount */
> > > > + fsparam_flag	("noalign",    Opt_noalign),   /* turn off
> > > > stripe alignment */
> > > > + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn on
> > > > stripe width allocation */
> > > > + fsparam_u32	("sunit",      Opt_sunit),     /* data volume
> > > > stripe unit */
> > > > + fsparam_u32	("swidth",     Opt_swidth),    /* data volume
> > > > stripe width */
> > > > + fsparam_flag	("nouuid",     Opt_nouuid),    /* ignore
> > > > filesystem UUID */
> > > > + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID
> > > > from
> > > > parent directory (or not) */
> > > > + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /* group-ID from
> > > > parent directory */
> > > > + fsparam_flag	("sysvgroups", Opt_sysvgroups),/* group-ID from
> > > > current process */
> > > > + fsparam_string ("allocsize",  Opt_allocsize), /* preferred
> > > > allocation size */
> > > > + fsparam_flag	("norecovery", Opt_norecovery),/* don't run XFS
> > > > recovery */
> > > > + fsparam_flag	("inode64",    Opt_inode64),   /* inodes can be
> > > > allocated anywhere */
> > > > + fsparam_flag	("inode32",    Opt_inode32),   /* inode
> > > > allocation limited to XFS_MAXINUMBER_32 */
> > > > + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not free
> > > > (or
> > > > keep) empty inode clusters */
> > > > + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or
> > > > do
> > > > not report) large I/O sizes in stat() */
> > > > + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do
> > > > not)
> > > > use attr2 attribute format */
> > > > + fsparam_flag	("filestreams",Opt_filestreams), /* use
> > > > filestreams allocator */
> > > > + fsparam_flag_no("quota",      Opt_quota),     /* disk quotas
> > > > (user) */
> > > > + fsparam_flag	("usrquota",   Opt_usrquota),  /* user quota
> > > > enabled */
> > > > + fsparam_flag	("grpquota",   Opt_grpquota),  /* group quota
> > > > enabled */
> > > > + fsparam_flag	("prjquota",   Opt_prjquota),  /* project quota
> > > > enabled */
> > > > + fsparam_flag	("uquota",     Opt_uquota),    /* user quota
> > > > (IRIX variant) */
> > > > + fsparam_flag	("gquota",     Opt_gquota),    /* group quota
> > > > (IRIX variant) */
> > > > + fsparam_flag	("pquota",     Opt_pquota),    /* project quota
> > > > (IRIX variant) */
> > > > + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /* user quota
> > > > limit enforcement */
> > > > + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /* group quota
> > > > limit enforcement */
> > > > + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /* project
> > > > quota limit enforcement */
> > > > + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /* same as
> > > > uqnoenforce */
> > > > + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do
> > > > not)
> > > > not discard unused blocks */
> > > > + fsparam_flag	("dax",	       Opt_dax),       /* Enable
> > > > direct access to bdev pages */
> > > > + {}
> > > > +};
> > > > +
> > > > +static const struct fs_parameter_description xfs_fs_parameters
> > > > = {
> > > > +	.name		= "XFS",
> > > > +	.specs		= xfs_param_specs,
> > > > +};
> > > >  
> > > >  STATIC int
> > > >  suffix_kstrtoint(const substring_t *s, unsigned int base, int
> > > > *res)
> > > > 


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

* Re: [PATCH v2 02/15] xfs: mount-api - add fs parameter description
  2019-09-18  3:43         ` Ian Kent
@ 2019-09-18  3:49           ` Ian Kent
  0 siblings, 0 replies; 58+ messages in thread
From: Ian Kent @ 2019-09-18  3:49 UTC (permalink / raw)
  To: Brian Foster, Darrick J. Wong
  Cc: linux-xfs, Dave Chinner, David Howells, Al Viro, Eric Sandeen

On Wed, 2019-09-18 at 11:43 +0800, Ian Kent wrote:
> On Tue, 2019-09-17 at 08:10 -0400, Brian Foster wrote:
> > On Tue, Sep 17, 2019 at 11:13:20AM +0800, Ian Kent wrote:
> > > On Tue, 2019-08-27 at 08:39 -0400, Brian Foster wrote:
> > > > On Fri, Aug 23, 2019 at 08:59:27AM +0800, Ian Kent wrote:
> > > > > The new mount-api uses an array of struct fs_parameter_spec
> > > > > for
> > > > > parameter parsing, create this table populated with the xfs
> > > > > mount
> > > > > parameters.
> > > > > 
> > > > > The new mount-api table definition is wider than the token
> > > > > based
> > > > > parameter table and interleaving the option description
> > > > > comments
> > > > > between each table line is much less readable than adding
> > > > > them
> > > > > to
> > > > > the end of each table entry. So add the option description
> > > > > comment
> > > > > to each entry line even though it causes quite a few of the
> > > > > entries
> > > > > to be longer than 80 characters.
> > > > > 
> > > > > Signed-off-by: Ian Kent <raven@themaw.net>
> > > > > ---
> > > > >  fs/xfs/xfs_super.c |   48
> > > > > +++++++++++++++++++++++++++++++++++++++++++++---
> > > > >  1 file changed, 45 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > > > index f9450235533c..74c88b92ce22 100644
> > > > > --- a/fs/xfs/xfs_super.c
> > > > > +++ b/fs/xfs/xfs_super.c
> > > > > @@ -38,6 +38,8 @@
> > > > >  
> > > > >  #include <linux/magic.h>
> > > > >  #include <linux/parser.h>
> > > > > +#include <linux/fs_context.h>
> > > > > +#include <linux/fs_parser.h>
> > > > >  
> > > > >  static const struct super_operations xfs_super_operations;
> > > > >  struct bio_set xfs_ioend_bioset;
> > > > > @@ -47,9 +49,6 @@ static struct kset *xfs_kset;		
> > > > > /* top-
> > > > > level xfs sysfs dir */
> > > > >  static struct xfs_kobj xfs_dbg_kobj;	/* global debug sysfs
> > > > > attrs */
> > > > >  #endif
> > > > >  
> > > > > -/*
> > > > > - * Table driven mount option parser.
> > > > > - */
> > > > 
> > > > Not sure why this is comment is removed here if the associated
> > > > code
> > > > is
> > > > staying put in this patch..?
> > > > 
> > > > >  enum {
> > > > >  	Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev,
> > > > > Opt_biosize,
> > > > >  	Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit,
> > > > > Opt_swidth,
> > > > > Opt_nouuid,
> > > > > @@ -109,6 +108,49 @@ static const match_table_t tokens = {
> > > > >  	{Opt_err,	NULL},
> > > > >  };
> > > > >  
> > > > > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > > > > + fsparam_u32	("logbufs",    Opt_logbufs),   /* number of XFS
> > > > > log buffers */
> > > > > + fsparam_string ("logbsize",   Opt_logbsize),  /* size of
> > > > > XFS
> > > > > log
> > > > > buffers */
> > > > > + fsparam_string ("logdev",     Opt_logdev),    /* log device
> > > > > */
> > > > > + fsparam_string ("rtdev",      Opt_rtdev),     /* realtime
> > > > > I/O
> > > > > device */
> > > > > + fsparam_u32	("biosize",    Opt_biosize),   /* log2 of
> > > > > preferred buffered io size */
> > > > 
> > > > Hmm.. it looks like the difference between numerical values as
> > > > strings
> > > > vs. numeric types is whether we support things like unit
> > > > suffixes
> > > > (i.e.
> > > > "64k"). That said, Opt_biosize uses suffix_kstrtoint() similar
> > > > to
> > > > Opt_logbsize yet is defined here as a u32 (and Opt_allocsize
> > > > falls
> > > > into
> > > > the same parsing code but is a string). Is that wrong or am I
> > > > just
> > > > missing something wrt to the type specifiers here?
> > > 
> > > Right, the distinction appeared to be between those that use a
> > > human
> > > unit (like 64k etc.) and those that don't.
> > > 
> > > Opt_biosize looked different in that it's described to be "log2
> > > of
> > > preferred buffered io size" so I don't think it can be given as a
> > > human unit and that also appeared to be the case from the
> > > original
> > > options table.
> > > 
> > > Do I need to change this somehow?
> > > 
> > 
> > I'm not sure. Can you respond to the question in my most recent
> > reply[1]
> > to this patch please?
> > 
> > Brian
> > 
> > [1] 
> > https://lore.kernel.org/linux-xfs/20190830115611.GA25927@bfoster/
> 
> I see, yes, they are different in the unchanged source.
> 
> It seems to me that the handling of these should be changed since
> it looks like Opt_allocsize can have a human unit value while
> Opt_biosize, given it's listed as a log2 value, it doesn't make
> sense to call suffix_kstrtoint() on it.
> 
> Maybe that should be corrected as a pre-patch in the series or
> forwarded separately ... although I can see how this has gone 
> unnoticed.

Ha, and surely there needs to be a conversion of some sort if
they really are different unit values ...

Darrick?

> 
> > > > Brian
> > > > 
> > > > > + fsparam_flag	("wsync",      Opt_wsync),     /* safe-
> > > > > mode nfs
> > > > > compatible mount */
> > > > > + fsparam_flag	("noalign",    Opt_noalign),   /* turn
> > > > > off
> > > > > stripe alignment */
> > > > > + fsparam_flag	("swalloc",    Opt_swalloc),   /* turn
> > > > > on
> > > > > stripe width allocation */
> > > > > + fsparam_u32	("sunit",      Opt_sunit),     /* data volume
> > > > > stripe unit */
> > > > > + fsparam_u32	("swidth",     Opt_swidth),    /* data volume
> > > > > stripe width */
> > > > > + fsparam_flag	("nouuid",     Opt_nouuid),    /*
> > > > > ignore
> > > > > filesystem UUID */
> > > > > + fsparam_flag_no("grpid",      Opt_grpid),     /* group-ID
> > > > > from
> > > > > parent directory (or not) */
> > > > > + fsparam_flag	("bsdgroups",  Opt_bsdgroups), /*
> > > > > group-ID from
> > > > > parent directory */
> > > > > + fsparam_flag	("sysvgroups", Opt_sysvgroups),/*
> > > > > group-ID from
> > > > > current process */
> > > > > + fsparam_string ("allocsize",  Opt_allocsize), /* preferred
> > > > > allocation size */
> > > > > + fsparam_flag	("norecovery", Opt_norecovery),/* don't
> > > > > run XFS
> > > > > recovery */
> > > > > + fsparam_flag	("inode64",    Opt_inode64),   /*
> > > > > inodes can be
> > > > > allocated anywhere */
> > > > > + fsparam_flag	("inode32",    Opt_inode32),   /* inode
> > > > > allocation limited to XFS_MAXINUMBER_32 */
> > > > > + fsparam_flag_no("ikeep",      Opt_ikeep),     /* do not
> > > > > free
> > > > > (or
> > > > > keep) empty inode clusters */
> > > > > + fsparam_flag_no("largeio",    Opt_largeio),   /* report (or
> > > > > do
> > > > > not report) large I/O sizes in stat() */
> > > > > + fsparam_flag_no("attr2",      Opt_attr2),     /* do (or do
> > > > > not)
> > > > > use attr2 attribute format */
> > > > > + fsparam_flag	("filestreams",Opt_filestreams), /* use
> > > > > filestreams allocator */
> > > > > + fsparam_flag_no("quota",      Opt_quota),     /* disk
> > > > > quotas
> > > > > (user) */
> > > > > + fsparam_flag	("usrquota",   Opt_usrquota),  /* user
> > > > > quota
> > > > > enabled */
> > > > > + fsparam_flag	("grpquota",   Opt_grpquota),  /* group
> > > > > quota
> > > > > enabled */
> > > > > + fsparam_flag	("prjquota",   Opt_prjquota),  /*
> > > > > project quota
> > > > > enabled */
> > > > > + fsparam_flag	("uquota",     Opt_uquota),    /* user
> > > > > quota
> > > > > (IRIX variant) */
> > > > > + fsparam_flag	("gquota",     Opt_gquota),    /* group
> > > > > quota
> > > > > (IRIX variant) */
> > > > > + fsparam_flag	("pquota",     Opt_pquota),    /*
> > > > > project quota
> > > > > (IRIX variant) */
> > > > > + fsparam_flag	("uqnoenforce",Opt_uqnoenforce), /*
> > > > > user quota
> > > > > limit enforcement */
> > > > > + fsparam_flag	("gqnoenforce",Opt_gqnoenforce), /*
> > > > > group quota
> > > > > limit enforcement */
> > > > > + fsparam_flag	("pqnoenforce",Opt_pqnoenforce), /*
> > > > > project
> > > > > quota limit enforcement */
> > > > > + fsparam_flag	("qnoenforce", Opt_qnoenforce),  /*
> > > > > same as
> > > > > uqnoenforce */
> > > > > + fsparam_flag_no("discard",    Opt_discard),   /* Do (or do
> > > > > not)
> > > > > not discard unused blocks */
> > > > > + fsparam_flag	("dax",	       Opt_dax),       /*
> > > > > Enable
> > > > > direct access to bdev pages */
> > > > > + {}
> > > > > +};
> > > > > +
> > > > > +static const struct fs_parameter_description
> > > > > xfs_fs_parameters
> > > > > = {
> > > > > +	.name		= "XFS",
> > > > > +	.specs		= xfs_param_specs,
> > > > > +};
> > > > >  
> > > > >  STATIC int
> > > > >  suffix_kstrtoint(const substring_t *s, unsigned int base,
> > > > > int
> > > > > *res)
> > > > > 


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

end of thread, other threads:[~2019-09-18  3:49 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-23  0:59 [PATCH v2 00/15] xfs: mount API patch series Ian Kent
2019-08-23  0:59 ` [PATCH v2 01/15] vfs: Create fs_context-aware mount_bdev() replacement Ian Kent
2019-08-23  0:59 ` [PATCH v2 02/15] xfs: mount-api - add fs parameter description Ian Kent
2019-08-27 12:39   ` Brian Foster
2019-08-30 10:31     ` Ian Kent
2019-08-30 11:56       ` Brian Foster
2019-09-17  3:13     ` Ian Kent
2019-09-17 12:10       ` Brian Foster
2019-09-18  3:43         ` Ian Kent
2019-09-18  3:49           ` Ian Kent
2019-08-23  0:59 ` [PATCH v2 03/15] xfs: mount-api - refactor suffix_kstrtoint() Ian Kent
2019-08-27 12:40   ` Brian Foster
2019-08-30 10:33     ` Ian Kent
2019-09-17  4:31     ` Ian Kent
2019-09-17 12:10       ` Brian Foster
2019-08-23  0:59 ` [PATCH v2 04/15] xfs: mount-api - refactor xfs_parseags() Ian Kent
2019-08-27 12:40   ` Brian Foster
2019-08-23  0:59 ` [PATCH v2 05/15] xfs: mount-api - make xfs_parse_param() take context .parse_param() args Ian Kent
2019-08-26 19:19   ` Eric Sandeen
2019-08-26 19:31     ` Eric Sandeen
2019-08-26 19:32       ` Eric Sandeen
2019-08-30 10:23       ` Ian Kent
2019-08-27 12:41   ` Brian Foster
2019-08-27 15:10     ` Darrick J. Wong
2019-08-27 15:15       ` Eric Sandeen
2019-08-28  0:55         ` Ian Kent
2019-08-30 10:51     ` Ian Kent
2019-08-23  0:59 ` [PATCH v2 06/15] xfs: mount-api - move xfs_parseargs() validation to a helper Ian Kent
2019-08-27 12:41   ` Brian Foster
2019-08-30 10:55     ` Ian Kent
2019-08-23  0:59 ` [PATCH v2 07/15] xfs: mount-api - refactor xfs_fs_fill_super() Ian Kent
2019-08-27 12:42   ` Brian Foster
2019-08-30 10:56     ` Ian Kent
2019-08-23  0:59 ` [PATCH v2 08/15] xfs: mount-api - add xfs_get_tree() Ian Kent
2019-08-28 13:27   ` Brian Foster
2019-08-30 11:01     ` Ian Kent
2019-08-23  1:00 ` [PATCH v2 09/15] xfs: mount-api - add xfs_remount_rw() helper Ian Kent
2019-08-28 13:27   ` Brian Foster
2019-08-23  1:00 ` [PATCH v2 10/15] xfs: mount-api - add xfs_remount_ro() helper Ian Kent
2019-08-28 13:27   ` Brian Foster
2019-08-23  1:00 ` [PATCH v2 11/15] xfs: mount api - add xfs_reconfigure() Ian Kent
2019-08-28 13:28   ` Brian Foster
2019-08-30 11:10     ` Ian Kent
2019-08-30 11:56       ` Brian Foster
2019-09-02  2:41         ` Ian Kent
2019-08-23  1:00 ` [PATCH v2 12/15] xfs: mount-api - add xfs_fc_free() Ian Kent
2019-08-28 13:28   ` Brian Foster
2019-08-30 11:19     ` Ian Kent
2019-08-30 11:20     ` Ian Kent
2019-08-23  1:00 ` [PATCH v2 13/15] xfs: mount-api - dont set sb in xfs_mount_alloc() Ian Kent
2019-08-28 13:28   ` Brian Foster
2019-08-23  1:00 ` [PATCH v2 14/15] xfs: mount-api - switch to new mount-api Ian Kent
2019-08-28 13:29   ` Brian Foster
2019-08-28 13:34     ` Eric Sandeen
2019-08-30 11:30       ` Ian Kent
2019-08-30 11:27     ` Ian Kent
2019-08-23  1:00 ` [PATCH v2 15/15] xfs: mount-api - remove legacy mount functions Ian Kent
2019-08-26 19:33 ` [PATCH v2 00/15] xfs: mount API patch series Darrick J. Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).