f2fs: call f2fs_wait_on_page_writeback instead of native function
authorJaegeuk Kim <jaegeuk.kim@samsung.com>
Tue, 18 Mar 2014 04:29:07 +0000 (13:29 +0900)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Thu, 20 Mar 2014 13:10:04 +0000 (22:10 +0900)
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>
fs/f2fs/checkpoint.c
fs/f2fs/dir.c
fs/f2fs/file.c
fs/f2fs/node.c
fs/f2fs/recovery.c

index 2a00c94726fb9bf3d6ff21175507852ace69163b..a80be5121e8a0767d88476701e157c4c3665a9f5 100644 (file)
@@ -33,14 +33,12 @@ struct page *grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
        struct address_space *mapping = META_MAPPING(sbi);
        struct page *page = NULL;
 repeat:
-       page = grab_cache_page(mapping, index);
+       page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
        if (!page) {
                cond_resched();
                goto repeat;
        }
 
-       /* We wait writeback only inside grab_meta_page() */
-       wait_on_page_writeback(page);
        SetPageUptodate(page);
        return page;
 }
@@ -168,7 +166,7 @@ static int f2fs_write_meta_page(struct page *page,
        if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG)))
                goto no_write;
 
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, META);
        write_meta_page(sbi, page);
 no_write:
        dec_page_count(sbi, F2FS_DIRTY_META);
index f3a80ce9ddf5801b07f20451977e4557506d21be..7c9b17c0367581e4e7253e602b4e8f2b54e9cb0d 100644 (file)
@@ -253,7 +253,7 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
                struct page *page, struct inode *inode)
 {
        lock_page(page);
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
        de->ino = cpu_to_le32(inode->i_ino);
        set_de_type(de, inode);
        kunmap(page);
@@ -352,14 +352,11 @@ static struct page *init_inode_metadata(struct inode *inode,
                err = f2fs_init_security(inode, dir, name, page);
                if (err)
                        goto put_error;
-
-               wait_on_page_writeback(page);
        } else {
                page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
                if (IS_ERR(page))
                        return page;
 
-               wait_on_page_writeback(page);
                set_cold_node(inode, page);
        }
 
@@ -494,7 +491,7 @@ start:
        ++level;
        goto start;
 add_dentry:
-       wait_on_page_writeback(dentry_page);
+       f2fs_wait_on_page_writeback(dentry_page, DATA);
 
        page = init_inode_metadata(inode, dir, name);
        if (IS_ERR(page)) {
@@ -543,7 +540,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
        int i;
 
        lock_page(page);
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
 
        dentry_blk = (struct f2fs_dentry_block *)kaddr;
        bit_pos = dentry - (struct f2fs_dir_entry *)dentry_blk->dentry;
index a4cc1d6bdd848f8f402d02286ecbd140855223d2..e755ee57e042a081405c1d1b745e246004a4ba6b 100644 (file)
@@ -76,7 +76,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        trace_f2fs_vm_page_mkwrite(page, DATA);
 mapped:
        /* fill the page */
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
 out:
        sb_end_pagefault(inode->i_sb);
        return block_page_mkwrite_return(err);
@@ -245,7 +245,7 @@ static void truncate_partial_data_page(struct inode *inode, u64 from)
                f2fs_put_page(page, 1);
                return;
        }
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
        zero_user(page, offset, PAGE_CACHE_SIZE - offset);
        set_page_dirty(page);
        f2fs_put_page(page, 1);
@@ -422,7 +422,7 @@ static void fill_zero(struct inode *inode, pgoff_t index,
        f2fs_unlock_op(sbi);
 
        if (!IS_ERR(page)) {
-               wait_on_page_writeback(page);
+               f2fs_wait_on_page_writeback(page, DATA);
                zero_user(page, start, len);
                set_page_dirty(page);
                f2fs_put_page(page, 1);
index 5e9c38e846a56017c2d1141da04de6db488ff523..9a6d8bbf0bd73281ed10bf99b4812ae1492e482f 100644 (file)
@@ -725,7 +725,7 @@ skip_partial:
                                f2fs_put_page(page, 1);
                                goto restart;
                        }
-                       wait_on_page_writeback(page);
+                       f2fs_wait_on_page_writeback(page, NODE);
                        ri->i_nid[offset[0] - NODE_DIR1_BLOCK] = 0;
                        set_page_dirty(page);
                        unlock_page(page);
@@ -814,7 +814,8 @@ struct page *new_node_page(struct dnode_of_data *dn,
        if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
                return ERR_PTR(-EPERM);
 
-       page = grab_cache_page(NODE_MAPPING(sbi), dn->nid);
+       page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
+                                       dn->nid, AOP_FLAG_NOFS);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -910,7 +911,8 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
        struct page *page;
        int err;
 repeat:
-       page = grab_cache_page(NODE_MAPPING(sbi), nid);
+       page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
+                                       nid, AOP_FLAG_NOFS);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -1130,7 +1132,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
                                continue;
 
                        if (ino && ino_of_node(page) == ino) {
-                               wait_on_page_writeback(page);
+                               f2fs_wait_on_page_writeback(page, NODE);
                                if (TestClearPageError(page))
                                        ret = -EIO;
                        }
@@ -1163,7 +1165,7 @@ static int f2fs_write_node_page(struct page *page,
        if (unlikely(sbi->por_doing))
                goto redirty_out;
 
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, NODE);
 
        /* get old block addr of this node page */
        nid = nid_of_node(page);
index 03b28ec4c2dc4b115841ae24d816de03468cf077..bbef4ed157a77bd349c16c1da2c58f9116e546b9 100644 (file)
@@ -316,7 +316,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
                goto out;
        }
 
-       wait_on_page_writeback(dn.node_page);
+       f2fs_wait_on_page_writeback(dn.node_page, NODE);
 
        get_node_info(sbi, dn.nid, &ni);
        f2fs_bug_on(ni.ino != ino_of_node(page));