diff options
author | Huang Ying <ying.huang@intel.com> | 2014-09-07 11:05:20 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-09-09 13:15:07 -0700 |
commit | 9a01b56b1a79e210e9d2d67c9b18906d31d536c4 (patch) | |
tree | e87eb9e201717999a21e78dabb04cf2748f0dbf3 /fs | |
parent | 721bd4d5c3f957f98157b6dcac9c4a4dd828e3ff (diff) | |
download | op-kernel-dev-9a01b56b1a79e210e9d2d67c9b18906d31d536c4.zip op-kernel-dev-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')
-rw-r--r-- | fs/f2fs/gc.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 943a31d..075ea1e 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); |