Re: [PATCH 1/2] f2fs: add remount_fs callback support

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

 



On 06/16/2013 08:48 AM, Namjae Jeon wrote:

> From: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>
> 
> Add the f2fs_remount function call which will be used
> during the filesystem remounting. This function
> will help us to change the mount options specific to
> f2fs.
> 
> Also modify the f2fs background_gc mount option, which
> will allow the user to dynamically trun on/off the
> garbage collection in f2fs based on the background_gc
> value. If background_gc=on, Garbage collection will
> be turned off & if background_gc=off, Garbage collection
> will be truned on.
> 
> By default the garbage collection is on in f2fs.
> 
> Change Log:
> v2: Incorporated the review comments by Gu Zheng.
>     Removing the restore part for VFS flags
>     Updating comments with proper flag conditions
>     Display GC background option as ON/OFF
>     Revised conditions to stop GC in case of remount
> 
> v1: Initial changes for adding remount_fs callback
> support.
> 
> Cc: Gu Zheng <guz.fnst@xxxxxxxxxxxxxx>
> Signed-off-by: Namjae Jeon <namjae.jeon@xxxxxxxxxxx>
> Signed-off-by: Pankaj Kumar <pankaj.km@xxxxxxxxxxx>


Reviewed-by: Gu Zheng <guz.fnst@xxxxxxxxxxxxxx>

Thanks,
Gu

