mirror of https://gitee.com/openkylin/linux.git
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: Hou Pengyang <houpengyang@huawei.com> Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
63a94fa1d7
commit
7eab0c0df8
|
@ -1302,6 +1302,49 @@ static int f2fs_read_data_pages(struct file *file,
|
|||
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)
|
||||
{
|
||||
struct page *page = fio->page;
|
||||
|
@ -1322,30 +1365,9 @@ int do_write_data_page(struct f2fs_io_info *fio)
|
|||
goto out_writepage;
|
||||
}
|
||||
|
||||
if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
|
||||
gfp_t gfp_flags = GFP_NOFS;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
err = encrypt_one_page(fio);
|
||||
if (err)
|
||||
goto out_writepage;
|
||||
|
||||
set_page_writeback(page);
|
||||
|
||||
|
@ -1353,15 +1375,14 @@ int do_write_data_page(struct f2fs_io_info *fio)
|
|||
* If current allocation needs SSR,
|
||||
* it had better in-place writes for updated data.
|
||||
*/
|
||||
if (unlikely(fio->old_blkaddr != NEW_ADDR &&
|
||||
!is_cold_data(page) &&
|
||||
!IS_ATOMIC_WRITTEN_PAGE(page) &&
|
||||
need_inplace_update(inode, fio))) {
|
||||
f2fs_unlock_op(F2FS_I_SB(inode));
|
||||
if (need_inplace_update(fio)) {
|
||||
f2fs_bug_on(fio->sbi, !fio->cp_rwsem_locked);
|
||||
f2fs_unlock_op(fio->sbi);
|
||||
fio->cp_rwsem_locked = false;
|
||||
|
||||
err = rewrite_data_page(fio);
|
||||
trace_f2fs_do_write_data_page(fio->page, IPU);
|
||||
set_inode_flag(inode, FI_UPDATE_WRITE);
|
||||
trace_f2fs_do_write_data_page(page, IPU);
|
||||
} else {
|
||||
write_data_page(&dn, fio);
|
||||
trace_f2fs_do_write_data_page(page, OPU);
|
||||
|
|
|
@ -1898,7 +1898,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
|
|||
int err;
|
||||
|
||||
/* 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;
|
||||
|
||||
pg_start = range->start >> PAGE_SHIFT;
|
||||
|
@ -2033,7 +2033,7 @@ static int f2fs_ioc_defragment(struct file *filp, unsigned long arg)
|
|||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
if (!S_ISREG(inode->i_mode) || f2fs_is_atomic_file(inode))
|
||||
return -EINVAL;
|
||||
|
||||
if (f2fs_readonly(sbi->sb))
|
||||
|
|
|
@ -564,16 +564,12 @@ enum {
|
|||
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_sb_info *sbi = F2FS_I_SB(inode);
|
||||
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))
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue