f2fs: expand counting dirty pages in the inode page cache
authorJaegeuk Kim <jaegeuk@kernel.org>
Fri, 12 Sep 2014 22:53:45 +0000 (15:53 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 16 Sep 2014 11:10:39 +0000 (04:10 -0700)
Previously f2fs only counts dirty dentry pages, but there is no reason not to
expand the scope.

This patch changes the names on the management of dirty pages and to count
dirty pages in each inode info as well.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/gc.c
fs/f2fs/inode.c
fs/f2fs/super.c

index 935a56e03bf62cad6641bc4f04538d94078f5180..5af7e3d1bb6e46b354e20b81d18733b185543b11 100644 (file)
@@ -627,27 +627,33 @@ static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)
        return 0;
 }
 
-void set_dirty_dir_page(struct inode *inode, struct page *page)
+void update_dirty_page(struct inode *inode, struct page *page)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct dir_inode_entry *new;
        int ret = 0;
 
-       if (!S_ISDIR(inode->i_mode))
+       if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
                return;
 
+       if (!S_ISDIR(inode->i_mode)) {
+               inode_inc_dirty_pages(inode);
+               goto out;
+       }
+
        new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
        new->inode = inode;
        INIT_LIST_HEAD(&new->list);
 
        spin_lock(&sbi->dir_inode_lock);
        ret = __add_dirty_inode(inode, new);
-       inode_inc_dirty_dents(inode);
-       SetPagePrivate(page);
+       inode_inc_dirty_pages(inode);
        spin_unlock(&sbi->dir_inode_lock);
 
        if (ret)
                kmem_cache_free(inode_entry_slab, new);
+out:
+       SetPagePrivate(page);
 }
 
 void add_dirty_dir_inode(struct inode *inode)
@@ -677,7 +683,7 @@ void remove_dirty_dir_inode(struct inode *inode)
                return;
 
        spin_lock(&sbi->dir_inode_lock);
-       if (get_dirty_dents(inode) ||
+       if (get_dirty_pages(inode) ||
                        !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) {
                spin_unlock(&sbi->dir_inode_lock);
                return;
index 64d855085edf7ad360876c90201be0920b044e19..0e376585e29f43b8913d204353303de31b9402c6 100644 (file)
@@ -843,7 +843,7 @@ write:
        if (unlikely(f2fs_cp_error(sbi))) {
                SetPageError(page);
                unlock_page(page);
-               return 0;
+               goto out;
        }
 
        if (!wbc->for_reclaim)
@@ -863,7 +863,7 @@ done:
 
        clear_cold_data(page);
 out:
-       inode_dec_dirty_dents(inode);
+       inode_dec_dirty_pages(inode);
        unlock_page(page);
        if (need_balance_fs)
                f2fs_balance_fs(sbi);
@@ -901,7 +901,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
                return 0;
 
        if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
-                       get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA) &&
+                       get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
                        available_free_memory(sbi, DIRTY_DENTS))
                goto skip_write;
 
@@ -923,7 +923,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
        return ret;
 
 skip_write:
-       wbc->pages_skipped += get_dirty_dents(inode);
+       wbc->pages_skipped += get_dirty_pages(inode);
        return 0;
 }
 
@@ -1107,8 +1107,12 @@ static void f2fs_invalidate_data_page(struct page *page, unsigned int offset,
                                      unsigned int length)
 {
        struct inode *inode = page->mapping->host;
+
+       if (offset % PAGE_CACHE_SIZE || length != PAGE_CACHE_SIZE)
+               return;
+
        if (PageDirty(page))
-               inode_dec_dirty_dents(inode);
+               inode_dec_dirty_pages(inode);
        ClearPagePrivate(page);
 }
 
@@ -1130,7 +1134,7 @@ static int f2fs_set_data_page_dirty(struct page *page)
 
        if (!PageDirty(page)) {
                __set_page_dirty_nobuffers(page);
-               set_dirty_dir_page(inode, page);
+               update_dirty_page(inode, page);
                return 1;
        }
        return 0;
index f1ceeb2f898e93549b1793cfd1544ba78fc3ab66..b54f87149c09a5a0ecc6e96d72af9096362573a6 100644 (file)
@@ -618,7 +618,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
                truncate_hole(dir, page->index, page->index + 1);
                clear_page_dirty_for_io(page);
                ClearPageUptodate(page);
-               inode_dec_dirty_dents(dir);
+               inode_dec_dirty_pages(dir);
        }
        f2fs_put_page(page, 1);
 }
