Commit 7eab0c0d authored by Hou Pengyang's avatar Hou Pengyang Committed by Jaegeuk Kim

f2fs: reconstruct code to write a data page

This patch introduces encrypt_one_page which encrypts one data page before
submit_bio, and change the use of need_inplace_update.
Signed-off-by: default avatarHou Pengyang <houpengyang@huawei.com>
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 63a94fa1
...@@ -1302,6 +1302,49 @@ static int f2fs_read_data_pages(struct file *file, ...@@ -1302,6 +1302,49 @@ static int f2fs_read_data_pages(struct file *file,
return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages); return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages);
} }
static int encrypt_one_page(struct f2fs_io_info *fio)
{
struct inode *inode = fio->page->mapping->host;
gfp_t gfp_flags = GFP_NOFS;
if (!f2fs_encrypted_inode(inode) || !S_ISREG(inode->i_mode))
return 0;
/* wait for GCed encrypted page writeback */
f2fs_wait_on_encrypted_page_writeback(fio->sbi, fio->old_blkaddr);
retry_encrypt:
fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
PAGE_SIZE, 0, fio->page->index, gfp_flags);
if (!IS_ERR(fio->encrypted_page))
return 0;
/* flush pending IOs and wait for a while in the ENOMEM case */
if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
f2fs_flush_merged_bios(fio->sbi);
congestion_wait(BLK_RW_ASYNC, HZ/50);
gfp_flags |= __GFP_NOFAIL;
goto retry_encrypt;
}
return PTR_ERR(fio->encrypted_page);
}
static inline bool need_inplace_update(struct f2fs_io_info *fio)
{
struct inode *inode = fio->page->mapping->host;
if (fio->old_blkaddr == NEW_ADDR)
return false;
if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode))
return false;
if (is_cold_data(fio->page))
return false;
if (IS_ATOMIC_WRITTEN_PAGE(fio->page))
return false;
return need_inplace_update_policy(inode, fio);
}
int do_write_data_page(struct f2fs_io_info *fio) int do_write_data_page(struct f2fs_io_info *fio)
{ {
struct page *page = fio->page; struct page *page = fio->page;
...@@ -1322,30 +1365,9 @@ int do_write_data_page(struct f2fs_io_info *fio) ...@@ -1322,30 +1365,9 @@ int do_write_data_page(struct f2fs_io_info *fio)
goto out_writepage; goto out_writepage;
} }
if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { err = encrypt_one_page(fio);
gfp_t gfp_flags = GFP_NOFS; if (err)
/* wait for GCed encrypted page writeback */
f2fs_wait_on_encrypted_page_writeback(F2FS_I_SB(inode),
fio->old_blkaddr);
retry_encrypt:
fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
PAGE_SIZE, 0,
fio->page->index,
gfp_flags);
if (IS_ERR(fio->encrypted_page)) {
err = PTR_ERR(fio->encrypted_page);
if (err == -ENOMEM) {
/* flush pending ios and wait for a while */
f2fs_flush_merged_bios(F2FS_I_SB(inode));
congestion_wait(BLK_RW_ASYNC, HZ/50);
gfp_flags |= __GFP_NOFAIL;
err = 0;
goto retry_encrypt;
}
goto out_writepage; goto out_writepage;
}
}
set_page_writeback(page); set_page_writeback(page);
...@@ -1353,15 +1375,14 @@ int do_write_data_page(struct f2fs_io_info *fio) ...@@ -1353,15 +1375,14 @@ int do_write_data_page(struct f2fs_io_info *fio)
* If current allocation needs SSR, * If current allocation needs SSR,
* it had better in-place writes for updated data. * it had better in-place writes for updated data.
*/ */
if (unlikely(fio->old_blkaddr != NEW_ADDR && if (need_inplace_update(fio)) {
!is_cold_data(page) && f2fs_bug_on(fio->sbi, !fio->cp_rwsem_locked);
!IS_ATOMIC_WRITTEN_PAGE(page) && f2fs_unlock_op(fio->sbi);
need_inplace_update(inode, fio))) {
f2fs_unlock_op(F2FS_I_SB(inode));
fio->cp_rwsem_locked = false; fio->cp_rwsem_locked = false;
err = rewrite_data_page(fio); err = rewrite_data_page(fio);
trace_f2fs_do_write_data_page(fio->page, IPU);
set_inode_flag(inode, FI_UPDATE_WRITE); set_inode_flag(inode, FI_UPDATE_WRITE);
trace_f2fs_do_write_data_page(page, IPU);
} else { } else {
write_data_page(&dn, fio); write_data_page(&dn, fio);
trace_f2fs_do_write_data_page(page, OPU); trace_f2fs_do_write_data_page(page, OPU);
......
...@@ -1898,7 +1898,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, ...@@ -1898,7 +1898,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
int err; int err;
/* if in-place-update policy is enabled, don't waste time here */ /* if in-place-update policy is enabled, don't waste time here */
if (need_inplace_update(inode, NULL)) if (need_inplace_update_policy(inode, NULL))
return -EINVAL; return -EINVAL;
pg_start = range->start >> PAGE_SHIFT; pg_start = range->start >> PAGE_SHIFT;
...@@ -2033,7 +2033,7 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg) ...@@ -2033,7 +2033,7 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg)
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->i_mode) || f2fs_is_atomic_file(inode))
return -EINVAL; return -EINVAL;
if (f2fs_readonly(sbi->sb)) if (f2fs_readonly(sbi->sb))
......
...@@ -564,16 +564,12 @@ enum { ...@@ -564,16 +564,12 @@ enum {
F2FS_IPU_ASYNC, F2FS_IPU_ASYNC,
}; };
static inline bool need_inplace_update(struct inode *inode, static inline bool need_inplace_update_policy(struct inode *inode,
struct f2fs_io_info *fio) struct f2fs_io_info *fio)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
unsigned int policy = SM_I(sbi)->ipu_policy; unsigned int policy = SM_I(sbi)->ipu_policy;
/* IPU can be done only for the user data */
if (S_ISDIR(inode->i_mode) || f2fs_is_atomic_file(inode))
return false;
if (test_opt(sbi, LFS)) if (test_opt(sbi, LFS))
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment