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>
此提交包含在:
Chao Yu
2021-03-05 17:56:01 +08:00
提交者 Jaegeuk Kim
父節點 a5407f50d3
當前提交 26423921ac
共有 3 個檔案被更改,包括 36 行新增19 行删除

查看文件

@@ -1644,27 +1644,26 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
return 0;
if (f2fs_is_pinned_file(inode)) {
block_t len = (map.m_len >> sbi->log_blocks_per_seg) <<
sbi->log_blocks_per_seg;
block_t sec_blks = BLKS_PER_SEC(sbi);
block_t sec_len = roundup(map.m_len, sec_blks);
block_t done = 0;
if (map.m_len % sbi->blocks_per_seg)
len += sbi->blocks_per_seg;
map.m_len = sbi->blocks_per_seg;
map.m_len = sec_blks;
next_alloc:
if (has_not_enough_free_secs(sbi, 0,
GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) {
down_write(&sbi->gc_lock);
err = f2fs_gc(sbi, true, false, false, NULL_SEGNO);
if (err && err != -ENODATA && err != -EAGAIN)
if (err && err != -ENODATA && err != -EAGAIN) {
map.m_len = done;
goto out_err;
}
}
down_write(&sbi->pin_sem);
f2fs_lock_op(sbi);
f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED);
f2fs_unlock_op(sbi);
map.m_seg_type = CURSEG_COLD_DATA_PINNED;
@@ -1673,9 +1672,9 @@ next_alloc:
up_write(&sbi->pin_sem);
done += map.m_len;
len -= map.m_len;
sec_len -= map.m_len;
map.m_lblk += map.m_len;
if (!err && len)
if (!err && sec_len)
goto next_alloc;
map.m_len = done;