diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-10-18 07:33:55 +0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2014-11-04 03:07:30 +0300 |
commit | 9ba69cf9877384baebd16c6fb51ceccd13677b37 (patch) | |
tree | c88d71c4b2e41c1519851c54f52b96c523fa6a4c /fs/f2fs/file.c | |
parent | a78186ebe516b6d7df43636603f0998803ab356a (diff) | |
download | linux-9ba69cf9877384baebd16c6fb51ceccd13677b37.tar.xz |
f2fs: avoid to allocate when inline_data was written
The sceanrio is like this.
inline_data i_size page write_begin/vm_page_mkwrite
X 30 dirty_page
X 30 write to #4096 position
X 30 get_dnode_of_data wait for get_dnode_of_data
O 30 write inline_data
O 30 get_dnode_of_data
O 30 reserve data block
..
In this case, we have #0 = NEW_ADDR and inline_data as well.
We should not allow this condition for further access.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/file.c')
-rw-r--r-- | fs/f2fs/file.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 543d8c630345..456df07f19cb 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -35,12 +35,13 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, struct inode *inode = file_inode(vma->vm_file); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; + struct page *ipage; int err; f2fs_balance_fs(sbi); sb_start_pagefault(inode->i_sb); - +retry: /* force to convert with normal data indices */ err = f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1, page); if (err) @@ -48,11 +49,28 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, /* block allocation */ f2fs_lock_op(sbi); - set_new_dnode(&dn, inode, NULL, NULL, 0); + + /* check inline_data */ + ipage = get_node_page(sbi, inode->i_ino); + if (IS_ERR(ipage)) { + f2fs_unlock_op(sbi); + goto out; + } + + if (f2fs_has_inline_data(inode)) { + f2fs_put_page(ipage, 1); + f2fs_unlock_op(sbi); + goto retry; + } + + set_new_dnode(&dn, inode, ipage, NULL, 0); err = f2fs_reserve_block(&dn, page->index); - f2fs_unlock_op(sbi); - if (err) + if (err) { + f2fs_unlock_op(sbi); goto out; + } + f2fs_put_dnode(&dn); + f2fs_unlock_op(sbi); file_update_time(vma->vm_file); lock_page(page); |