aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-09-12 18:53:45 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-09-16 07:10:39 -0400
commita7ffdbe22cecaed59b5d76a5f003d68907d64240 (patch)
tree455b985cab6761423687153ca36aae86058a2fa8 /fs
parent2403c155b83c09d8b6255237ef049f2650f9fe01 (diff)
f2fs: expand counting dirty pages in the inode page cache
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/checkpoint.c16
-rw-r--r--fs/f2fs/data.c16
-rw-r--r--fs/f2fs/dir.c2
-rw-r--r--fs/f2fs/f2fs.h25
-rw-r--r--fs/f2fs/gc.c2
-rw-r--r--fs/f2fs/inode.c2
-rw-r--r--fs/f2fs/super.c2
7 files changed, 39 insertions, 26 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 935a56e03bf6..5af7e3d1bb6e 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -627,27 +627,33 @@ static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)
627 return 0; 627 return 0;
628} 628}
629 629
630void set_dirty_dir_page(struct inode *inode, struct page *page) 630void update_dirty_page(struct inode *inode, struct page *page)
631{ 631{
632 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 632 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
633 struct dir_inode_entry *new; 633 struct dir_inode_entry *new;
634 int ret = 0; 634 int ret = 0;
635 635
636 if (!S_ISDIR(inode->i_mode)) 636 if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
637 return; 637 return;
638 638
639 if (!S_ISDIR(inode->i_mode)) {
640 inode_inc_dirty_pages(inode);
641 goto out;
642 }
643
639 new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); 644 new = f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
640 new->inode = inode; 645 new->inode = inode;
641 INIT_LIST_HEAD(&new->list); 646 INIT_LIST_HEAD(&new->list);
642 647
643 spin_lock(&sbi->dir_inode_lock); 648 spin_lock(&sbi->dir_inode_lock);
644 ret = __add_dirty_inode(inode, new); 649 ret = __add_dirty_inode(inode, new);
645 inode_inc_dirty_dents(inode); 650 inode_inc_dirty_pages(inode);
646 SetPagePrivate(page);
647 spin_unlock(&sbi->dir_inode_lock); 651 spin_unlock(&sbi->dir_inode_lock);
648 652
649 if (ret) 653 if (ret)
650 kmem_cache_free(inode_entry_slab, new); 654 kmem_cache_free(inode_entry_slab, new);
655out:
656 SetPagePrivate(page);
651} 657}
652 658
653void add_dirty_dir_inode(struct inode *inode) 659void add_dirty_dir_inode(struct inode *inode)
@@ -677,7 +683,7 @@ void remove_dirty_dir_inode(struct inode *inode)
677 return; 683 return;
678 684
679 spin_lock(&sbi->dir_inode_lock); 685 spin_lock(&sbi->dir_inode_lock);
680 if (get_dirty_dents(inode) || 686 if (get_dirty_pages(inode) ||
681 !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) { 687 !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) {
682 spin_unlock(&sbi->dir_inode_lock); 688 spin_unlock(&sbi->dir_inode_lock);
683 return; 689 return;
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 64d855085edf..0e376585e29f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -843,7 +843,7 @@ write:
843 if (unlikely(f2fs_cp_error(sbi))) { 843 if (unlikely(f2fs_cp_error(sbi))) {
844 SetPageError(page); 844 SetPageError(page);
845 unlock_page(page); 845 unlock_page(page);
846 return 0; 846 goto out;
847 } 847 }
848 848
849 if (!wbc->for_reclaim) 849 if (!wbc->for_reclaim)
@@ -863,7 +863,7 @@ done:
863 863
864 clear_cold_data(page); 864 clear_cold_data(page);
865out: 865out:
866 inode_dec_dirty_dents(inode); 866 inode_dec_dirty_pages(inode);
867 unlock_page(page); 867 unlock_page(page);
868 if (need_balance_fs) 868 if (need_balance_fs)
869 f2fs_balance_fs(sbi); 869 f2fs_balance_fs(sbi);
@@ -901,7 +901,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
901 return 0; 901 return 0;
902 902
903 if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE && 903 if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
904 get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA) && 904 get_dirty_pages(inode) < nr_pages_to_skip(sbi, DATA) &&
905 available_free_memory(sbi, DIRTY_DENTS)) 905 available_free_memory(sbi, DIRTY_DENTS))
906 goto skip_write; 906 goto skip_write;
907 907
@@ -923,7 +923,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
923 return ret; 923 return ret;
924 924
925skip_write: 925skip_write:
926 wbc->pages_skipped += get_dirty_dents(inode); 926 wbc->pages_skipped += get_dirty_pages(inode);
927 return 0; 927 return 0;
928} 928}
929 929
@@ -1107,8 +1107,12 @@ static void f2fs_invalidate_data_page(struct page *page, unsigned int offset,
1107 unsigned int length) 1107 unsigned int length)
1108{ 1108{
1109 struct inode *inode = page->mapping->host; 1109 struct inode *inode = page->mapping->host;
1110
1111 if (offset % PAGE_CACHE_SIZE || length != PAGE_CACHE_SIZE)
1112 return;
1113
1110 if (PageDirty(page)) 1114 if (PageDirty(page))
1111 inode_dec_dirty_dents(inode); 1115 inode_dec_dirty_pages(inode);
1112 ClearPagePrivate(page); 1116 ClearPagePrivate(page);
1113} 1117}
1114 1118
@@ -1130,7 +1134,7 @@ static int f2fs_set_data_page_dirty(struct page *page)
1130 1134
1131 if (!PageDirty(page)) { 1135 if (!PageDirty(page)) {
1132 __set_page_dirty_nobuffers(page); 1136 __set_page_dirty_nobuffers(page);
1133 set_dirty_dir_page(inode, page); 1137 update_dirty_page(inode, page);
1134 return 1; 1138 return 1;
1135 } 1139 }
1136 return 0; 1140 return 0;
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index f1ceeb2f898e..b54f87149c09 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -618,7 +618,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
618 truncate_hole(dir, page->index, page->index + 1); 618 truncate_hole(dir, page->index, page->index + 1);
619 clear_page_dirty_for_io(page); 619 clear_page_dirty_for_io(page);
620 ClearPageUptodate(page); 620 ClearPageUptodate(page);
621 inode_dec_dirty_dents(dir); 621 inode_dec_dirty_pages(dir);
622 } 622 }
623 f2fs_put_page(page, 1); 623 f2fs_put_page(page, 1);
624} 624}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 1def9eeedbf1..ad7e9b369319 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -237,7 +237,7 @@ struct f2fs_inode_info {
237 /* Use below internally in f2fs*/ 237 /* Use below internally in f2fs*/
238 unsigned long flags; /* use to pass per-file flags */ 238 unsigned long flags; /* use to pass per-file flags */
239 struct rw_semaphore i_sem; /* protect fi info */ 239 struct rw_semaphore i_sem; /* protect fi info */
240 atomic_t dirty_dents; /* # of dirty dentry pages */ 240 atomic_t dirty_pages; /* # of dirty pages */
241 f2fs_hash_t chash; /* hash value of given file name */ 241 f2fs_hash_t chash; /* hash value of given file name */
242 unsigned int clevel; /* maximum level of given file name */ 242 unsigned int clevel; /* maximum level of given file name */
243 nid_t i_xattr_nid; /* node id that contains xattrs */ 243 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)
747 F2FS_SET_SB_DIRT(sbi); 747 F2FS_SET_SB_DIRT(sbi);
748} 748}
749 749
750static inline void inode_inc_dirty_dents(struct inode *inode) 750static inline void inode_inc_dirty_pages(struct inode *inode)
751{ 751{
752 inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS); 752 atomic_inc(&F2FS_I(inode)->dirty_pages);
753 atomic_inc(&F2FS_I(inode)->dirty_dents); 753 if (S_ISDIR(inode->i_mode))
754 inc_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
754} 755}
755 756
756static inline void dec_page_count(struct f2fs_sb_info *sbi, int count_type) 757static 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)
758 atomic_dec(&sbi->nr_pages[count_type]); 759 atomic_dec(&sbi->nr_pages[count_type]);
759} 760}
760 761
761static inline void inode_dec_dirty_dents(struct inode *inode) 762static inline void inode_dec_dirty_pages(struct inode *inode)
762{ 763{
763 if (!S_ISDIR(inode->i_mode)) 764 if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
764 return; 765 return;
765 766
766 dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS); 767 atomic_dec(&F2FS_I(inode)->dirty_pages);
767 atomic_dec(&F2FS_I(inode)->dirty_dents); 768
769 if (S_ISDIR(inode->i_mode))
770 dec_page_count(F2FS_I_SB(inode), F2FS_DIRTY_DENTS);
768} 771}
769 772
770static inline int get_pages(struct f2fs_sb_info *sbi, int count_type) 773static 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)
772 return atomic_read(&sbi->nr_pages[count_type]); 775 return atomic_read(&sbi->nr_pages[count_type]);
773} 776}
774 777
775static inline int get_dirty_dents(struct inode *inode) 778static inline int get_dirty_pages(struct inode *inode)
776{ 779{
777 return atomic_read(&F2FS_I(inode)->dirty_dents); 780 return atomic_read(&F2FS_I(inode)->dirty_pages);
778} 781}
779 782
780static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type) 783static 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);
1302void remove_orphan_inode(struct f2fs_sb_info *, nid_t); 1305void remove_orphan_inode(struct f2fs_sb_info *, nid_t);
1303void recover_orphan_inodes(struct f2fs_sb_info *); 1306void recover_orphan_inodes(struct f2fs_sb_info *);
1304int get_valid_checkpoint(struct f2fs_sb_info *); 1307int get_valid_checkpoint(struct f2fs_sb_info *);
1305void set_dirty_dir_page(struct inode *, struct page *); 1308void update_dirty_page(struct inode *, struct page *);
1306void add_dirty_dir_inode(struct inode *); 1309void add_dirty_dir_inode(struct inode *);
1307void remove_dirty_dir_inode(struct inode *); 1310void remove_dirty_dir_inode(struct inode *);
1308void sync_dirty_dir_inodes(struct f2fs_sb_info *); 1311void sync_dirty_dir_inodes(struct f2fs_sb_info *);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 075ea1eb8fa0..dca7818c0662 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -537,7 +537,7 @@ static void move_data_page(struct inode *inode, struct page *page, int gc_type)
537 f2fs_wait_on_page_writeback(page, DATA); 537 f2fs_wait_on_page_writeback(page, DATA);
538 538
539 if (clear_page_dirty_for_io(page)) 539 if (clear_page_dirty_for_io(page))
540 inode_dec_dirty_dents(inode); 540 inode_dec_dirty_pages(inode);
541 set_cold_data(page); 541 set_cold_data(page);
542 do_write_data_page(page, &fio); 542 do_write_data_page(page, &fio);
543 clear_cold_data(page); 543 clear_cold_data(page);
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index 95c0bc2a666c..ff95547cfc3d 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -276,7 +276,7 @@ void f2fs_evict_inode(struct inode *inode)
276 inode->i_ino == F2FS_META_INO(sbi)) 276 inode->i_ino == F2FS_META_INO(sbi))
277 goto out_clear; 277 goto out_clear;
278 278
279 f2fs_bug_on(sbi, get_dirty_dents(inode)); 279 f2fs_bug_on(sbi, get_dirty_pages(inode));
280 remove_dirty_dir_inode(inode); 280 remove_dirty_dir_inode(inode);
281 281
282 if (inode->i_nlink || is_bad_inode(inode)) 282 if (inode->i_nlink || is_bad_inode(inode))
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 3275e733b28e..b5af9be94a4d 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -366,7 +366,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
366 366
367 /* Initialize f2fs-specific inode info */ 367 /* Initialize f2fs-specific inode info */
368 fi->vfs_inode.i_version = 1; 368 fi->vfs_inode.i_version = 1;
369 atomic_set(&fi->dirty_dents, 0); 369 atomic_set(&fi->dirty_pages, 0);
370 fi->i_current_depth = 1; 370 fi->i_current_depth = 1;
371 fi->i_advise = 0; 371 fi->i_advise = 0;
372 rwlock_init(&fi->ext.ext_lock); 372 rwlock_init(&fi->ext.ext_lock);