f2fs: call SetPageUptodate if needed
[deliverable/linux.git] / fs / f2fs / node.c
index 1f21aae80c4015ac4f96be6d268a0613ee3405e0..ca1bb3cc6c32b5ecac355a171c70ffab0688b1a9 100644 (file)
@@ -52,6 +52,10 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type)
                mem_size = (nm_i->nat_cnt * sizeof(struct nat_entry)) >>
                                                        PAGE_SHIFT;
                res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 2);
+               if (excess_cached_nats(sbi))
+                       res = false;
+               if (nm_i->nat_cnt > DEF_NAT_CACHE_THRESHOLD)
+                       res = false;
        } else if (type == DIRTY_DENTS) {
                if (sbi->sb->s_bdi->wb.dirty_exceeded)
                        return false;
@@ -670,8 +674,7 @@ static void truncate_node(struct dnode_of_data *dn)
        if (dn->nid == dn->inode->i_ino) {
                remove_orphan_inode(sbi, dn->nid);
                dec_valid_inode_count(sbi);
-       } else {
-               sync_inode_page(dn);
+               f2fs_inode_synced(dn->inode);
        }
 invalidate:
        clear_node_page_dirty(dn->node_page);
@@ -953,7 +956,7 @@ int truncate_xattr_node(struct inode *inode, struct page *page)
        if (IS_ERR(npage))
                return PTR_ERR(npage);
 
-       F2FS_I(inode)->i_xattr_nid = 0;
+       f2fs_i_xnid_write(inode, 0);
 
        /* need to do checkpoint during fsync */
        F2FS_I(inode)->xattr_ver = cur_cp_version(F2FS_CKPT(sbi));
@@ -1019,7 +1022,7 @@ struct page *new_node_page(struct dnode_of_data *dn,
        struct page *page;
        int err;
 
-       if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
+       if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
                return ERR_PTR(-EPERM);
 
        page = f2fs_grab_cache_page(NODE_MAPPING(sbi), dn->nid, false);
@@ -1042,21 +1045,16 @@ struct page *new_node_page(struct dnode_of_data *dn,
        f2fs_wait_on_page_writeback(page, NODE, true);
        fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true);
        set_cold_node(dn->inode, page);
-       SetPageUptodate(page);
+       if (!PageUptodate(page))
+               SetPageUptodate(page);
        if (set_page_dirty(page))
                dn->node_changed = true;
 
        if (f2fs_has_xattr_block(ofs))
-               F2FS_I(dn->inode)->i_xattr_nid = dn->nid;
+               f2fs_i_xnid_write(dn->inode, dn->nid);
 
-       dn->node_page = page;
-       if (ipage)
-               update_inode(dn->inode, ipage);
-       else
-               sync_inode_page(dn);
        if (ofs == 0)
                inc_valid_inode_count(sbi);
-
        return page;
 
 fail:
@@ -1149,16 +1147,21 @@ repeat:
 
        lock_page(page);
 
-       if (unlikely(!PageUptodate(page))) {
-               f2fs_put_page(page, 1);
-               return ERR_PTR(-EIO);
-       }
        if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
                f2fs_put_page(page, 1);
                goto repeat;
        }
+
+       if (unlikely(!PageUptodate(page)))
+               goto out_err;
 page_hit:
-       f2fs_bug_on(sbi, nid != nid_of_node(page));
+       if(unlikely(nid != nid_of_node(page))) {
+               f2fs_bug_on(sbi, 1);
+               ClearPageUptodate(page);
+out_err:
+               f2fs_put_page(page, 1);
+               return ERR_PTR(-EIO);
+       }
        return page;
 }
 
@@ -1175,24 +1178,6 @@ struct page *get_node_page_ra(struct page *parent, int start)
        return __get_node_page(sbi, nid, parent, start);
 }
 
-void sync_inode_page(struct dnode_of_data *dn)
-{
-       int ret = 0;
-
-       if (IS_INODE(dn->node_page) || dn->inode_page == dn->node_page) {
-               ret = update_inode(dn->inode, dn->node_page);
-       } else if (dn->inode_page) {
-               if (!dn->inode_page_locked)
-                       lock_page(dn->inode_page);
-               ret = update_inode(dn->inode, dn->inode_page);
-               if (!dn->inode_page_locked)
-                       unlock_page(dn->inode_page);
-       } else {
-               ret = update_inode_page(dn->inode);
-       }
-       dn->node_changed = ret ? true: false;
-}
-
 static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino)
 {
        struct inode *inode;
@@ -1318,7 +1303,7 @@ continue_unlock:
        return last_page;
 }
 
