]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/f2fs/node.c
f2fs: increase pages_skipped when skipping writepages
[karo-tx-linux.git] / fs / f2fs / node.c
index c415cec041b73f0c573f46b5a6f40f6a3c50e5d4..7cc146bcbfed1df06fc6c481e4cdecdb5a4f401e 100644 (file)
@@ -836,7 +836,7 @@ struct page *new_node_page(struct dnode_of_data *dn,
        SetPageUptodate(page);
        set_page_dirty(page);
 
-       if (ofs == XATTR_NODE_OFFSET)
+       if (f2fs_has_xattr_block(ofs))
                F2FS_I(dn->inode)->i_xattr_nid = dn->nid;
 
        dn->node_page = page;
@@ -1198,12 +1198,6 @@ redirty_out:
        return AOP_WRITEPAGE_ACTIVATE;
 }
 
-/*
- * It is very important to gather dirty pages and write at once, so that we can
- * submit a big bio without interfering other data writes.
- * Be default, 512 pages (2MB) * 3 node types, is more reasonable.
- */
-#define COLLECT_DIRTY_NODES    1536
 static int f2fs_write_node_pages(struct address_space *mapping,
                            struct writeback_control *wbc)
 {
@@ -1214,8 +1208,8 @@ static int f2fs_write_node_pages(struct address_space *mapping,
        f2fs_balance_fs_bg(sbi);
 
        /* collect a number of dirty node pages and write together */
-       if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES)
-               return 0;
+       if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
+               goto skip_write;
 
        /* if mounting is failed, skip writing node pages */
        wbc->nr_to_write = 3 * max_hw_blocks(sbi);
@@ -1224,6 +1218,10 @@ static int f2fs_write_node_pages(struct address_space *mapping,
        wbc->nr_to_write = nr_to_write - (3 * max_hw_blocks(sbi) -
                                                wbc->nr_to_write);
        return 0;
+
+skip_write:
+       wbc->pages_skipped += get_pages(sbi, F2FS_DIRTY_NODES);
+       return 0;
 }
 
 static int f2fs_set_node_page_dirty(struct page *page)
@@ -1493,6 +1491,37 @@ void recover_node_page(struct f2fs_sb_info *sbi, struct page *page,
        clear_node_page_dirty(page);
 }
 
+void recover_inline_xattr(struct inode *inode, struct page *page)
+{
+       struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       void *src_addr, *dst_addr;
+       size_t inline_size;
+       struct page *ipage;
+       struct f2fs_inode *ri;
+
+       if (!f2fs_has_inline_xattr(inode))
+               return;
+
+       if (!IS_INODE(page))
+               return;
+
+       ri = F2FS_INODE(page);
+       if (!(ri->i_inline & F2FS_INLINE_XATTR))
+               return;
+
+       ipage = get_node_page(sbi, inode->i_ino);
+       f2fs_bug_on(IS_ERR(ipage));
+
+       dst_addr = inline_xattr_addr(ipage);
+       src_addr = inline_xattr_addr(page);
+       inline_size = inline_xattr_size(inode);
+
+       memcpy(dst_addr, src_addr, inline_size);
+
+       update_inode(inode, ipage);
+       f2fs_put_page(ipage, 1);
+}
+
 bool recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
@@ -1500,7 +1529,9 @@ bool recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr)
        nid_t new_xnid = nid_of_node(page);
        struct node_info ni;
 
-       if (ofs_of_node(page) != XATTR_NODE_OFFSET)
+       recover_inline_xattr(inode, page);
+
+       if (!f2fs_has_xattr_block(ofs_of_node(page)))
                return false;
 
        /* 1: invalidate the previous xattr nid */