diff options
author | Chao Yu <chao2.yu@samsung.com> | 2013-12-04 20:54:56 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-12-22 20:18:06 -0500 |
commit | b9987a277f1ec9dba203d04c3a20d967c01a1fba (patch) | |
tree | abb337cbc3d88aaa49836c191aa4f33e2226de43 | |
parent | a0acdfe05a954363861a65eb537573ab417cb7ed (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.c | 9 |
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); |
195 | out: | ||
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); |
416 | out: | ||
417 | __free_pages(page, 0); | 418 | __free_pages(page, 0); |
418 | 419 | ||
419 | if (!err) | 420 | if (!err) |