Re: [f2fs-dev] [PATCH 1/5 v2] f2fs: add mount option for segment allocation policy

From: Jaegeuk Kim
Date: Wed Feb 28 2018 - 21:54:02 EST


On 02/28, Chao Yu wrote:
> On 2018/2/28 13:09, Jaegeuk Kim wrote:
> > Change log from v1:
> > - add doc :)
> >
> > This patch adds an mount option, "alloc_mode=%s" having two options, "default"
> > and "reuse".
> >
> > In "alloc_mode=reuse" case, f2fs starts to allocate segments from 0'th segment
> > all the time to reassign segments. It'd be useful for small-sized eMMC parts.
>
> We have to restore old alloc_mode if we encounter any failure in ->remount, right?

Yup, done.

>
> Thanks,
>
> >
> > Signed-off-by: Jaegeuk Kim <jaegeuk@xxxxxxxxxx>
> > ---
> > Documentation/filesystems/f2fs.txt | 2 ++
> > fs/f2fs/f2fs.h | 8 ++++++++
> > fs/f2fs/segment.c | 5 +++++
> > fs/f2fs/super.c | 24 ++++++++++++++++++++++++
> > 4 files changed, 39 insertions(+)
> >
> > diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
> > index 0caf7da0a532..0409c47584ea 100644
> > --- a/Documentation/filesystems/f2fs.txt
> > +++ b/Documentation/filesystems/f2fs.txt
> > @@ -180,6 +180,8 @@ whint_mode=%s Control which write hints are passed down to block
> > down hints. In "user-based" mode, f2fs tries to pass
> > down hints given by users. And in "fs-based" mode, f2fs
> > passes down hints with its policy.
> > +alloc_mode=%s Adjust block allocation policy, which supports "reuse"
> > + and "default".
> >
> > ================================================================================
> > DEBUGFS ENTRIES
> > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> > index f68ece08b5a2..d1bfdf691afc 100644
> > --- a/fs/f2fs/f2fs.h
> > +++ b/fs/f2fs/f2fs.h
> > @@ -1043,6 +1043,11 @@ enum {
> > WHINT_MODE_FS, /* pass down hints with F2FS policy */
> > };
> >
> > +enum {
> > + ALLOC_MODE_DEFAULT, /* stay default */
> > + ALLOC_MODE_REUSE, /* reuse segments as much as possible */
> > +};
> > +
> > struct f2fs_sb_info {
> > struct super_block *sb; /* pointer to VFS super block */
> > struct proc_dir_entry *s_proc; /* proc entry */
> > @@ -1229,6 +1234,9 @@ struct f2fs_sb_info {
> > #endif
> > /* For which write hints are passed down to block layer */
> > int whint_mode;
> > +
> > + /* segment allocation policy */
> > + int alloc_mode;
> > };
> >
> > #ifdef CONFIG_F2FS_FAULT_INJECTION
> > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> > index 0646d5de8cd0..5e5e2936a26a 100644
> > --- a/fs/f2fs/segment.c
> > +++ b/fs/f2fs/segment.c
> > @@ -2170,6 +2170,11 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
> >
> > if (SIT_I(sbi)->last_victim[ALLOC_NEXT])
> > return SIT_I(sbi)->last_victim[ALLOC_NEXT];
> > +
> > + /* find segments from 0 to reuse freed segments */
> > + if (sbi->alloc_mode == ALLOC_MODE_REUSE)
> > + return 0;
> > +
> > return CURSEG_I(sbi, type)->segno;
> > }
> >
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index 2d832866720c..1345ef167140 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -130,6 +130,7 @@ enum {
> > Opt_jqfmt_vfsv0,
> > Opt_jqfmt_vfsv1,
> > Opt_whint,
> > + Opt_alloc,
> > Opt_err,
> > };
> >
> > @@ -184,6 +185,7 @@ static match_table_t f2fs_tokens = {
> > {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
> > {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
> > {Opt_whint, "whint_mode=%s"},
> > + {Opt_alloc, "alloc_mode=%s"},
> > {Opt_err, NULL},
> > };
> >
> > @@ -700,6 +702,23 @@ static int parse_options(struct super_block *sb, char *options)
> > }
> > kfree(name);
> > break;
> > + case Opt_alloc:
> > + name = match_strdup(&args[0]);
> > + if (!name)
> > + return -ENOMEM;
> > +
> > + if (strlen(name) == 7 &&
> > + !strncmp(name, "default", 7)) {
> > + sbi->alloc_mode = ALLOC_MODE_DEFAULT;
> > + } else if (strlen(name) == 5 &&
> > + !strncmp(name, "reuse", 5)) {
> > + sbi->alloc_mode = ALLOC_MODE_REUSE;
> > + } else {
> > + kfree(name);
> > + return -EINVAL;
> > + }
> > + kfree(name);
> > + break;
> > default:
> > f2fs_msg(sb, KERN_ERR,
> > "Unrecognized mount option \"%s\" or missing value",
> > @@ -1264,6 +1283,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
> > else if (sbi->whint_mode == WHINT_MODE_FS)
> > seq_printf(seq, ",whint_mode=%s", "fs-based");
> >
> > + if (sbi->alloc_mode == ALLOC_MODE_DEFAULT)
> > + seq_printf(seq, ",alloc_mode=%s", "default");
> > + else if (sbi->alloc_mode == ALLOC_MODE_REUSE)
> > + seq_printf(seq, ",alloc_mode=%s", "reuse");
> > return 0;
> > }
> >
> > @@ -1273,6 +1296,7 @@ static void default_options(struct f2fs_sb_info *sbi)
> > sbi->active_logs = NR_CURSEG_TYPE;
> > sbi->inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
> > sbi->whint_mode = WHINT_MODE_OFF;
> > + sbi->alloc_mode = ALLOC_MODE_DEFAULT;
> >
> > set_opt(sbi, BG_GC);
> > set_opt(sbi, INLINE_XATTR);
> >