mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
f2fs: fix to mitigate overhead of f2fs_zero_post_eof_page()
[ Upstream commit c2f7c32b254006ad48f8e4efb2e7e7bf71739f17 ]
f2fs_zero_post_eof_page() may cuase more overhead due to invalidate_lock
and page lookup, change as below to mitigate its overhead:
- check new_size before grabbing invalidate_lock
- lookup and invalidate pages only in range of [old_size, new_size]
Fixes: ba8dac350faf ("f2fs: fix to zero post-eof page")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
83a8e4efea
commit
7d9b97e613
@@ -36,15 +36,23 @@
|
||||
#include <trace/events/f2fs.h>
|
||||
#include <uapi/linux/f2fs.h>
|
||||
|
||||
static void f2fs_zero_post_eof_page(struct inode *inode, loff_t new_size)
|
||||
static void f2fs_zero_post_eof_page(struct inode *inode,
|
||||
loff_t new_size, bool lock)
|
||||
{
|
||||
loff_t old_size = i_size_read(inode);
|
||||
|
||||
if (old_size >= new_size)
|
||||
return;
|
||||
|
||||
if (mapping_empty(inode->i_mapping))
|
||||
return;
|
||||
|
||||
if (lock)
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
/* zero or drop pages only in range of [old_size, new_size] */
|
||||
truncate_pagecache(inode, old_size);
|
||||
truncate_inode_pages_range(inode->i_mapping, old_size, new_size);
|
||||
if (lock)
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
}
|
||||
|
||||
static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
|
||||
@@ -115,9 +123,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
|
||||
|
||||
f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT, true);
|
||||
|
||||
file_update_time(vmf->vma->vm_file);
|
||||
filemap_invalidate_lock_shared(inode->i_mapping);
|
||||
@@ -1077,7 +1083,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
if (attr->ia_size > old_size)
|
||||
f2fs_zero_post_eof_page(inode, attr->ia_size);
|
||||
f2fs_zero_post_eof_page(inode, attr->ia_size, false);
|
||||
truncate_setsize(inode, attr->ia_size);
|
||||
|
||||
if (attr->ia_size <= old_size)
|
||||
@@ -1196,9 +1202,7 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, offset + len);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, offset + len, true);
|
||||
|
||||
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
|
||||
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
|
||||
@@ -1484,7 +1488,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
|
||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
f2fs_zero_post_eof_page(inode, offset + len);
|
||||
f2fs_zero_post_eof_page(inode, offset + len, false);
|
||||
|
||||
f2fs_lock_op(sbi);
|
||||
f2fs_drop_extent_tree(inode);
|
||||
@@ -1608,9 +1612,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
filemap_invalidate_lock(mapping);
|
||||
f2fs_zero_post_eof_page(inode, offset + len);
|
||||
filemap_invalidate_unlock(mapping);
|
||||
f2fs_zero_post_eof_page(inode, offset + len, true);
|
||||
|
||||
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
|
||||
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
|
||||
@@ -1744,7 +1746,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
|
||||
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
|
||||
filemap_invalidate_lock(mapping);
|
||||
|
||||
f2fs_zero_post_eof_page(inode, offset + len);
|
||||
f2fs_zero_post_eof_page(inode, offset + len, false);
|
||||
truncate_pagecache(inode, offset);
|
||||
|
||||
while (!ret && idx > pg_start) {
|
||||
@@ -1800,9 +1802,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, offset + len);
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, offset + len, true);
|
||||
|
||||
f2fs_balance_fs(sbi, true);
|
||||
|
||||
@@ -4718,9 +4718,8 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode, iocb->ki_pos + iov_iter_count(from));
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
f2fs_zero_post_eof_page(inode,
|
||||
iocb->ki_pos + iov_iter_count(from), true);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user