Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddd52a4e authored by Daeho Jeong's avatar Daeho Jeong Committed by Jaegeuk Kim
Browse files

f2fs: clear radix tree dirty tag of pages whose dirty flag is cleared



commit 0abd8e70d24b665dd00972d4a259e05528cbf4c6 upstream.

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: default avatarDaeho Jeong <daeho.jeong@samsung.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 55828d6e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);
+7 −0
Original line number Diff line number Diff line
@@ -220,6 +220,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);
@@ -241,6 +243,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);

+1 −0
Original line number Diff line number Diff line
@@ -310,6 +310,7 @@ struct address_space *page_mapping(struct page *page)
		mapping = NULL;
	return mapping;
}
EXPORT_SYMBOL(page_mapping);

int overcommit_ratio_handler(struct ctl_table *table, int write,
			     void __user *buffer, size_t *lenp,