-int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino,
+int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
                        struct writeback_control *wbc, bool atomic)
 {
        pgoff_t index, end;
@@ -1326,6 +1311,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino,
        int ret = 0;
        struct page *last_page = NULL;
        bool marked = false;
+       nid_t ino = inode->i_ino;
 
        if (atomic) {
                last_page = last_fsync_dnode(sbi, ino);
@@ -1379,9 +1365,13 @@ continue_unlock:
 
                        if (!atomic || page == last_page) {
                                set_fsync_mark(page, 1);
-                               if (IS_INODE(page))
+                               if (IS_INODE(page)) {
+                                       if (is_inode_flag_set(inode,
+                                                               FI_DIRTY_INODE))
+                                               update_inode(inode, page);
                                        set_dentry_mark(page,
                                                need_dentry_mark(sbi, ino));
+                               }
                                /*  may be written by other thread */
                                if (!PageDirty(page))
                                        set_page_dirty(page);
@@ -1655,9 +1645,10 @@ static int f2fs_set_node_page_dirty(struct page *page)
 {
        trace_f2fs_set_page_dirty(page, NODE);
 
-       SetPageUptodate(page);
+       if (!PageUptodate(page))
+               SetPageUptodate(page);
        if (!PageDirty(page)) {
-               __set_page_dirty_nobuffers(page);
+               f2fs_set_page_dirty_nobuffers(page);
                inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES);
                SetPagePrivate(page);
                f2fs_trace_pid(page);
@@ -1776,7 +1767,7 @@ static void scan_nat_page(struct f2fs_sb_info *sbi,
        }
 }
 
-static void build_free_nids(struct f2fs_sb_info *sbi)
+void build_free_nids(struct f2fs_sb_info *sbi)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
@@ -1785,7 +1776,7 @@ static void build_free_nids(struct f2fs_sb_info *sbi)
        nid_t nid = nm_i->next_scan_nid;
 
        /* Enough entries */
-       if (nm_i->fcnt > NAT_ENTRY_PER_BLOCK)
+       if (nm_i->fcnt >= NAT_ENTRY_PER_BLOCK)
                return;
 
        /* readahead nat pages to be scanned */
@@ -1923,12 +1914,15 @@ int try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink)
        struct free_nid *i, *next;
        int nr = nr_shrink;
 
+       if (nm_i->fcnt <= MAX_FREE_NIDS)
+               return 0;
+
        if (!mutex_trylock(&nm_i->build_lock))
                return 0;
 
        spin_lock(&nm_i->free_nid_list_lock);
        list_for_each_entry_safe(i, next, &nm_i->free_nid_list, list) {
-               if (nr_shrink <= 0 || nm_i->fcnt <= NAT_ENTRY_PER_BLOCK)
+               if (nr_shrink <= 0 || nm_i->fcnt <= MAX_FREE_NIDS)
                        break;
                if (i->state == NID_ALLOC)
                        continue;
@@ -1955,7 +1949,7 @@ void recover_inline_xattr(struct inode *inode, struct page *page)
 
        ri = F2FS_INODE(page);
        if (!(ri->i_inline & F2FS_INLINE_XATTR)) {
-               clear_inode_flag(F2FS_I(inode), FI_INLINE_XATTR);
+               clear_inode_flag(inode, FI_INLINE_XATTR);
                goto update_inode;
        }
 
@@ -1997,13 +1991,11 @@ recover_xnid:
        get_node_info(sbi, new_xnid, &ni);
        ni.ino = inode->i_ino;
        set_node_addr(sbi, &ni, NEW_ADDR, false);
-       F2FS_I(inode)->i_xattr_nid = new_xnid;
+       f2fs_i_xnid_write(inode, new_xnid);
 
        /* 3: update xattr blkaddr */
        refresh_sit_entry(sbi, NEW_ADDR, blkaddr);
        set_node_addr(sbi, &ni, blkaddr, false);
-
-       update_inode_page(inode);
 }
 
 int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
@@ -2025,7 +2017,8 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
        /* Should not use this inode from free nid list */
        remove_free_nid(NM_I(sbi), ino);
 
-       SetPageUptodate(ipage);
+       if (!PageUptodate(ipage))
+               SetPageUptodate(ipage);
        fill_node_footer(ipage, ino, ino, 0, true);
 
        src = F2FS_INODE(page);
This page took 0.034854 seconds and 5 git commands to generate.