aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2014-03-18 00:29:07 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-03-20 09:10:04 -0400
commit3cb5ad152b54430f3e5f338c15f8cd434e7160c8 (patch)
tree84f89b065e23b7f174f2c7d777217c6b2d363da6
parent50c8cdb35ad8016c52fb2326ef9d65542e3a3e1b (diff)
f2fs: call f2fs_wait_on_page_writeback instead of native function
If a page is on writeback, f2fs can face with deadlock due to under writepages. This is caused by merging IOs inside f2fs, so if it comes to detect, let's throw merged IOs, which is implemented by f2fs_wait_on_page_writeback. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/checkpoint.c6
-rw-r--r--fs/f2fs/dir.c9
-rw-r--r--fs/f2fs/file.c6
-rw-r--r--fs/f2fs/node.c12
-rw-r--r--fs/f2fs/recovery.c2
5 files changed, 16 insertions, 19 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 2a00c94726fb..a80be5121e8a 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -33,14 +33,12 @@ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
33 struct address_space *mapping = META_MAPPING(sbi); 33 struct address_space *mapping = META_MAPPING(sbi);
34 struct page *page = NULL; 34 struct page *page = NULL;
35repeat: 35repeat:
36 page = grab_cache_page(mapping, index); 36 page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
37 if (!page) { 37 if (!page) {
38 cond_resched(); 38 cond_resched();
39 goto repeat; 39 goto repeat;
40 } 40 }
41 41
42 /* We wait writeback only inside grab_meta_page() */
43 wait_on_page_writeback(page);
44 SetPageUptodate(page); 42 SetPageUptodate(page);
45 return page; 43 return page;
46} 44}
@@ -168,7 +166,7 @@ static int f2fs_write_meta_page(struct page *page,
168 if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG))) 166 if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
169 goto no_write; 167 goto no_write;
170 168
171 wait_on_page_writeback(page); 169 f2fs_wait_on_page_writeback(page, META);
172 write_meta_page(sbi, page); 170 write_meta_page(sbi, page);
173no_write: 171no_write:
174 dec_page_count(sbi, F2FS_DIRTY_META); 172 dec_page_count(sbi, F2FS_DIRTY_META);
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index f3a80ce9ddf5..7c9b17c03675 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -253,7 +253,7 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
253 struct page *page, struct inode *inode) 253 struct page *page, struct inode *inode)
254{ 254{
255 lock_page(page); 255 lock_page(page);
256 wait_on_page_writeback(page); 256 f2fs_wait_on_page_writeback(page, DATA);
257 de->ino = cpu_to_le32(inode->i_ino); 257 de->ino = cpu_to_le32(inode->i_ino);
258 set_de_type(de, inode); 258 set_de_type(de, inode);
259 kunmap(page); 259 kunmap(page);
@@ -352,14 +352,11 @@ static struct page *init_inode_metadata(struct inode *inode,
352 err = f2fs_init_security(inode, dir, name, page); 352 err = f2fs_init_security(inode, dir, name, page);
353 if (err) 353 if (err)
354 goto put_error; 354 goto put_error;
355
356 wait_on_page_writeback(page);
357 } else { 355 } else {
358 page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); 356 page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
359 if (IS_ERR(page)) 357 if (IS_ERR(page))
360 return page; 358 return page;
361 359
362 wait_on_page_writeback(page);
363 set_cold_node(inode, page); 360 set_cold_node(inode, page);
364 } 361 }
365 362
@@ -494,7 +491,7 @@ start:
494 ++level; 491 ++level;
495 goto start; 492 goto start;
496add_dentry: 493add_dentry:
497 wait_on_page_writeback(dentry_page); 494 f2fs_wait_on_page_writeback(dentry_page, DATA);
498 495
499 page = init_inode_metadata(inode, dir, name); 496 page = init_inode_metadata(inode, dir, name);
500 if (IS_ERR(page)) { 497 if (IS_ERR(page)) {
@@ -543,7 +540,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
543 int i; 540 int i;
544 541
545 lock_page(page); 542 lock_page(page);
546 wait_on_page_writeback(page); 543 f2fs_wait_on_page_writeback(page, DATA);
547 544
548 dentry_blk = (struct f2fs_dentry_block *)kaddr; 545 dentry_blk = (struct f2fs_dentry_block *)kaddr;
549 bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry; 546 bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry;
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index a4cc1d6bdd84..e755ee57e042 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -76,7 +76,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
76 trace_f2fs_vm_page_mkwrite(page, DATA); 76 trace_f2fs_vm_page_mkwrite(page, DATA);
77mapped: 77mapped:
78 /* fill the page */ 78 /* fill the page */
79 wait_on_page_writeback(page); 79 f2fs_wait_on_page_writeback(page, DATA);
80out: 80out:
81 sb_end_pagefault(inode->i_sb); 81 sb_end_pagefault(inode->i_sb);
82 return block_page_mkwrite_return(err); 82 return block_page_mkwrite_return(err);
@@ -245,7 +245,7 @@ static void truncate_partial_data_page(struct inode *inode, u64 from)
245 f2fs_put_page(page, 1); 245 f2fs_put_page(page, 1);
246 return; 246 return;
247 } 247 }
248 wait_on_page_writeback(page); 248 f2fs_wait_on_page_writeback(page, DATA);
249 zero_user(page, offset, PAGE_CACHE_SIZE - offset); 249 zero_user(page, offset, PAGE_CACHE_SIZE - offset);
250 set_page_dirty(page); 250 set_page_dirty(page);
251 f2fs_put_page(page, 1); 251 f2fs_put_page(page, 1);
@@ -422,7 +422,7 @@ static void fill_zero(struct inode *inode, pgoff_t index,
422 f2fs_unlock_op(sbi); 422 f2fs_unlock_op(sbi);
423 423
424 if (!IS_ERR(page)) { 424 if (!IS_ERR(page)) {
425 wait_on_page_writeback(page); 425 f2fs_wait_on_page_writeback(page, DATA);
426 zero_user(page, start, len); 426 zero_user(page, start, len);
427 set_page_dirty(page); 427 set_page_dirty(page);
428 f2fs_put_page(page, 1); 428 f2fs_put_page(page, 1);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 5e9c38e846a5..9a6d8bbf0bd7 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -725,7 +725,7 @@ skip_partial:
725 f2fs_put_page(page, 1); 725 f2fs_put_page(page, 1);
726 goto restart; 726 goto restart;
727 } 727 }
728 wait_on_page_writeback(page); 728 f2fs_wait_on_page_writeback(page, NODE);
729 ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0; 729 ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0;
730 set_page_dirty(page); 730 set_page_dirty(page);
731 unlock_page(page); 731 unlock_page(page);
@@ -814,7 +814,8 @@ struct page *new_node_page(struct dnode_of_data *dn,
814 if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC))) 814 if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
815 return ERR_PTR(-EPERM); 815 return ERR_PTR(-EPERM);
816 816
817 page = grab_cache_page(NODE_MAPPING(sbi), dn->nid); 817 page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
818 dn->nid, AOP_FLAG_NOFS);
818 if (!page) 819 if (!page)
819 return ERR_PTR(-ENOMEM); 820 return ERR_PTR(-ENOMEM);
820 821
@@ -910,7 +911,8 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
910 struct page *page; 911 struct page *page;
911 int err; 912 int err;
912repeat: 913repeat:
913 page = grab_cache_page(NODE_MAPPING(sbi), nid); 914 page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
915 nid, AOP_FLAG_NOFS);
914 if (!page) 916 if (!page)
915 return ERR_PTR(-ENOMEM); 917 return ERR_PTR(-ENOMEM);
916 918
@@ -1130,7 +1132,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
1130 continue; 1132 continue;
1131 1133
1132 if (ino && ino_of_node(page) == ino) { 1134 if (ino && ino_of_node(page) == ino) {
1133 wait_on_page_writeback(page); 1135 f2fs_wait_on_page_writeback(page, NODE);
1134 if (TestClearPageError(page)) 1136 if (TestClearPageError(page))
1135 ret = -EIO; 1137 ret = -EIO;
1136 } 1138 }
@@ -1163,7 +1165,7 @@ static int f2fs_write_node_page(struct page *page,
1163 if (unlikely(sbi->por_doing)) 1165 if (unlikely(sbi->por_doing))
1164 goto redirty_out; 1166 goto redirty_out;
1165 1167
1166 wait_on_page_writeback(page); 1168 f2fs_wait_on_page_writeback(page, NODE);
1167 1169
1168 /* get old block addr of this node page */ 1170 /* get old block addr of this node page */
1169 nid = nid_of_node(page); 1171 nid = nid_of_node(page);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 03b28ec4c2dc..bbef4ed157a7 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -316,7 +316,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
316 goto out; 316 goto out;
317 } 317 }
318 318
319 wait_on_page_writeback(dn.node_page); 319 f2fs_wait_on_page_writeback(dn.node_page, NODE);
320 320
321 get_node_info(sbi, dn.nid, &ni); 321 get_node_info(sbi, dn.nid, &ni);
322 f2fs_bug_on(ni.ino != ino_of_node(page)); 322 f2fs_bug_on(ni.ino != ino_of_node(page));