diff options
author | Chao Yu <chao2.yu@samsung.com> | 2015-12-16 00:09:20 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-12-16 11:58:12 -0500 |
commit | c227f912732f204c0ec4a577ba812401ac4672af (patch) | |
tree | 86bb9eb87ccf717cbe486d1d1b7e0eab31e10cbc /fs/f2fs/checkpoint.c | |
parent | b3980910f746d885111db7252f664600de2a5ea3 (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.c | 66 |
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 | ||
725 | static void __add_dirty_inode(struct inode *inode) | 725 | static 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 | ||
739 | static void __remove_dirty_inode(struct inode *inode) | 740 | static 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 | ||
753 | void update_dirty_page(struct inode *inode, struct page *page) | 756 | void 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 | ||
771 | out: | ||
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 | ||
785 | void remove_dirty_dir_inode(struct inode *inode) | 783 | void 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 | ||
804 | void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) | 804 | void 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; |