diff options
author | Sahitya Tummala <stummala@codeaurora.org> | 2018-10-10 10:56:22 +0530 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2018-10-22 17:54:47 -0700 |
commit | 1e78e8bd9d107c351930cdb1e11202caec01b311 (patch) | |
tree | c5474a32fa460a8583eb9bc88e7c21a0035ebcf0 /fs/f2fs/data.c | |
parent | 0c093b590efb5c1ccdc835868dc2ae94bd2e14dc (diff) | |
download | lwn-1e78e8bd9d107c351930cdb1e11202caec01b311.tar.gz lwn-1e78e8bd9d107c351930cdb1e11202caec01b311.zip |
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>
Diffstat (limited to 'fs/f2fs/data.c')
-rw-r--r-- | fs/f2fs/data.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8a831f17503e..00b37a1bd15c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1053,6 +1053,11 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, map->m_flags = F2FS_MAP_MAPPED; if (map->m_next_extent) *map->m_next_extent = pgofs + map->m_len; + + /* for hardware encryption, but to avoid potential issue in future */ + if (flag == F2FS_GET_BLOCK_DIO) + f2fs_wait_on_block_writeback_range(inode, + map->m_pblk, map->m_len); goto out; } @@ -1211,6 +1216,12 @@ skip: goto next_dnode; sync_out: + + /* for hardware encryption, but to avoid potential issue in future */ + if (flag == F2FS_GET_BLOCK_DIO && map->m_flags & F2FS_MAP_MAPPED) + f2fs_wait_on_block_writeback_range(inode, + map->m_pblk, map->m_len); + if (flag == F2FS_GET_BLOCK_PRECACHE) { if (map->m_flags & F2FS_MAP_MAPPED) { unsigned int ofs = start_pgofs - map->m_lblk; |