f2fs: fix to align to section for fallocate() on pinned file

Now, fallocate() on a pinned file only allocates blocks which aligns
to segment rather than section, so GC may try to migrate pinned file's
block, and after several times of failure, pinned file's block could
be migrated to other place, however user won't be aware of such
condition, and then old obsolete block address may be readed/written
incorrectly.

To avoid such condition, let's try to allocate pinned file's blocks
with section alignment.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Chao Yu
2021-03-05 17:56:01 +08:00
committed by Jaegeuk Kim
parent a5407f50d3
commit 26423921ac
3 changed files with 36 additions and 19 deletions

View File

@@ -2899,7 +2899,8 @@ unlock:
up_read(&SM_I(sbi)->curseg_lock);
}
static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type,
bool new_sec)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
unsigned int old_segno;
@@ -2907,10 +2908,22 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
if (!curseg->inited)
goto alloc;
if (!curseg->next_blkoff &&
!get_valid_blocks(sbi, curseg->segno, false) &&
!get_ckpt_valid_blocks(sbi, curseg->segno))
return;
if (curseg->next_blkoff ||
get_valid_blocks(sbi, curseg->segno, new_sec))
goto alloc;
if (new_sec) {
unsigned int segno = START_SEGNO(curseg->segno);
int i;
for (i = 0; i < sbi->segs_per_sec; i++, segno++) {
if (get_ckpt_valid_blocks(sbi, segno))
goto alloc;
}
} else {
if (!get_ckpt_valid_blocks(sbi, curseg->segno))
return;
}
alloc:
old_segno = curseg->segno;
@@ -2918,10 +2931,15 @@ alloc:
locate_dirty_segment(sbi, old_segno);
}
void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
static void __allocate_new_section(struct f2fs_sb_info *sbi, int type)
{
__allocate_new_segment(sbi, type, true);
}
void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type)
{
down_write(&SIT_I(sbi)->sentry_lock);
__allocate_new_segment(sbi, type);
__allocate_new_section(sbi, type);
up_write(&SIT_I(sbi)->sentry_lock);
}
@@ -2931,7 +2949,7 @@ void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
down_write(&SIT_I(sbi)->sentry_lock);
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
__allocate_new_segment(sbi, i);
__allocate_new_segment(sbi, i, false);
up_write(&SIT_I(sbi)->sentry_lock);
}