Re: [PATCH v9 13/17] xfs: switch to use the new mount-api

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2019-11-05 at 07:23 -0800, Darrick J. Wong wrote:
> On Tue, Nov 05, 2019 at 11:00:36AM +0800, Ian Kent wrote:
> > On Mon, 2019-11-04 at 14:53 -0800, Darrick J. Wong wrote:
> > > On Mon, Nov 04, 2019 at 06:55:44PM +0800, Ian Kent wrote:
> > > > Define the struct fs_parameter_spec table that's used by the
> > > > new
> > > > mount-api for options parsing.
> > > > 
> > > > Create the various fs context operations methods and define the
> > > > fs_context_operations struct.
> > > > 
> > > > Create the fs context initialization method and update the
> > > > struct
> > > > file_system_type to utilize it. The initialization function is
> > > > responsible for working storage initialization, allocation and
> > > > initialization of file system private information storage and
> > > > for
> > > > setting the operations in the fs context.
> > > > 
> > > > Also set struct file_system_type .parameters to the newly
> > > > defined
> > > > struct fs_parameter_spec options parsing table for use by the
> > > > fs
> > > > context methods and remove unused code.
> > > > 
> > > > Signed-off-by: Ian Kent <raven@xxxxxxxxxx>
> > > > ---
> > > >  fs/xfs/xfs_super.c |  408 ++++++++++++++++++++++------------
> > > > ----
> > > > --------------
> > > >  1 file changed, 171 insertions(+), 237 deletions(-)
> > > > 
> > > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > > > index 62dfc678c415..2d4edaaf934e 100644
> > > > --- a/fs/xfs/xfs_super.c
> > > > +++ b/fs/xfs/xfs_super.c
> > > > @@ -37,7 +37,8 @@
> > > >  #include "xfs_reflink.h"
> > > >  
> > > >  #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;
> > > >  
> > > > @@ -58,55 +59,57 @@ enum {
> > > >  	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,
> > > > +	Opt_discard, Opt_nodiscard, Opt_dax,
> > > >  };
> > > >  
> > > > -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_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},
> > > > +static const struct fs_parameter_spec xfs_param_specs[] = {
> > > > +	fsparam_u32("logbufs",		Opt_logbufs),
> > > > +	fsparam_string("logbsize",	Opt_logbsize),
> > > > +	fsparam_string("logdev",	Opt_logdev),
> > > > +	fsparam_string("rtdev",		Opt_rtdev),
> > > > +	fsparam_flag("wsync",		Opt_wsync),
> > > > +	fsparam_flag("noalign",		Opt_noalign),
> > > > +	fsparam_flag("swalloc",		Opt_swalloc),
> > > > +	fsparam_u32("sunit",		Opt_sunit),
> > > > +	fsparam_u32("swidth",		Opt_swidth),
> > > > +	fsparam_flag("nouuid",		Opt_nouuid),
> > > > +	fsparam_flag("grpid",		Opt_grpid),
> > > > +	fsparam_flag("nogrpid",		Opt_nogrpid),
> > > > +	fsparam_flag("bsdgroups",	Opt_bsdgroups),
> > > > +	fsparam_flag("sysvgroups",	Opt_sysvgroups),
> > > > +	fsparam_string("allocsize",	Opt_allocsize),
> > > > +	fsparam_flag("norecovery",	Opt_norecovery),
> > > > +	fsparam_flag("inode64",		Opt_inode64),
> > > > +	fsparam_flag("inode32",		Opt_inode32),
> > > > +	fsparam_flag("ikeep",		Opt_ikeep),
> > > > +	fsparam_flag("noikeep",		Opt_noikeep),
> > > > +	fsparam_flag("largeio",		Opt_largeio),
> > > > +	fsparam_flag("nolargeio",	Opt_nolargeio),
> > > > +	fsparam_flag("attr2",		Opt_attr2),
> > > > +	fsparam_flag("noattr2",		Opt_noattr2),
> > > > +	fsparam_flag("filestreams",	Opt_filestreams),
> > > > +	fsparam_flag("quota",		Opt_quota),
> > > > +	fsparam_flag("noquota",		Opt_noquota),
> > > > +	fsparam_flag("usrquota",	Opt_usrquota),
> > > > +	fsparam_flag("grpquota",	Opt_grpquota),
> > > > +	fsparam_flag("prjquota",	Opt_prjquota),
> > > > +	fsparam_flag("uquota",		Opt_uquota),
> > > > +	fsparam_flag("gquota",		Opt_gquota),
> > > > +	fsparam_flag("pquota",		Opt_pquota),
> > > > +	fsparam_flag("uqnoenforce",	Opt_uqnoenforce),
> > > > +	fsparam_flag("gqnoenforce",	Opt_gqnoenforce),
> > > > +	fsparam_flag("pqnoenforce",	Opt_pqnoenforce),
> > > > +	fsparam_flag("qnoenforce",	Opt_qnoenforce),
> > > > +	fsparam_flag("discard",		Opt_discard),
> > > > +	fsparam_flag("nodiscard",	Opt_nodiscard),
> > > > +	fsparam_flag("dax",		Opt_dax),
> > > > +	{}
> > > >  };
> > > >  
> > > > +static const struct fs_parameter_description xfs_fs_parameters
> > > > = {
> > > > +	.name		= "xfs",
> > > > +	.specs		= xfs_param_specs,
> > > > +};
> > > >  
> > > >  static int
> > > >  suffix_kstrtoint(
> > > > @@ -143,55 +146,42 @@ suffix_kstrtoint(
> > > >  	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;
> > > > -}
> > > > -
> > > >  static int
> > > >  xfs_fc_parse_param(
> > > 
> > > This is the only function where mp->m_super can be NULL, correct?
> > 
> > Yep.
> > 
> > > If so, I'll add a comment to that effect, and,
> > > Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> > 
> > Thanks, much appreciated.
> > 
> > > (for this and patch 12.)
> > > 
> > > Will throw this at a testing cloud and see what happens...
> > 
> > It's seems ok when I run it against xfstests but I'm not as
> > familiar
> > with what to expect as you would be, I'm interested to hear how it
> > goes, ;)
> 
> Looked like it ran just fine.
> 
> > I noticed a significant change in test run times with the latest
> > for-next but there was also an xfstests update so I'm not sure
> > what caused it. Some test run times went up by 8 to 10 or more
> > times, which seemed like a big change, possibly a regression.
> 
> Hmm, I haven't seen any such regression; it still takes ~3h to run
> all
> the non-dangerous tests.

Ok, it must be my setup then.
Thought I'd mention it just in case there was something wrong.

Ian
> 
> --D
> 
> > Ian
> > 
> > > --D
> > > 
> > > > -	int			token,
> > > > -	char			*p,
> > > > -	substring_t		*args,
> > > > -	struct xfs_mount	*mp)
> > > > +	struct fs_context	*fc,
> > > > +	struct fs_parameter	*param)
> > > >  {
> > > > +	struct xfs_mount	*mp = fc->s_fs_info;
> > > > +	struct fs_parse_result	result;
> > > >  	int			size = 0;
> > > > +	int			opt;
> > > > +
> > > > +	opt = fs_parse(fc, &xfs_fs_parameters, param, &result);
> > > > +	if (opt < 0)
> > > > +		return opt;
> > > >  
> > > > -	switch (token) {
> > > > +	switch (opt) {
> > > >  	case Opt_logbufs:
> > > > -		if (match_int(args, &mp->m_logbufs))
> > > > -			return -EINVAL;
> > > > +		mp->m_logbufs = result.uint_32;
> > > >  		return 0;
> > > >  	case Opt_logbsize:
> > > > -		if (match_kstrtoint(args, 10, &mp->m_logbsize))
> > > > +		if (suffix_kstrtoint(param->string, 10, &mp-
> > > > > m_logbsize))
> > > >  			return -EINVAL;
> > > >  		return 0;
> > > >  	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;
> > > >  		return 0;
> > > >  	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;
> > > >  		return 0;
> > > >  	case Opt_allocsize:
> > > > -		if (match_kstrtoint(args, 10, &size))
> > > > +		if (suffix_kstrtoint(param->string, 10, &size))
> > > >  			return -EINVAL;
> > > >  		mp->m_allocsize_log = ffs(size) - 1;
> > > >  		mp->m_flags |= XFS_MOUNT_ALLOCSIZE;
> > > > @@ -217,12 +207,10 @@ xfs_fc_parse_param(
> > > >  		mp->m_flags |= XFS_MOUNT_SWALLOC;
> > > >  		return 0;
> > > >  	case Opt_sunit:
> > > > -		if (match_int(args, &mp->m_dalign))
> > > > -			return -EINVAL;
> > > > +		mp->m_dalign = result.uint_32;
> > > >  		return 0;
> > > >  	case Opt_swidth:
> > > > -		if (match_int(args, &mp->m_swidth))
> > > > -			return -EINVAL;
> > > > +		mp->m_swidth = result.uint_32;
> > > >  		return 0;
> > > >  	case Opt_inode32:
> > > >  		mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
> > > > @@ -301,7 +289,7 @@ xfs_fc_parse_param(
> > > >  		return 0;
> > > >  #endif
> > > >  	default:
> > > > -		xfs_warn(mp, "unknown mount option [%s].", p);
> > > > +		xfs_warn(mp, "unknown mount option [%s].",
> > > > param->key);
> > > >  		return -EINVAL;
> > > >  	}
> > > >  
> > > > @@ -376,62 +364,6 @@ xfs_fc_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;
> > > > -	substring_t		args[MAX_OPT_ARGS];
> > > > -
> > > > -	/*
> > > > -	 * 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;
> > > > -
> > > > -	/*
> > > > -	 * These can be overridden by the mount option parsing.
> > > > -	 */
> > > > -	mp->m_logbufs = -1;
> > > > -	mp->m_logbsize = -1;
> > > > -	mp->m_allocsize_log = 16; /* 64k */
> > > > -
> > > > -	if (!options)
> > > > -		return 0;
> > > > -
> > > > -	while ((p = strsep(&options, ",")) != NULL) {
> > > > -		int		token;
> > > > -		int		ret;
> > > > -
> > > > -		if (!*p)
> > > > -			continue;
> > > > -
> > > > -		token = match_token(p, tokens, args);
> > > > -		ret = xfs_fc_parse_param(token, p, args, mp);
> > > > -		if (ret)
> > > > -			return ret;
> > > > -	}
> > > > -
> > > > -	return xfs_fc_validate_params(mp);
> > > > -}
> > > > -
> > > >  struct proc_xfs_info {
> > > >  	uint64_t	flag;
> > > >  	char		*str;
> > > > @@ -1207,25 +1139,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_mount_free(tmp_mp);
> > > > -
> > > > -	return error;
> > > > -}
> > > > -
> > > >  static int
> > > >  xfs_remount_rw(
> > > >  	struct xfs_mount	*mp)
> > > > @@ -1329,76 +1242,57 @@ xfs_remount_ro(
> > > >  	return 0;
> > > >  }
> > > >  
> > > > -STATIC int
> > > > -xfs_fs_remount(
> > > > -	struct super_block	*sb,
> > > > -	int			*flags,
> > > > -	char			*options)
> > > > +/*
> > > > + * 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.
> > > > + */
> > > > +static int
> > > > +xfs_fc_reconfigure(
> > > > +	struct fs_context	*fc)
> > > >  {
> > > > -	struct xfs_mount	*mp = XFS_M(sb);
> > > > +	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;
> > > > -	substring_t		args[MAX_OPT_ARGS];
> > > > -	char			*p;
> > > > +	int			flags = fc->sb_flags;
> > > >  	int			error;
> > > >  
> > > > -	/* First, check for complete junk; i.e. invalid options
> > > > */
> > > > -	error = xfs_test_remount_options(sb, options);
> > > > +	error = xfs_fc_validate_params(new_mp);
> > > >  	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
> > > > -		}
> > > > +	sync_filesystem(mp->m_super);
> > > > +
> > > > +	/* 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))
> > > > {
> > > > +	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))
> > > > {
> > > > +	if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (flags &
> > > > SB_RDONLY)) {
> > > >  		error = xfs_remount_ro(mp);
> > > >  		if (error)
> > > >  			return error;
> > > > @@ -1588,28 +1482,18 @@ xfs_mount_alloc(void)
> > > >  	return mp;
> > > >  }
> > > >  
> > > > -
> > > > -STATIC int
> > > > -xfs_fs_fill_super(
> > > > +static int
> > > > +xfs_fc_fill_super(
> > > >  	struct super_block	*sb,
> > > > -	void			*data,
> > > > -	int			silent)
> > > > +	struct fs_context	*fc)
> > > >  {
> > > > +	struct xfs_mount	*mp = sb->s_fs_info;
> > > >  	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();
> > > > -	if (!mp)
> > > > -		goto out;
> > > >  	mp->m_super = sb;
> > > > -	sb->s_fs_info = mp;
> > > >  
> > > > -	error = xfs_parseargs(mp, (char *)data);
> > > > +	error = xfs_fc_validate_params(mp);
> > > >  	if (error)
> > > >  		goto out_free_names;
> > > >  
> > > > @@ -1633,7 +1517,7 @@ xfs_fs_fill_super(
> > > >  		msleep(xfs_globals.mount_delay * 1000);
> > > >  	}
> > > >  
> > > > -	if (silent)
> > > > +	if (fc->sb_flags & SB_SILENT)
> > > >  		flags |= XFS_MFSI_QUIET;
> > > >  
> > > >  	error = xfs_open_devices(mp);
> > > > @@ -1778,7 +1662,6 @@ xfs_fs_fill_super(
> > > >   out_free_names:
> > > >  	sb->s_fs_info = NULL;
> > > >  	xfs_mount_free(mp);
> > > > - out:
> > > >  	return error;
> > > >  
> > > >   out_unmount:
> > > > @@ -1787,6 +1670,13 @@ xfs_fs_fill_super(
> > > >  	goto out_free_sb;
> > > >  }
> > > >  
> > > > +static int
> > > > +xfs_fc_get_tree(
> > > > +	struct fs_context	*fc)
> > > > +{
> > > > +	return get_tree_bdev(fc, xfs_fc_fill_super);
> > > > +}
> > > > +
> > > >  STATIC void
> > > >  xfs_fs_put_super(
> > > >  	struct super_block	*sb)
> > > > @@ -1811,16 +1701,6 @@ xfs_fs_put_super(
> > > >  	xfs_mount_free(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,
> > > > @@ -1850,16 +1730,70 @@ 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,
> > > >  };
> > > >  
> > > > +static void xfs_fc_free(
> > > > +	struct fs_context	*fc)
> > > > +{
> > > > +	struct xfs_mount	*mp = fc->s_fs_info;
> > > > +
> > > > +	/*
> > > > +	 * mp is stored in the fs_context when it is
> > > > initialized.
> > > > +	 * mp is transferred to the superblock on a successful
> > > > mount,
> > > > +	 * but if an error occurs before the transfer we have
> > > > to free
> > > > +	 * it here.
> > > > +	 */
> > > > +	if (mp)
> > > > +		xfs_mount_free(mp);
> > > > +}
> > > > +
> > > > +static const struct fs_context_operations xfs_context_ops = {
> > > > +	.parse_param = xfs_fc_parse_param,
> > > > +	.get_tree    = xfs_fc_get_tree,
> > > > +	.reconfigure = xfs_fc_reconfigure,
> > > > +	.free        = xfs_fc_free,
> > > > +};
> > > > +
> > > > +static int xfs_init_fs_context(
> > > > +	struct fs_context	*fc)
> > > > +{
> > > > +	struct xfs_mount	*mp;
> > > > +
> > > > +	mp = xfs_mount_alloc();
> > > > +	if (!mp)
> > > > +		return -ENOMEM;
> > > > +
> > > > +	/*
> > > > +	 * These can be overridden by the mount option parsing.
> > > > +	 */
> > > > +	mp->m_logbufs = -1;
> > > > +	mp->m_logbsize = -1;
> > > > +	mp->m_allocsize_log = 16; /* 64k */
> > > > +
> > > > +	/*
> > > > +	 * 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->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,
> > > >  };
> > > > 




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux