diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-04-25 22:55:17 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-04-28 22:19:32 -0400 |
commit | afcb7ca01f47b0481e0b248d1542d0934fa70767 (patch) | |
tree | 2834b57b958d2b444d40aa8144ac60ee739507ac /fs/f2fs/data.c | |
parent | 55008d845d233396ed374473da4613cee691aa03 (diff) |
f2fs: check truncation of mapping after lock_page
We call lock_page when we need to update a page after readpage.
Between grab and lock page, the page can be truncated by other thread.
So, we should check the page after lock_page whether it was truncated or not.
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/data.c')
-rw-r--r-- | fs/f2fs/data.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index eba7e84d1ffd..2db9380f5dda 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -240,7 +240,7 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index) | |||
240 | 240 | ||
241 | if (dn.data_blkaddr == NULL_ADDR) | 241 | if (dn.data_blkaddr == NULL_ADDR) |
242 | return ERR_PTR(-ENOENT); | 242 | return ERR_PTR(-ENOENT); |
243 | 243 | repeat: | |
244 | page = grab_cache_page(mapping, index); | 244 | page = grab_cache_page(mapping, index); |
245 | if (!page) | 245 | if (!page) |
246 | return ERR_PTR(-ENOMEM); | 246 | return ERR_PTR(-ENOMEM); |
@@ -260,6 +260,10 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index) | |||
260 | f2fs_put_page(page, 1); | 260 | f2fs_put_page(page, 1); |
261 | return ERR_PTR(-EIO); | 261 | return ERR_PTR(-EIO); |
262 | } | 262 | } |
263 | if (page->mapping != mapping) { | ||
264 | f2fs_put_page(page, 1); | ||
265 | goto repeat; | ||
266 | } | ||
263 | return page; | 267 | return page; |
264 | } | 268 | } |
265 | 269 | ||
@@ -291,7 +295,7 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index, | |||
291 | } | 295 | } |
292 | } | 296 | } |
293 | f2fs_put_dnode(&dn); | 297 | f2fs_put_dnode(&dn); |
294 | 298 | repeat: | |
295 | page = grab_cache_page(mapping, index); | 299 | page = grab_cache_page(mapping, index); |
296 | if (!page) | 300 | if (!page) |
297 | return ERR_PTR(-ENOMEM); | 301 | return ERR_PTR(-ENOMEM); |
@@ -311,6 +315,10 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index, | |||
311 | f2fs_put_page(page, 1); | 315 | f2fs_put_page(page, 1); |
312 | return ERR_PTR(-EIO); | 316 | return ERR_PTR(-EIO); |
313 | } | 317 | } |
318 | if (page->mapping != mapping) { | ||
319 | f2fs_put_page(page, 1); | ||
320 | goto repeat; | ||
321 | } | ||
314 | } | 322 | } |
315 | 323 | ||
316 | if (new_i_size && | 324 | if (new_i_size && |
@@ -611,7 +619,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, | |||
611 | *fsdata = NULL; | 619 | *fsdata = NULL; |
612 | 620 | ||
613 | f2fs_balance_fs(sbi); | 621 | f2fs_balance_fs(sbi); |
614 | 622 | repeat: | |
615 | page = grab_cache_page_write_begin(mapping, index, flags); | 623 | page = grab_cache_page_write_begin(mapping, index, flags); |
616 | if (!page) | 624 | if (!page) |
617 | return -ENOMEM; | 625 | return -ENOMEM; |
@@ -656,6 +664,10 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, | |||
656 | f2fs_put_page(page, 1); | 664 | f2fs_put_page(page, 1); |
657 | return -EIO; | 665 | return -EIO; |
658 | } | 666 | } |
667 | if (page->mapping != mapping) { | ||
668 | f2fs_put_page(page, 1); | ||
669 | goto repeat; | ||
670 | } | ||
659 | } | 671 | } |
660 | out: | 672 | out: |
661 | SetPageUptodate(page); | 673 | SetPageUptodate(page); |