index 1def9eeedbf15a2fb78eb9f55291891b3faedbe2..ad7e9b369319768799b85b0d7f25b7476f275570 100644 (file)
@@ -237,7 +237,7 @@ struct f2fs_inode_info {
        /* Use below internally in f2fs*/
        unsigned long flags;            /* use to pass per-file flags */
        struct rw_semaphore i_sem;      /* protect fi info */
-       atomic_t dirty_dents;           /* # of dirty dentry pages */
+       atomic_t dirty_pages;           /* # of dirty pages */
        f2fs_hash_t chash;              /* hash value of given file name */
        unsigned int clevel;            /* maximum level of given file name */
        nid_t i_xattr_nid;              /* node id that contains xattrs */
@@ -747,10 +747,11 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
        F2FS_SET_SB_DIRT(sbi);
 }
 
-static inline void inode_inc_dirty_dents(struct inode *inode)
+static inline void inode_inc_dirty_pages(struct inode *inode)
 {
-       inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
-       atomic_inc(&F2FS_I(inode)->dirty_dents);
+       atomic_inc(&F2FS_I(inode)->dirty_pages);
+       if (S_ISDIR(inode->i_mode))
+               inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
 }
 
 static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
@@ -758,13 +759,15 @@ static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type)
        atomic_dec(&sbi->nr_pages[count_type]);
 }
 
-static inline void inode_dec_dirty_dents(struct inode *inode)
+static inline void inode_dec_dirty_pages(struct inode *inode)
 {
-       if (!S_ISDIR(inode->i_mode))
+       if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
                return;
 
-       dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
-       atomic_dec(&F2FS_I(inode)->dirty_dents);
+       atomic_dec(&F2FS_I(inode)->dirty_pages);
+
+       if (S_ISDIR(inode->i_mode))
+               dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
 }
 
 static inline int get_pages(struct f2fs_sb_info *sbi, int count_type)
@@ -772,9 +775,9 @@ static inline int get_pages(struct f2fs_sb_info *sbi, int count_type)
        return atomic_read(&sbi->nr_pages[count_type]);
 }
 
-static inline int get_dirty_dents(struct inode *inode)
+static inline int get_dirty_pages(struct inode *inode)
 {
-       return atomic_read(&F2FS_I(inode)->dirty_dents);
+       return atomic_read(&F2FS_I(inode)->dirty_pages);
 }
 
 static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
@@ -1302,7 +1305,7 @@ void add_orphan_inode(struct f2fs_sb_info *, nid_t);
 void remove_orphan_inode(struct f2fs_sb_info *, nid_t);
 void recover_orphan_inodes(struct f2fs_sb_info *);
 int get_valid_checkpoint(struct f2fs_sb_info *);
-void set_dirty_dir_page(struct inode *, struct page *);
+void update_dirty_page(struct inode *, struct page *);
 void add_dirty_dir_inode(struct inode *);
 void remove_dirty_dir_inode(struct inode *);
 void sync_dirty_dir_inodes(struct f2fs_sb_info *);
index 075ea1eb8fa0bad28317c103ae2bbbbad7db0dfa..dca7818c06627a03a2cc45c13c41b0b3a1c4fece 100644 (file)
@@ -537,7 +537,7 @@ static void move_data_page(struct inode *inode, struct page *page, int gc_type)
                f2fs_wait_on_page_writeback(page, DATA);
 
                if (clear_page_dirty_for_io(page))
-                       inode_dec_dirty_dents(inode);
+                       inode_dec_dirty_pages(inode);
                set_cold_data(page);
                do_write_data_page(page, &fio);
                clear_cold_data(page);
index 95c0bc2a666ca3fdb40f42c717386f0ae223c239..ff95547cfc3dcaf0753a2525934b600ad3530ac3 100644 (file)
@@ -276,7 +276,7 @@ void f2fs_evict_inode(struct inode *inode)
                        inode->i_ino == F2FS_META_INO(sbi))
                goto out_clear;
 
-       f2fs_bug_on(sbi, get_dirty_dents(inode));
+       f2fs_bug_on(sbi, get_dirty_pages(inode));
        remove_dirty_dir_inode(inode);
 
        if (inode->i_nlink || is_bad_inode(inode))
index 3275e733b28eba6093976fa14e80ab77e2235abe..b5af9be94a4da72298df808f9c5a72e6848bc2e3 100644 (file)
@@ -366,7 +366,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
 
        /* Initialize f2fs-specific inode info */
        fi->vfs_inode.i_version = 1;
-       atomic_set(&fi->dirty_dents, 0);
+       atomic_set(&fi->dirty_pages, 0);
        fi->i_current_depth = 1;
        fi->i_advise = 0;
        rwlock_init(&fi->ext.ext_lock);