summaryrefslogtreecommitdiff
path: root/fs/f2fs
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2014-09-07 11:05:20 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2014-09-09 13:15:07 -0700
commit9a01b56b1a79e210e9d2d67c9b18906d31d536c4 (patch)
treee87eb9e201717999a21e78dabb04cf2748f0dbf3 /fs/f2fs
parent721bd4d5c3f957f98157b6dcac9c4a4dd828e3ff (diff)
downloadlinux-next-9a01b56b1a79e210e9d2d67c9b18906d31d536c4.tar.gz
f2fs: avoid node page to be written twice in gc_node_segment
In gc_node_segment, if node page gc is run concurrently with node page writeback, and check_valid_map and get_node_page run after page locked and before cur_valid_map is updated as below, it is possible for the page to be written twice unnecessarily. sync_node_pages try_lock_page ... check_valid_map f2fs_write_node_page ... write_node_page do_write_page allocate_data_block ... refresh_sit_entry /* update cur_valid_map */ ... ... unlock_page get_node_page ... set_page_dirty ... f2fs_put_page unlock_page This can be solved via calling check_valid_map after get_node_page again. Signed-off-by: Huang, Ying <ying.huang@intel.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/gc.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 943a31db7cc3..075ea1eb8fa0 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -423,6 +423,12 @@ next_step:
if (IS_ERR(node_page))
continue;
+ /* block may become invalid during get_node_page */
+ if (check_valid_map(sbi, segno, off) == 0) {
+ f2fs_put_page(node_page, 1);
+ continue;
+ }
+
/* set page dirty and write it */
if (gc_type == FG_GC) {
f2fs_wait_on_page_writeback(node_page, NODE);