summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/file.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-10-08 13:27:34 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2015-10-13 09:52:34 -0700
commit08b39fbd59781729da9fb6367decaf4804a22721 (patch)
tree47c7016690f424b2461fe5ac75c876ade8f83a82 /fs/f2fs/file.c
parentea1a29a0bdfffd56ca98335c0655308e8d7d0e22 (diff)
downloadlinux-stable-08b39fbd59781729da9fb6367decaf4804a22721.tar.gz
linux-stable-08b39fbd59781729da9fb6367decaf4804a22721.tar.bz2
linux-stable-08b39fbd59781729da9fb6367decaf4804a22721.zip
f2fs crypto: fix racing of accessing encrypted page among
different competitors Since we use different page cache (normally inode's page cache for R/W and meta inode's page cache for GC) to cache the same physical block which is belong to an encrypted inode. Writeback of these two page cache should be exclusive, but now we didn't handle writeback state well, so there may be potential racing problem: a) kworker: f2fs_gc: - f2fs_write_data_pages - f2fs_write_data_page - do_write_data_page - write_data_page - f2fs_submit_page_mbio (page#1 in inode's page cache was queued in f2fs bio cache, and be ready to write to new blkaddr) - gc_data_segment - move_encrypted_block - pagecache_get_page (page#2 in meta inode's page cache was cached with the invalid datas of physical block located in new blkaddr) - f2fs_submit_page_mbio (page#1 was submitted, later, page#2 with invalid data will be submitted) b) f2fs_gc: - gc_data_segment - move_encrypted_block - f2fs_submit_page_mbio (page#1 in meta inode's page cache was queued in f2fs bio cache, and be ready to write to new blkaddr) user thread: - f2fs_write_begin - f2fs_submit_page_bio (we submit the request to block layer to update page#2 in inode's page cache with physical block located in new blkaddr, so here we may read gabbage data from new blkaddr since GC hasn't writebacked the page#1 yet) This patch fixes above potential racing problem for encrypted inode. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/file.c')
-rw-r--r--fs/f2fs/file.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 5d2a2ee35742..91c51a6d42dd 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -87,6 +87,11 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
mapped:
/* fill the page */
f2fs_wait_on_page_writeback(page, DATA);
+
+ /* wait for GCed encrypted page writeback */
+ if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+ f2fs_wait_on_encrypted_page_writeback(sbi, dn.data_blkaddr);
+
/* if gced page is attached, don't write to cold segment */
clear_cold_data(page);
out: