* [PATCH 1/2] mkfs.f2fs: add option to set the value of reserved segments and overprovision segments
2017-02-17 12:53 [PATCH 0/2] Reduce the overprovision size a lot in f2fs Yunlong Song
@ 2017-02-17 12:53 ` Yunlong Song
2017-02-17 12:53 ` [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE Yunlong Song
2017-02-17 19:33 ` [PATCH 0/2] Reduce the overprovision size a lot in f2fs Jaegeuk Kim
2 siblings, 0 replies; 7+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song, miaoxie,
zhouxiyu
Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel
Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
include/f2fs_fs.h | 3 +++
lib/libf2fs.c | 3 +++
mkfs/f2fs_format.c | 21 ++++++++++++++-------
mkfs/f2fs_format_main.c | 10 +++++++++-
4 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 97ee297..2a62660 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -304,6 +304,9 @@ struct f2fs_configuration {
/* sload parameters */
char *from_dir;
char *mount_point;
+
+ u_int32_t force_rsvd;
+ u_int32_t force_ovp;
} __attribute__((packed));
#ifdef CONFIG_64BIT
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 93d3da9..971fe99 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -573,6 +573,9 @@ void f2fs_init_configuration(void)
c.trim = 1;
c.ro = 0;
c.kd = -1;
+
+ c.force_rsvd = 0;
+ c.force_ovp = 0;
}
static int is_mounted(const char *mpt, const char *device)
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 3c13026..42a7bd5 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -337,9 +337,12 @@ static int f2fs_prepare_super_block(void)
if (c.overprovision == 0)
c.overprovision = get_best_overprovision(sb);
- c.reserved_segments =
- (2 * (100 / c.overprovision + 1) + 6)
- * c.segs_per_sec;
+ if (c.force_rsvd)
+ c.reserved_segments = c.force_rsvd;
+ else
+ c.reserved_segments =
+ (2 * (100 / c.overprovision + 1) + 6)
+ * c.segs_per_sec;
if (c.overprovision == 0 || c.total_segments < F2FS_MIN_SEGMENTS ||
(c.devices[0].total_sectors *
@@ -522,13 +525,17 @@ static int f2fs_write_check_point_pack(void)
set_cp(cur_data_blkoff[0], 1);
set_cp(valid_block_count, 2);
set_cp(rsvd_segment_count, c.reserved_segments);
- set_cp(overprov_segment_count, (get_sb(segment_count_main) -
- get_cp(rsvd_segment_count)) *
- c.overprovision / 100);
+ if (c.force_ovp)
+ set_cp(overprov_segment_count, c.force_ovp);
+ else
+ set_cp(overprov_segment_count, (get_sb(segment_count_main) -
+ get_cp(rsvd_segment_count)) *
+ c.overprovision / 100);
set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
get_cp(rsvd_segment_count));
- MSG(0, "Info: Overprovision ratio = %.3lf%%\n", c.overprovision);
+ if (c.force_rsvd == 0 || c.force_ovp == 0)
+ MSG(0, "Info: Overprovision ratio = %.3lf%%\n", c.overprovision);
MSG(0, "Info: Overprovision segments = %u (GC reserved = %u)\n",
get_cp(overprov_segment_count),
c.reserved_segments);
diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
index 5bb1faf..45c513b 100644
--- a/mkfs/f2fs_format_main.c
+++ b/mkfs/f2fs_format_main.c
@@ -39,6 +39,8 @@ static void mkfs_usage()
MSG(0, " -z # of sections per zone [default:1]\n");
MSG(0, " -t 0: nodiscard, 1: discard [default:1]\n");
MSG(0, " -m support zoned block device [default:0]\n");
+ MSG(0, " -r force set reserved segments\n");
+ MSG(0, " -R force set overprovision segments\n");
MSG(0, "sectors: number of sectors. [default: determined by device size]\n");
exit(1);
}
@@ -72,7 +74,7 @@ static void parse_feature(const char *features)
static void f2fs_parse_options(int argc, char *argv[])
{
- static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:";
+ static const char *option_string = "qa:c:d:e:l:mo:O:s:z:t:r:R:";
int32_t option=0;
while ((option = getopt(argc,argv,option_string)) != EOF) {
@@ -128,6 +130,12 @@ static void f2fs_parse_options(int argc, char *argv[])
case 't':
c.trim = atoi(optarg);
break;
+ case 'r':
+ c.force_rsvd = atoi(optarg);
+ break;
+ case 'R':
+ c.force_ovp = atoi(optarg);
+ break;
default:
MSG(0, "\tError: Unknown option %c\n",option);
mkfs_usage();
--
1.8.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
2017-02-17 12:53 [PATCH 0/2] Reduce the overprovision size a lot in f2fs Yunlong Song
2017-02-17 12:53 ` [PATCH 1/2] mkfs.f2fs: add option to set the value of reserved segments and overprovision segments Yunlong Song
@ 2017-02-17 12:53 ` Yunlong Song
2017-02-17 18:39 ` Jaegeuk Kim
2017-02-17 19:33 ` [PATCH 0/2] Reduce the overprovision size a lot in f2fs Jaegeuk Kim
2 siblings, 1 reply; 7+ messages in thread
From: Yunlong Song @ 2017-02-17 12:53 UTC (permalink / raw)
To: jaegeuk, cm224.lee, yuchao0, chao, sylinux, yunlong.song, miaoxie,
zhouxiyu
Cc: bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel
If the free segments are used up, then new_curseg will fail for
CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
new_curseg.
Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
---
fs/f2fs/segment.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index df2ff5c..32820cd 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
if (force)
new_curseg(sbi, type, true);
- else if (type == CURSEG_WARM_NODE)
- new_curseg(sbi, type, false);
else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
new_curseg(sbi, type, false);
else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
--
1.8.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
2017-02-17 12:53 ` [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE Yunlong Song
@ 2017-02-17 18:39 ` Jaegeuk Kim
2017-02-23 12:06 ` Chao Yu
0 siblings, 1 reply; 7+ messages in thread
From: Jaegeuk Kim @ 2017-02-17 18:39 UTC (permalink / raw)
To: Yunlong Song
Cc: cm224.lee, yuchao0, chao, sylinux, miaoxie, zhouxiyu,
bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel
Hi Yunlong,
I already started to test this since a couple of days ago. :)
http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd
Thanks,
On 02/17, Yunlong Song wrote:
> If the free segments are used up, then new_curseg will fail for
> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
> new_curseg.
>
> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
> ---
> fs/f2fs/segment.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index df2ff5c..32820cd 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
>
> if (force)
> new_curseg(sbi, type, true);
> - else if (type == CURSEG_WARM_NODE)
> - new_curseg(sbi, type, false);
> else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
> new_curseg(sbi, type, false);
> else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
> --
> 1.8.5.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
2017-02-17 18:39 ` Jaegeuk Kim
@ 2017-02-23 12:06 ` Chao Yu
2017-02-23 19:27 ` Jaegeuk Kim
0 siblings, 1 reply; 7+ messages in thread
From: Chao Yu @ 2017-02-23 12:06 UTC (permalink / raw)
To: Jaegeuk Kim, Yunlong Song
Cc: cm224.lee, chao, sylinux, miaoxie, zhouxiyu, bintian.wang,
linux-fsdevel, linux-f2fs-devel, linux-kernel
On 2017/2/18 2:39, Jaegeuk Kim wrote:
> Hi Yunlong,
>
> I already started to test this since a couple of days ago. :)
>
> http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd
Hi, Jaegeuk,
Could you send this patch into mailing list? Anyway I will comment in this patch
first. :)
>
> Thanks,
>
> On 02/17, Yunlong Song wrote:
>> If the free segments are used up, then new_curseg will fail for
>> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
>> new_curseg.
>>
>> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
>> ---
>> fs/f2fs/segment.c | 2 --
>> 1 file changed, 2 deletions(-)
>>
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index df2ff5c..32820cd 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
>>
>> if (force)
>> new_curseg(sbi, type, true);
>> - else if (type == CURSEG_WARM_NODE)
Would it be better to check CP_CRC_RECOVERY_FLAG for compatibility of old image?
else if (!is_set_ckpt_flags(CP_CRC_RECOVERY_FLAG) && type == CURSEG_WARM_NODE)
new_curseg(sbi, type, false);
Thanks,
>> - new_curseg(sbi, type, false);
>> else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
>> new_curseg(sbi, type, false);
>> else if (need_SSR(sbi) && get_ssr_segment(sbi, type))
>> --
>> 1.8.5.2
>
> .
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE
2017-02-23 12:06 ` Chao Yu
@ 2017-02-23 19:27 ` Jaegeuk Kim
0 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2017-02-23 19:27 UTC (permalink / raw)
To: Chao Yu
Cc: Yunlong Song, cm224.lee, chao, sylinux, miaoxie, zhouxiyu,
bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel
On 02/23, Chao Yu wrote:
> On 2017/2/18 2:39, Jaegeuk Kim wrote:
> > Hi Yunlong,
> >
> > I already started to test this since a couple of days ago. :)
> >
> > http://git.kernel.org/cgit/linux/kernel/git/jaegeuk/f2fs.git/commit/?h=dev-test&id=908b5f463c82eaf972b149a26bb310f5e25064fd
>
> Hi, Jaegeuk,
>
> Could you send this patch into mailing list? Anyway I will comment in this patch
> first. :)
>
> >
> > Thanks,
> >
> > On 02/17, Yunlong Song wrote:
> >> If the free segments are used up, then new_curseg will fail for
> >> CURSEG_WARM_NODE, in this case, we should use change_curseg instead of
> >> new_curseg.
> >>
> >> Signed-off-by: Yunlong Song <yunlong.song@huawei.com>
> >> ---
> >> fs/f2fs/segment.c | 2 --
> >> 1 file changed, 2 deletions(-)
> >>
> >> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >> index df2ff5c..32820cd 100644
> >> --- a/fs/f2fs/segment.c
> >> +++ b/fs/f2fs/segment.c
> >> @@ -1564,8 +1564,6 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
> >>
> >> if (force)
> >> new_curseg(sbi, type, true);
> >> - else if (type == CURSEG_WARM_NODE)
>
> Would it be better to check CP_CRC_RECOVERY_FLAG for compatibility of old image?
>
> else if (!is_set_ckpt_flags(CP_CRC_RECOVERY_FLAG) && type == CURSEG_WARM_NODE)
> new_curseg(sbi, type, false);
Agreed, when considering any potential risk. ;)
>From 5b6c6be2d878bd7ec4dc2cb4e2a2da2779fe52ab Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim <jaegeuk@kernel.org>
Date: Tue, 14 Feb 2017 19:32:51 -0800
Subject: [PATCH] f2fs: use SSR for warm node as well
We have had node chains, but haven't used it so far due to stale node blocks.
Now, we have crc|cp_ver in node footer and give random cp_ver at format time,
we can start to use it again.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/segment.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b2e0769a09d0..0b42b0cdd674 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1563,7 +1563,8 @@ static void allocate_segment_by_default(struct f2fs_sb_info *sbi,
if (force)
new_curseg(sbi, type, true);
- else if (type == CURSEG_WARM_NODE)
+ else if (!is_set_ckpt_flags(sbi, CP_CRC_RECOVERY_FLAG) &&
+ type == CURSEG_WARM_NODE)
new_curseg(sbi, type, false);
else if (curseg->alloc_type == LFS && is_next_segment_free(sbi, type))
new_curseg(sbi, type, false);
--
2.11.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] Reduce the overprovision size a lot in f2fs
2017-02-17 12:53 [PATCH 0/2] Reduce the overprovision size a lot in f2fs Yunlong Song
2017-02-17 12:53 ` [PATCH 1/2] mkfs.f2fs: add option to set the value of reserved segments and overprovision segments Yunlong Song
2017-02-17 12:53 ` [PATCH 2/2] f2fs: fix the case when there is no free segment to allocate for CURSEG_WARM_NODE Yunlong Song
@ 2017-02-17 19:33 ` Jaegeuk Kim
2 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2017-02-17 19:33 UTC (permalink / raw)
To: Yunlong Song
Cc: cm224.lee, yuchao0, chao, sylinux, miaoxie, zhouxiyu,
bintian.wang, linux-fsdevel, linux-f2fs-devel, linux-kernel
Hi Yunlong,
On 02/17, Yunlong Song wrote:
> Rethink the meaning of reserved segments and overprovision segments in f2fs
>
> The key issue is that flash FTL has already made overprovision itself, e.g. 7%,
> according to the difference between gigabyte (GB) and gibibyte (GiB). And this
> part can nenver be seen by the upper file system. The device capacity which it
> tells the upper file system is the other part which does not include the
> overprovision part, which means the whole device capacity that file system knows
> can "all" be used for write safely. The overprovision flash FTL has already reserved
> includes the needed capacity for garbage collection and other operations. So,
> filesystem can just take it easy and do not need to set the reserved segments and
> overprovision segments again in mkfs.f2fs.
>
> I want to explain more in detail. First, let's forget the section alignment
> issue in the following talk, since it is really not possible in real production
> case. As a result, f2fs does not need to behave like flash (i.e., new write
> must come after erase for a block page in flash).
Simply say no, F2FS has nothing to do with FTL, and LFS acts like flash.
> Take a look at the current design of mkfs.f2fs:
>
> c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;
>
> The original motivation may be like this:
>
> For example, if ovp is 20%, we select 5 victim segments to reclaim one free
> segment in the worst case. During this migration, we need additional 4 free
> segments to write valid blocks in the victim segments. Other remaining added
> segments are just to keep as a buffer to prepare any abnormal situation.
>
> But f2fs does not have to bahave like flash, so why do we need 4 more free segments
> here? For current codes of f2fs gc, we only need 1 free segment:
>
> Initial status: 1 free segment is needed
>
> segment 0 segment 1 segment 2 segment 3 segment 4 segment 5
> |20% invalid| |20% invalid| |20% invalid| |20% invalid| |20% invalid| | free |
> |80% valid| |80% valid| |80% valid| |80% valid| |80% valid| | free |
>
>
> step 1: segment 0 -> segment 5, free segment 0
Should be step 1: segment 0 -> segment 5, prefree segment 0
Anyway,
> segment 0 segment 1 segment 2 segment 3 segment 4 segment 5
> | free | |20% invalid| |20% invalid| |20% invalid| |20% invalid| |20% free|
> | free | |80% valid| |80% valid| |80% valid| |80% valid| |80% valid|
>
>
> step 2: segment 1 -> segment 5 and segment 0, free segment 1
Here, we cannot use segment 0 to fill 60% to handle power-cut. If power-cut
happens after this, we will lose prevous data in segment 0. That's why we're
using prefree segments.
Thanks,
>
> segment 0 segment 1 segment 2 segment 3 segment 4 segment 5
> |40% free| | free | |20% invalid| |20% invalid| |20% invalid| |20% valid|
> |60% valid| | free | |80% valid| |80% valid| |80% valid| |80% valid|
>
>
> step 3: segment 2 -> segment 0 and segment 1, free segment 2
>
> segment 0 segment 1 segment 2 segment 3 segment 4 segment 5
> |40% valid| |60% free| | free | |20% invalid| |20% invalid| |20% valid|
> |60% valid| |40% valid| | free | |80% valid| |80% valid| |80% valid|
>
>
> step 4: segment 3 -> segment 1 and segment 2, free segment 3
>
> segment 0 segment 1 segment 2 segment 3 segment 4 segment 5
> |40% valid| |60% valid| |80% free| | free | |20% invalid| |20% valid|
> |60% valid| |40% valid| |20% valid| | free | |80% valid| |80% valid|
>
>
> step 5: segment 4 -> segment 2, free segment 4
>
> segment 0 segment 1 segment 2 segment 3 segment 4 segment 5
> |40% valid| |60% valid| |80% valid| | free | | free | |20% valid|
> |60% valid| |40% valid| |20% valid| | free | | free | |80% valid|
>
> done. Now there are 1 new free segment.
>
> If we change the f2fs gc codes in future, we can even let the initial 1 free
> segment go away, just copy valid data among the 5 segments themselves using SSR.
>
> So the previous formula:
>
> c.reserved_segments = (2 * (100 / c.overprovision + 1) + 6) * c.segs_per_sec;
>
> is not needed, we can set reserved_segments to any value if we want, no matter
> what value c.overprovision is, just take it away from the formula.
>
> And take take a look at the overprov_segment_count in current design of
> mkfs.f2fs:
>
> set_cp(overprov_segment_count, (get_sb(segment_count_main) - get_cp(rsvd_segment_count)) * c.overprovision / 100);
>
> The original motivation may be like this:
>
> For example, if ovp is 20%, the worst case is that each segment is 20% invalid,
> then all the segments can not be selected as victim target for FTL GC, then
> there is (segment_count_main - rsvd_segment_count) * 20%, which are all invalid
> blocks and can not be used for write, thus we should regard this as
> overprovision segments, which can never be used by user. However, as we
> have explained above, all the device capacity which FTL tells f2fs can be used
> for write, so it is not correct to use this formula. In fact, we do not need to set
> the overprovision segments at all for this consideration.
>
> Yunlong Song (2):
> mkfs.f2fs: add option to set the value of reserved segments
> and overprovision segments
> f2fs: fix the case when there is no free segment to allocate for
> CURSEG_WARM_NODE
>
> fs/f2fs/segment.c | 2 --
> 1 file changed, 2 deletions(-)
>
> --
> 1.8.5.2
^ permalink raw reply [flat|nested] 7+ messages in thread