diff options
Diffstat (limited to 'fs/f2fs/data.c')
-rw-r--r-- | fs/f2fs/data.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e0965b43d16e..bf39eed2442f 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -706,13 +706,28 @@ out: static int f2fs_read_data_page(struct file *file, struct page *page) { - return mpage_readpage(page, get_data_block); + struct inode *inode = page->mapping->host; + int ret; + + /* If the file has inline data, try to read it directlly */ + if (f2fs_has_inline_data(inode)) + ret = f2fs_read_inline_data(inode, page); + else + ret = mpage_readpage(page, get_data_block); + + return ret; } static int f2fs_read_data_pages(struct file *file, struct address_space *mapping, struct list_head *pages, unsigned nr_pages) { + struct inode *inode = file->f_mapping->host; + + /* If the file has inline data, skip readpages */ + if (f2fs_has_inline_data(inode)) + return 0; + return mpage_readpages(mapping, pages, nr_pages, get_data_block); } @@ -761,7 +776,7 @@ static int f2fs_write_data_page(struct page *page, loff_t i_size = i_size_read(inode); const pgoff_t end_index = ((unsigned long long) i_size) >> PAGE_CACHE_SHIFT; - unsigned offset; + unsigned offset = 0; bool need_balance_fs = false; int err = 0; struct f2fs_io_info fio = { @@ -799,7 +814,15 @@ write: err = do_write_data_page(page, &fio); } else { f2fs_lock_op(sbi); - err = do_write_data_page(page, &fio); + + if (f2fs_has_inline_data(inode) || f2fs_may_inline(inode)) { + err = f2fs_write_inline_data(inode, page, offset); + f2fs_unlock_op(sbi); + goto out; + } else { + err = do_write_data_page(page, &fio); + } + f2fs_unlock_op(sbi); need_balance_fs = true; } @@ -888,6 +911,15 @@ repeat: return -ENOMEM; *pagep = page; + if ((pos + len) < MAX_INLINE_DATA) { + if (f2fs_has_inline_data(inode)) + goto inline_data; + } else if (f2fs_has_inline_data(inode)) { + err = f2fs_convert_inline_data(inode, page, flags); + if (err) + return err; + } + f2fs_lock_op(sbi); set_new_dnode(&dn, inode, NULL, NULL, 0); err = f2fs_reserve_block(&dn, index); @@ -897,7 +929,7 @@ repeat: f2fs_put_page(page, 1); return err; } - +inline_data: if ((len == PAGE_CACHE_SIZE) || PageUptodate(page)) return 0; @@ -913,7 +945,10 @@ repeat: if (dn.data_blkaddr == NEW_ADDR) { zero_user_segment(page, 0, PAGE_CACHE_SIZE); } else { - err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr, + if (f2fs_has_inline_data(inode)) + err = f2fs_read_inline_data(inode, page); + else + err = f2fs_submit_page_bio(sbi, page, dn.data_blkaddr, READ_SYNC); if (err) return err; @@ -977,6 +1012,10 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb, struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; + /* Let buffer I/O handle the inline data case. */ + if (f2fs_has_inline_data(inode)) + return 0; + if (check_direct_IO(inode, rw, iov, offset, nr_segs)) return 0; |