Skip to content

Commit 1e78e8b

Browse files
Sahitya TummalaJaegeuk Kim
authored andcommitted
f2fs: fix data corruption issue with hardware encryption
Direct IO can be used in case of hardware encryption. The following scenario results into data corruption issue in this path - Thread A - Thread B- -> write file#1 in direct IO -> GC gets kicked in -> GC submitted bio on meta mapping for file#1, but pending completion -> write file#1 again with new data in direct IO -> GC bio gets completed now -> GC writes old data to the new location and thus file#1 is corrupted. Fix this by submitting and waiting for pending io on meta mapping for direct IO case in f2fs_map_blocks(). Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 0c093b5 commit 1e78e8b

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

fs/f2fs/data.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,11 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
10531053
map->m_flags = F2FS_MAP_MAPPED;
10541054
if (map->m_next_extent)
10551055
*map->m_next_extent = pgofs + map->m_len;
1056+
1057+
/* for hardware encryption, but to avoid potential issue in future */
1058+
if (flag == F2FS_GET_BLOCK_DIO)
1059+
f2fs_wait_on_block_writeback_range(inode,
1060+
map->m_pblk, map->m_len);
10561061
goto out;
10571062
}
10581063

@@ -1211,6 +1216,12 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
12111216
goto next_dnode;
12121217

12131218
sync_out:
1219+
1220+
/* for hardware encryption, but to avoid potential issue in future */
1221+
if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED)
1222+
f2fs_wait_on_block_writeback_range(inode,
1223+
map->m_pblk, map->m_len);
1224+
12141225
if (flag == F2FS_GET_BLOCK_PRECACHE) {
12151226
if (map->m_flags & F2FS_MAP_MAPPED) {
12161227
unsigned int ofs = start_pgofs - map->m_lblk;

fs/f2fs/f2fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,6 +2988,8 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
29882988
void f2fs_wait_on_page_writeback(struct page *page,
29892989
enum page_type type, bool ordered);
29902990
void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
2991+
void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
2992+
block_t len);
29912993
void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
29922994
void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
29932995
int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,

fs/f2fs/segment.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3303,6 +3303,15 @@ void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr)
33033303
}
33043304
}
33053305

3306+
void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr,
3307+
block_t len)
3308+
{
3309+
block_t i;
3310+
3311+
for (i = 0; i < len; i++)
3312+
f2fs_wait_on_block_writeback(inode, blkaddr + i);
3313+
}
3314+
33063315
static int read_compacted_summaries(struct f2fs_sb_info *sbi)
33073316
{
33083317
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);

0 commit comments

Comments
 (0)