aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2013-12-04 20:54:56 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-12-22 20:18:06 -0500
commitb9987a277f1ec9dba203d04c3a20d967c01a1fba (patch)
treeabb337cbc3d88aaa49836c191aa4f33e2226de43
parenta0acdfe05a954363861a65eb537573ab417cb7ed (diff)
f2fs: avoid unneeded page release for correct _count of page
In find_fsync_dnodes() and recover_data(), our flow is like this: ->f2fs_submit_page_bio() -> f2fs_put_page() -> page_cache_release() ---- page->_count declined to zero. ->__free_pages() -> put_page_testzero() ---- page->_count will be declined again. We will get a segment fault in put_page_testzero when CONFIG_DEBUG_VM is on, or return MM with a bad page with wrong _count num. So let's just release this page. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/recovery.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 7dda1f28f6cb..d07546575879 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -145,7 +145,7 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)
145 145
146 err = f2fs_submit_page_bio(sbi, page, blkaddr, READ_SYNC); 146 err = f2fs_submit_page_bio(sbi, page, blkaddr, READ_SYNC);
147 if (err) 147 if (err)
148 goto out; 148 return err;
149 149
150 lock_page(page); 150 lock_page(page);
151 151
@@ -191,9 +191,10 @@ next:
191 /* check next segment */ 191 /* check next segment */
192 blkaddr = next_blkaddr_of_node(page); 192 blkaddr = next_blkaddr_of_node(page);
193 } 193 }
194
194 unlock_page(page); 195 unlock_page(page);
195out:
196 __free_pages(page, 0); 196 __free_pages(page, 0);
197
197 return err; 198 return err;
198} 199}
199 200
@@ -388,7 +389,7 @@ static int recover_data(struct f2fs_sb_info *sbi,
388 389
389 err = f2fs_submit_page_bio(sbi, page, blkaddr, READ_SYNC); 390 err = f2fs_submit_page_bio(sbi, page, blkaddr, READ_SYNC);
390 if (err) 391 if (err)
391 goto out; 392 return err;
392 393
393 lock_page(page); 394 lock_page(page);
394 395
@@ -412,8 +413,8 @@ next:
412 /* check next segment */ 413 /* check next segment */
413 blkaddr = next_blkaddr_of_node(page); 414 blkaddr = next_blkaddr_of_node(page);
414 } 415 }
416
415 unlock_page(page); 417 unlock_page(page);
416out:
417 __free_pages(page, 0); 418 __free_pages(page, 0);
418 419
419 if (!err) 420 if (!err)