2019-04-09 10:37:40

by Sahitya Tummala

[permalink] [raw]
Subject: [PATCH 1/4] f2fs: add F2FS_IOC_RESIZE_FROM_END for compat_ioctl

Add F2FS_IOC_RESIZE_FROM_END for f2fs_compat_ioctl() as well.

Signed-off-by: Sahitya Tummala <[email protected]>
---
fs/f2fs/file.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 42adfc2..0514935 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3159,6 +3159,7 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case F2FS_IOC_GET_PIN_FILE:
case F2FS_IOC_SET_PIN_FILE:
case F2FS_IOC_PRECACHE_EXTENTS:
+ case F2FS_IOC_RESIZE_FROM_END:
break;
default:
return -ENOIOCTLCMD;
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.


2019-04-09 10:38:18

by Sahitya Tummala

[permalink] [raw]
Subject: [PATCH 3/4] f2fs: fix race between online resize path and allocate new data block path

There can be a potential race between allocate_segment_for_resize() and
allocate_data_block(), resulting into two issues -

1. The allocate_data_block() can get a data block from a segment which
is currently being resized. This results in data being updated in an
outdated or already resized segment.

2. It also results into these warnings from get_new_segment():
f2fs_bug_on(sbi, secno >= NEW_MAIN_SECS(sbi));

Fix these by using curseg_mutex lock in the resize context to prevent
race with allocate_data_block() path.

Signed-off-by: Sahitya Tummala <[email protected]>
---
fs/f2fs/segment.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 1c3cc30..e7c411f 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2643,12 +2643,14 @@ void allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type)
struct curseg_info *curseg = CURSEG_I(sbi, type);
unsigned int old_segno = curseg->segno;

+ mutex_lock(&curseg->curseg_mutex);
if (f2fs_need_SSR(sbi) && get_ssr_segment(sbi, type))
change_curseg(sbi, type);
else
new_curseg(sbi, type, true);

stat_inc_seg_type(sbi, curseg);
+ mutex_unlock(&curseg->curseg_mutex);

if (get_valid_blocks(sbi, old_segno, false) == 0)
__set_test_and_free(sbi, old_segno);
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.

2019-04-09 10:39:01

by Sahitya Tummala

[permalink] [raw]
Subject: [PATCH 2/4] f2fs: fix debugfs status to reflect the online resize changes

The main area segs/secs/zones will be updated/changed after an
online resize. Hence, update the struct f2fs_stat_info as well
accordingly to show correct status in debugfs.

Signed-off-by: Sahitya Tummala <[email protected]>
---
fs/f2fs/debug.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index 99e9a5c..7706049 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -27,8 +27,15 @@
static void update_general_status(struct f2fs_sb_info *sbi)
{
struct f2fs_stat_info *si = F2FS_STAT(sbi);
+ struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
int i;

+ /* these will be changed if online resize is done */
+ si->main_area_segs = le32_to_cpu(raw_super->segment_count_main);
+ si->main_area_sections = le32_to_cpu(raw_super->section_count);
+ si->main_area_zones = si->main_area_sections /
+ le32_to_cpu(raw_super->secs_per_zone);
+
/* validation check of the segment numbers */
si->hit_largest = atomic64_read(&sbi->read_hit_largest);
si->hit_cached = atomic64_read(&sbi->read_hit_cached);
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.

2019-04-09 10:39:35

by Sahitya Tummala

[permalink] [raw]
Subject: [PATCH 4/4] f2fs: fix potential race between online resize path and gc path

NEW_MAIN_SECS() can be updated by f2fs_resize_from_end() path,
while get_victim_by_default() is running. Hence, protect all
references to NEW_MAIN_SECS() with seglist_lock mutex.

Signed-off-by: Sahitya Tummala <[email protected]>
---
fs/f2fs/gc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 2077be9..d636721 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -311,10 +311,11 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
struct sit_info *sm = SIT_I(sbi);
struct victim_sel_policy p;
unsigned int secno, last_victim;
- unsigned int last_segment = NEW_MAIN_SECS(sbi) * sbi->segs_per_sec;
+ unsigned int last_segment;
unsigned int nsearched = 0;

mutex_lock(&dirty_i->seglist_lock);
+ last_segment = NEW_MAIN_SECS(sbi) * sbi->segs_per_sec;

p.alloc_mode = alloc_mode;
select_policy(sbi, gc_type, type, &p);
@@ -1400,6 +1401,7 @@ int f2fs_resize_from_end(struct f2fs_sb_info *sbi, size_t resize_len)

mutex_lock(&DIRTY_I(sbi)->seglist_lock);
NEW_MAIN_SECS(sbi) = MAIN_SECS(sbi) - secs;
+
for (gc_mode = 0; gc_mode < MAX_GC_POLICY; gc_mode++)
if (SIT_I(sbi)->last_victim[gc_mode] >=
NEW_MAIN_SECS(sbi) * sbi->segs_per_sec)
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.