pgoff_t start_fofs, end_fofs;
block_t start_blkaddr;
- if (is_inode_flag_set(fi, FI_NO_EXTENT))
- return false;
-
read_lock(&fi->ext_lock);
if (fi->ext.len == 0) {
read_unlock(&fi->ext_lock);
block_t start_blkaddr, end_blkaddr;
int need_update = true;
- if (is_inode_flag_set(fi, FI_NO_EXTENT))
- return false;
-
write_lock(&fi->ext_lock);
start_fofs = fi->ext.fofs;
struct extent_tree *et;
struct extent_node *en;
- if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
- return false;
-
trace_f2fs_lookup_extent_tree_start(inode, pgofs);
down_read(&sbi->extent_tree_lock);
struct extent_info ei, dei;
unsigned int endofs;
- if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
- return;
-
trace_f2fs_update_extent_tree(inode, fofs, blkaddr);
down_write(&sbi->extent_tree_lock);
static bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs,
struct extent_info *ei)
{
+ if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT))
+ return false;
+
if (test_opt(F2FS_I_SB(inode), EXTENT_CACHE))
return f2fs_lookup_extent_tree(inode, pgofs, ei);
/* Update the page address in the parent node */
__set_data_blkaddr(dn);
+ if (is_inode_flag_set(fi, FI_NO_EXTENT))
+ return;
+
fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
dn->ofs_in_node;
struct address_space *mapping = inode->i_mapping;
struct dnode_of_data dn;
struct page *page;
+ struct extent_info ei;
int err;
struct f2fs_io_info fio = {
.type = DATA,
.rw = sync ? READ_SYNC : READA,
};
+ /*
+ * If sync is false, it needs to check its block allocation.
+ * This is need and triggered by two flows:
+ * gc and truncate_partial_data_page.
+ */
+ if (!sync)
+ goto search;
+
page = find_get_page(mapping, index);
if (page && PageUptodate(page))
return page;
f2fs_put_page(page, 0);
+search:
+ if (f2fs_lookup_extent_cache(inode, index, &ei)) {
+ dn.data_blkaddr = ei.blk + index - ei.fofs;
+ goto got_it;
+ }
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (unlikely(dn.data_blkaddr == NEW_ADDR))
return ERR_PTR(-EINVAL);
+got_it:
page = grab_cache_page(mapping, index);
if (!page)
return ERR_PTR(-ENOMEM);
struct address_space *mapping = inode->i_mapping;
struct dnode_of_data dn;
struct page *page;
+ struct extent_info ei;
int err;
struct f2fs_io_info fio = {
.type = DATA,
if (!page)
return ERR_PTR(-ENOMEM);
+ if (f2fs_lookup_extent_cache(inode, index, &ei)) {
+ dn.data_blkaddr = ei.blk + index - ei.fofs;
+ goto got_it;
+ }
+
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (err) {
return ERR_PTR(-ENOENT);
}
+got_it:
if (PageUptodate(page))
return page;
fio->blk_addr = dn.data_blkaddr;
/* This page is already truncated */
- if (fio->blk_addr == NULL_ADDR)
+ if (fio->blk_addr == NULL_ADDR) {
+ ClearPageUptodate(page);
goto out_writepage;
+ }
set_page_writeback(page);
clear_cold_data(page);
out:
inode_dec_dirty_pages(inode);
+ if (err)
+ ClearPageUptodate(page);
unlock_page(page);
if (need_balance_fs)
f2fs_balance_fs(sbi);