]> git.baikalelectronics.ru Git - kernel.git/commitdiff
f2fs: clear radix tree dirty tag of pages whose dirty flag is cleared
authorDaeho Jeong <daeho.jeong@samsung.com>
Mon, 11 Sep 2017 07:30:28 +0000 (16:30 +0900)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 12 Sep 2017 04:32:38 +0000 (21:32 -0700)
On a senario like writing out the first dirty page of the inode
as the inline data, we only cleared dirty flags of the pages, but
didn't clear the dirty tags of those pages in the radix tree.

If we don't clear the dirty tags of the pages in the radix tree, the
inodes which contain the pages will be marked with I_DIRTY_PAGES again
and again, and writepages() for the inodes will be invoked in every
writeback period. As a result, nothing will be done in every
writepages() for the inodes and it will just consume CPU time
meaninglessly.

Signed-off-by: Daeho Jeong <daeho.jeong@samsung.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/dir.c
fs/f2fs/inline.c

index 37f9c7f556058fcda91b15b411acfeebdf48824d..c0c933ad43c8dce1910fe18615def9c96853bacb 100644 (file)
@@ -705,6 +705,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
        struct  f2fs_dentry_block *dentry_blk;
        unsigned int bit_pos;
        int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
+       struct address_space *mapping = page_mapping(page);
+       unsigned long flags;
        int i;
 
        f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
@@ -735,6 +737,11 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 
        if (bit_pos == NR_DENTRY_IN_BLOCK &&
                        !truncate_hole(dir, page->index, page->index + 1)) {
+               spin_lock_irqsave(&mapping->tree_lock, flags);
+               radix_tree_tag_clear(&mapping->page_tree, page_index(page),
+                                    PAGECACHE_TAG_DIRTY);
+               spin_unlock_irqrestore(&mapping->tree_lock, flags);
+
                clear_page_dirty_for_io(page);
                ClearPagePrivate(page);
                ClearPageUptodate(page);
index c133a4fdecf62d855a4d749bd31f8a9b4f80c36f..8322e4e7bb3fc432aabc8067b7ab459274c6d326 100644 (file)
@@ -202,6 +202,8 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
 {
        void *src_addr, *dst_addr;
        struct dnode_of_data dn;
+       struct address_space *mapping = page_mapping(page);
+       unsigned long flags;
        int err;
 
        set_new_dnode(&dn, inode, NULL, NULL, 0);
@@ -223,6 +225,11 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
        kunmap_atomic(src_addr);
        set_page_dirty(dn.inode_page);
 
+       spin_lock_irqsave(&mapping->tree_lock, flags);
+       radix_tree_tag_clear(&mapping->page_tree, page_index(page),
+                            PAGECACHE_TAG_DIRTY);
+       spin_unlock_irqrestore(&mapping->tree_lock, flags);
+
        set_inode_flag(inode, FI_APPEND_WRITE);
        set_inode_flag(inode, FI_DATA_EXIST);