aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/checkpoint.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-12-16 00:09:20 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2015-12-16 11:58:12 -0500
commitc227f912732f204c0ec4a577ba812401ac4672af (patch)
tree86bb9eb87ccf717cbe486d1d1b7e0eab31e10cbc /fs/f2fs/checkpoint.c
parentb3980910f746d885111db7252f664600de2a5ea3 (diff)
f2fs: record dirty status of regular/symlink inode
Maintain regular/symlink inode which has dirty pages in global dirty list and record their total dirty pages count like the way of handling directory inode. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r--fs/f2fs/checkpoint.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5008b872f316..a037bbd89dc6 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -722,53 +722,51 @@ fail_no_cp:
722 return -EINVAL; 722 return -EINVAL;
723} 723}
724 724
725static void __add_dirty_inode(struct inode *inode) 725static void __add_dirty_inode(struct inode *inode, enum inode_type type)
726{ 726{
727 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 727 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
728 struct f2fs_inode_info *fi = F2FS_I(inode); 728 struct f2fs_inode_info *fi = F2FS_I(inode);
729 int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE;
729 730
730 if (is_inode_flag_set(fi, FI_DIRTY_DIR)) 731 if (is_inode_flag_set(fi, flag))
731 return; 732 return;
732 733
733 set_inode_flag(fi, FI_DIRTY_DIR); 734 set_inode_flag(fi, flag);
734 list_add_tail(&fi->dirty_list, &sbi->dir_inode_list); 735 list_add_tail(&fi->dirty_list, &sbi->inode_list[type]);
735 stat_inc_dirty_dir(sbi); 736 if (type == DIR_INODE)
736 return; 737 stat_inc_dirty_dir(sbi);
737} 738}
738 739
739static void __remove_dirty_inode(struct inode *inode) 740static void __remove_dirty_inode(struct inode *inode, enum inode_type type)
740{ 741{
741 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 742 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
742 struct f2fs_inode_info *fi = F2FS_I(inode); 743 struct f2fs_inode_info *fi = F2FS_I(inode);
744 int flag = (type == DIR_INODE) ? FI_DIRTY_DIR : FI_DIRTY_FILE;
743 745
744 if (get_dirty_pages(inode) || 746 if (get_dirty_pages(inode) ||
745 !is_inode_flag_set(F2FS_I(inode), FI_DIRTY_DIR)) 747 !is_inode_flag_set(F2FS_I(inode), flag))
746 return; 748 return;
747 749
748 list_del_init(&fi->dirty_list); 750 list_del_init(&fi->dirty_list);
749 clear_inode_flag(fi, FI_DIRTY_DIR); 751 clear_inode_flag(fi, flag);
750 stat_dec_dirty_dir(sbi); 752 if (type == DIR_INODE)
753 stat_dec_dirty_dir(sbi);
751} 754}
752 755
753void update_dirty_page(struct inode *inode, struct page *page) 756void update_dirty_page(struct inode *inode, struct page *page)
754{ 757{
755 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 758 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
759 enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
756 760
757 if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) && 761 if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
758 !S_ISLNK(inode->i_mode)) 762 !S_ISLNK(inode->i_mode))
759 return; 763 return;
760 764
761 if (!S_ISDIR(inode->i_mode)) { 765 spin_lock(&sbi->inode_lock[type]);
762 inode_inc_dirty_pages(inode); 766 __add_dirty_inode(inode, type);
763 goto out;
764 }
765
766 spin_lock(&sbi->dir_inode_lock);
767 __add_dirty_inode(inode);
768 inode_inc_dirty_pages(inode); 767 inode_inc_dirty_pages(inode);
769 spin_unlock(&sbi->dir_inode_lock); 768 spin_unlock(&sbi->inode_lock[type]);
770 769
771out:
772 SetPagePrivate(page); 770 SetPagePrivate(page);
773 f2fs_trace_pid(page); 771 f2fs_trace_pid(page);
774} 772}
@@ -777,22 +775,24 @@ void add_dirty_dir_inode(struct inode *inode)
777{ 775{
778 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 776 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
779 777
780 spin_lock(&sbi->dir_inode_lock); 778 spin_lock(&sbi->inode_lock[DIR_INODE]);
781 __add_dirty_inode(inode); 779 __add_dirty_inode(inode, DIR_INODE);
782 spin_unlock(&sbi->dir_inode_lock); 780 spin_unlock(&sbi->inode_lock[DIR_INODE]);
783} 781}
784 782
785void remove_dirty_dir_inode(struct inode *inode) 783void remove_dirty_inode(struct inode *inode)
786{ 784{
787 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 785 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
788 struct f2fs_inode_info *fi = F2FS_I(inode); 786 struct f2fs_inode_info *fi = F2FS_I(inode);
787 enum inode_type type = S_ISDIR(inode->i_mode) ? DIR_INODE : FILE_INODE;
789 788
790 if (!S_ISDIR(inode->i_mode)) 789 if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) &&
790 !S_ISLNK(inode->i_mode))
791 return; 791 return;
792 792
793 spin_lock(&sbi->dir_inode_lock); 793 spin_lock(&sbi->inode_lock[type]);
794 __remove_dirty_inode(inode); 794 __remove_dirty_inode(inode, type);
795 spin_unlock(&sbi->dir_inode_lock); 795 spin_unlock(&sbi->inode_lock[type]);
796 796
797 /* Only from the recovery routine */ 797 /* Only from the recovery routine */
798 if (is_inode_flag_set(fi, FI_DELAY_IPUT)) { 798 if (is_inode_flag_set(fi, FI_DELAY_IPUT)) {
@@ -801,7 +801,7 @@ void remove_dirty_dir_inode(struct inode *inode)
801 } 801 }
802} 802}
803 803
804void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) 804void sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
805{ 805{
806 struct list_head *head; 806 struct list_head *head;
807 struct inode *inode; 807 struct inode *inode;
@@ -810,16 +810,16 @@ retry:
810 if (unlikely(f2fs_cp_error(sbi))) 810 if (unlikely(f2fs_cp_error(sbi)))
811 return; 811 return;
812 812
813 spin_lock(&sbi->dir_inode_lock); 813 spin_lock(&sbi->inode_lock[type]);
814 814
815 head = &sbi->dir_inode_list; 815 head = &sbi->inode_list[type];
816 if (list_empty(head)) { 816 if (list_empty(head)) {
817 spin_unlock(&sbi->dir_inode_lock); 817 spin_unlock(&sbi->inode_lock[type]);
818 return; 818 return;
819 } 819 }
820 fi = list_entry(head->next, struct f2fs_inode_info, dirty_list); 820 fi = list_entry(head->next, struct f2fs_inode_info, dirty_list);
821 inode = igrab(&fi->vfs_inode); 821 inode = igrab(&fi->vfs_inode);
822 spin_unlock(&sbi->dir_inode_lock); 822 spin_unlock(&sbi->inode_lock[type]);
823 if (inode) { 823 if (inode) {
824 filemap_fdatawrite(inode->i_mapping); 824 filemap_fdatawrite(inode->i_mapping);
825 iput(inode); 825 iput(inode);
@@ -854,7 +854,7 @@ retry_flush_dents:
854 /* write all the dirty dentry pages */ 854 /* write all the dirty dentry pages */
855 if (get_pages(sbi, F2FS_DIRTY_DENTS)) { 855 if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
856 f2fs_unlock_all(sbi); 856 f2fs_unlock_all(sbi);
857 sync_dirty_dir_inodes(sbi); 857 sync_dirty_inodes(sbi, DIR_INODE);
858 if (unlikely(f2fs_cp_error(sbi))) { 858 if (unlikely(f2fs_cp_error(sbi))) {
859 err = -EIO; 859 err = -EIO;
860 goto out; 860 goto out;