> ---
>  Documentation/filesystems/f2fs.txt |    9 +-
>  fs/f2fs/super.c                    |  235 +++++++++++++++++++++++-------------
>  2 files changed, 160 insertions(+), 84 deletions(-)
> 
> diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
> index bd3c56c..b91e2f2 100644
> --- a/Documentation/filesystems/f2fs.txt
> +++ b/Documentation/filesystems/f2fs.txt
> @@ -98,8 +98,13 @@ Cleaning Overhead
>  MOUNT OPTIONS
>  ================================================================================
>  
> -background_gc_off      Turn off cleaning operations, namely garbage collection,
> -		       triggered in background when I/O subsystem is idle.
> +background_gc=%s       Turn on/off cleaning operations, namely garbage
> +                       collection, triggered in background when I/O subsystem is
> +                       idle. If background_gc=on, it will turn on the garbage
> +                       collection and if background_gc=off, garbage collection
> +                       will be truned off.
> +                       Default value for this option is on. So garbage
> +                       collection is on by default.
>  disable_roll_forward   Disable the roll-forward recovery routine
>  discard                Issue discard/TRIM commands when a segment is cleaned.
>  no_heap                Disable heap-style segment allocation which finds free
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index ba56549..5a11484 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -34,7 +34,7 @@
>  static struct kmem_cache *f2fs_inode_cachep;
>  
>  enum {
> -	Opt_gc_background_off,
> +	Opt_gc_background,
>  	Opt_disable_roll_forward,
>  	Opt_discard,
>  	Opt_noheap,
> @@ -46,7 +46,7 @@ enum {
>  };
>  
>  static match_table_t f2fs_tokens = {
> -	{Opt_gc_background_off, "background_gc_off"},
> +	{Opt_gc_background, "background_gc=%s"},
>  	{Opt_disable_roll_forward, "disable_roll_forward"},
>  	{Opt_discard, "discard"},
>  	{Opt_noheap, "no_heap"},
> @@ -76,6 +76,91 @@ static void init_once(void *foo)
>  	inode_init_once(&fi->vfs_inode);
>  }
>  
> +static int parse_options(struct super_block *sb, char *options)
> +{
> +	struct f2fs_sb_info *sbi = F2FS_SB(sb);
> +	substring_t args[MAX_OPT_ARGS];
> +	char *p, *name;
> +	int arg = 0;
> +
> +	if (!options)
> +		return 0;
> +
> +	while ((p = strsep(&options, ",")) != NULL) {
> +		int token;
> +		if (!*p)
> +			continue;
> +		/*
> +		 * Initialize args struct so we know whether arg was
> +		 * found; some options take optional arguments.
> +		 */
> +		args[0].to = args[0].from = NULL;
> +		token = match_token(p, f2fs_tokens, args);
> +
> +		switch (token) {
> +		case Opt_gc_background:
> +			name = match_strdup(&args[0]);
> +
> +			if (!name)
> +				return -ENOMEM;
> +			if (!strncmp(name, "on", 2))
> +				set_opt(sbi, BG_GC);
> +			else if (!strncmp(name, "off", 3))
> +				clear_opt(sbi, BG_GC);
> +			else {
> +				kfree(name);
> +				return -EINVAL;
> +			}
> +			kfree(name);
> +			break;
> +		case Opt_disable_roll_forward:
> +			set_opt(sbi, DISABLE_ROLL_FORWARD);
> +			break;
> +		case Opt_discard:
> +			set_opt(sbi, DISCARD);
> +			break;
> +		case Opt_noheap:
> +			set_opt(sbi, NOHEAP);
> +			break;
> +#ifdef CONFIG_F2FS_FS_XATTR
> +		case Opt_nouser_xattr:
> +			clear_opt(sbi, XATTR_USER);
> +			break;
> +#else
> +		case Opt_nouser_xattr:
> +			f2fs_msg(sb, KERN_INFO,
> +				"nouser_xattr options not supported");
> +			break;
> +#endif
> +#ifdef CONFIG_F2FS_FS_POSIX_ACL
> +		case Opt_noacl:
> +			clear_opt(sbi, POSIX_ACL);
> +			break;
> +#else
> +		case Opt_noacl:
> +			f2fs_msg(sb, KERN_INFO, "noacl options not supported");
> +			break;
> +#endif
> +		case Opt_active_logs:
> +			if (args->from && match_int(args, &arg))
> +				return -EINVAL;
> +			if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE)
> +				return -EINVAL;
> +			sbi->active_logs = arg;
> +			break;
> +		case Opt_disable_ext_identify:
> +			set_opt(sbi, DISABLE_EXT_IDENTIFY);
> +			break;
> +		default:
> +			f2fs_msg(sb, KERN_ERR,
> +				"Unrecognized mount option \"%s\" or missing value",
> +				p);
> +			return -EINVAL;
> +		}
> +	}
> +	return 0;
> +}
> +
>  static struct inode *f2fs_alloc_inode(struct super_block *sb)
>  {
>  	struct f2fs_inode_info *fi;
> @@ -225,10 +310,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
>  {
>  	struct f2fs_sb_info *sbi = F2FS_SB(root->d_sb);
>  
> -	if (test_opt(sbi, BG_GC))
> -		seq_puts(seq, ",background_gc_on");
> +	if (!(root->d_sb->s_flags & MS_RDONLY) && test_opt(sbi, BG_GC))
> +		seq_printf(seq, ",background_gc=%s", "on");
>  	else
> -		seq_puts(seq, ",background_gc_off");
> +		seq_printf(seq, ",background_gc=%s", "off");
>  	if (test_opt(sbi, DISABLE_ROLL_FORWARD))
>  		seq_puts(seq, ",disable_roll_forward");
>  	if (test_opt(sbi, DISCARD))
> @@ -255,6 +340,58 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
>  	return 0;
>  }
>  
> +static int f2fs_remount(struct super_block *sb, int *flags, char *data)
> +{
> +	struct f2fs_sb_info *sbi = F2FS_SB(sb);
> +	struct f2fs_mount_info org_mount_opt;
> +	int err, active_logs;
> +
> +	/**
> +	 * Save the old mount options in case we
> +	 * need to restore them.
> +	 */
> +	org_mount_opt = sbi->mount_opt;
> +	active_logs = sbi->active_logs;
> +
> +	/* parse mount options */
> +	err = parse_options(sb, data);
> +	if (err)
> +		goto restore_opts;
> +
> +	/**
> +	 * Previous and new state of filesystem is RO,
> +	 * so no point in checking GC conditions.
> +	 */
> +	if ((sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
> +		goto skip;
> +
> +	/**
> +	 * We stop the GC thread if FS is mounted as RO
> +	 * or if background_gc = off is passed in mount
> +	 * option. Also sync the filesystem.
> +	 */
> +	if ((*flags & MS_RDONLY) || !test_opt(sbi, BG_GC)) {
> +		if (sbi->gc_thread) {
> +			stop_gc_thread(sbi);
> +			f2fs_sync_fs(sb, 1);
> +		}
> +	} else if (test_opt(sbi, BG_GC) && !sbi->gc_thread) {
> +		err = start_gc_thread(sbi);
> +		if (err)
> +			goto restore_opts;
> +	}
> +skip:
> +	/* Update the POSIXACL Flag */
> +	 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
> +		(test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0);
> +	return 0;
> +
> +restore_opts:
> +	sbi->mount_opt = org_mount_opt;
> +	sbi->active_logs = active_logs;
> +	return err;
> +}
> +
>  static struct super_operations f2fs_sops = {
>  	.alloc_inode	= f2fs_alloc_inode,
>  	.drop_inode	= f2fs_drop_inode,
> @@ -268,6 +405,7 @@ static struct super_operations f2fs_sops = {
>  	.freeze_fs	= f2fs_freeze,
>  	.unfreeze_fs	= f2fs_unfreeze,
>  	.statfs		= f2fs_statfs,
> +	.remount_fs	= f2fs_remount,
>  };
>  
>  static struct inode *f2fs_nfs_get_inode(struct super_block *sb,
> @@ -315,79 +453,6 @@ static const struct export_operations f2fs_export_ops = {
>  	.get_parent = f2fs_get_parent,
>  };
>  
> -static int parse_options(struct super_block *sb, char *options)
> -{
> -	struct f2fs_sb_info *sbi = F2FS_SB(sb);
> -	substring_t args[MAX_OPT_ARGS];
> -	char *p;
> -	int arg = 0;
> -
> -	if (!options)
> -		return 0;
> -
> -	while ((p = strsep(&options, ",")) != NULL) {
> -		int token;
> -		if (!*p)
> -			continue;
> -		/*
> -		 * Initialize args struct so we know whether arg was
> -		 * found; some options take optional arguments.
> -		 */
> -		args[0].to = args[0].from = NULL;
> -		token = match_token(p, f2fs_tokens, args);
> -
> -		switch (token) {
> -		case Opt_gc_background_off:
> -			clear_opt(sbi, BG_GC);
> -			break;
> -		case Opt_disable_roll_forward:
> -			set_opt(sbi, DISABLE_ROLL_FORWARD);
> -			break;
> -		case Opt_discard:
> -			set_opt(sbi, DISCARD);
> -			break;
> -		case Opt_noheap:
> -			set_opt(sbi, NOHEAP);
> -			break;
> -#ifdef CONFIG_F2FS_FS_XATTR
> -		case Opt_nouser_xattr:
> -			clear_opt(sbi, XATTR_USER);
> -			break;
> -#else
> -		case Opt_nouser_xattr:
> -			f2fs_msg(sb, KERN_INFO,
> -				"nouser_xattr options not supported");
> -			break;
> -#endif
> -#ifdef CONFIG_F2FS_FS_POSIX_ACL
> -		case Opt_noacl:
> -			clear_opt(sbi, POSIX_ACL);
> -			break;
> -#else
> -		case Opt_noacl:
> -			f2fs_msg(sb, KERN_INFO, "noacl options not supported");
> -			break;
> -#endif
> -		case Opt_active_logs:
> -			if (args->from && match_int(args, &arg))
> -				return -EINVAL;
> -			if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE)
> -				return -EINVAL;
> -			sbi->active_logs = arg;
> -			break;
> -		case Opt_disable_ext_identify:
> -			set_opt(sbi, DISABLE_EXT_IDENTIFY);
> -			break;
> -		default:
> -			f2fs_msg(sb, KERN_ERR,
> -				"Unrecognized mount option \"%s\" or missing value",
> -				p);
> -			return -EINVAL;
> -		}
> -	}
> -	return 0;
> -}
> -
>  static loff_t max_file_size(unsigned bits)
>  {
>  	loff_t result = ADDRS_PER_INODE;
> @@ -686,10 +751,16 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>  				"Cannot recover all fsync data errno=%ld", err);
>  	}
>  
> -	/* After POR, we can run background GC thread */
> -	err = start_gc_thread(sbi);
> -	if (err)
> -		goto fail;
> +	/**
> +	 * If filesystem is not mounted as read-only then
> +	 * do start the gc_thread.
> +	 */
> +	if (!(sb->s_flags & MS_RDONLY)) {
> +		/* After POR, we can run background GC thread.*/
> +		err = start_gc_thread(sbi);
> +		if (err)
> +			goto fail;
> +	}
>  
>  	err = f2fs_build_stats(sbi);
>  	if (err)


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux