Skip to content

Commit

Permalink
f2fs: do not bother checkpoint by f2fs_get_node_info
Browse files Browse the repository at this point in the history
This patch tries to mitigate lock contention between f2fs_write_checkpoint and
f2fs_get_node_info along with nat_tree_lock.

The idea is, if checkpoint is currently running, other threads that try to grab
nat_tree_lock would be better to wait for checkpoint.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
  • Loading branch information
Jaegeuk Kim committed Dec 14, 2021
1 parent cbcb33f commit 7e035df
Show file tree
Hide file tree
Showing 11 changed files with 26 additions and 25 deletions.
2 changes: 1 addition & 1 deletion fs/f2fs/checkpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
/* truncate all the data during iput */
iput(inode);

err = f2fs_get_node_info(sbi, ino, &ni);
err = f2fs_get_node_info(sbi, ino, &ni, false);
if (err)
goto err_out;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,

psize = (loff_t)(cc->rpages[last_index]->index + 1) << PAGE_SHIFT;

err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false);
if (err)
goto out_put_dnode;

Expand Down
8 changes: 4 additions & 4 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
return -EPERM;

err = f2fs_get_node_info(sbi, dn->nid, &ni);
err = f2fs_get_node_info(sbi, dn->nid, &ni, false);
if (err)
return err;

Expand Down Expand Up @@ -1757,7 +1757,7 @@ static int f2fs_xattr_fiemap(struct inode *inode,
if (!page)
return -ENOMEM;

err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false);
if (err) {
f2fs_put_page(page, 1);
return err;
Expand Down Expand Up @@ -1789,7 +1789,7 @@ static int f2fs_xattr_fiemap(struct inode *inode,
if (!page)
return -ENOMEM;

err = f2fs_get_node_info(sbi, xnid, &ni);
err = f2fs_get_node_info(sbi, xnid, &ni, false);
if (err) {
f2fs_put_page(page, 1);
return err;
Expand Down Expand Up @@ -2649,7 +2649,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
fio->need_lock = LOCK_REQ;
}

err = f2fs_get_node_info(fio->sbi, dn.nid, &ni);
err = f2fs_get_node_info(fio->sbi, dn.nid, &ni, false);
if (err)
goto out_writepage;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/f2fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3412,7 +3412,7 @@ int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
struct node_info *ni);
struct node_info *ni, bool checkpoint_context);
pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from);
Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
if (ret)
return ret;

ret = f2fs_get_node_info(sbi, dn.nid, &ni);
ret = f2fs_get_node_info(sbi, dn.nid, &ni, false);
if (ret) {
f2fs_put_dnode(&dn);
return ret;
Expand Down
6 changes: 3 additions & 3 deletions fs/f2fs/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi,
continue;
}

if (f2fs_get_node_info(sbi, nid, &ni)) {
if (f2fs_get_node_info(sbi, nid, &ni, false)) {
f2fs_put_page(node_page, 1);
continue;
}
Expand Down Expand Up @@ -1027,7 +1027,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
if (IS_ERR(node_page))
return false;

if (f2fs_get_node_info(sbi, nid, dni)) {
if (f2fs_get_node_info(sbi, nid, dni, false)) {
f2fs_put_page(node_page, 1);
return false;
}
Expand Down Expand Up @@ -1221,7 +1221,7 @@ static int move_data_block(struct inode *inode, block_t bidx,

f2fs_wait_on_block_writeback(inode, dn.data_blkaddr);

err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false);
if (err)
goto put_out;

Expand Down
4 changes: 2 additions & 2 deletions fs/f2fs/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
if (err)
return err;

err = f2fs_get_node_info(fio.sbi, dn->nid, &ni);
err = f2fs_get_node_info(fio.sbi, dn->nid, &ni, false);
if (err) {
f2fs_truncate_data_blocks_range(dn, 1);
f2fs_put_dnode(dn);
Expand Down Expand Up @@ -786,7 +786,7 @@ int f2fs_inline_data_fiemap(struct inode *inode,
ilen = start + len;
ilen -= start;

err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni, false);
if (err)
goto out;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
* so we can prevent losing this orphan when encoutering checkpoint
* and following suddenly power-off.
*/
err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false);
if (err) {
set_sbi_flag(sbi, SBI_NEED_FSCK);
f2fs_warn(sbi, "May loss orphan inode, run fsck to fix.");
Expand Down
19 changes: 10 additions & 9 deletions fs/f2fs/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
}

int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
struct node_info *ni)
struct node_info *ni, bool checkpoint_context)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
Expand Down Expand Up @@ -576,9 +576,10 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
* nat_tree_lock. Therefore, we should retry, if we failed to grab here
* while not bothering checkpoint.
*/
if (!rwsem_is_locked(&sbi->cp_global_sem)) {
if (!rwsem_is_locked(&sbi->cp_global_sem) || checkpoint_context) {
down_read(&curseg->journal_rwsem);
} else if (!down_read_trylock(&curseg->journal_rwsem)) {
} else if (rwsem_is_contended(&nm_i->nat_tree_lock) ||
!down_read_trylock(&curseg->journal_rwsem)) {
up_read(&nm_i->nat_tree_lock);
goto retry;
}
Expand Down Expand Up @@ -891,7 +892,7 @@ static int truncate_node(struct dnode_of_data *dn)
int err;
pgoff_t index;

err = f2fs_get_node_info(sbi, dn->nid, &ni);
err = f2fs_get_node_info(sbi, dn->nid, &ni, false);
if (err)
return err;

Expand Down Expand Up @@ -1290,7 +1291,7 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
goto fail;

#ifdef CONFIG_F2FS_CHECK_FS
err = f2fs_get_node_info(sbi, dn->nid, &new_ni);
err = f2fs_get_node_info(sbi, dn->nid, &new_ni, false);
if (err) {
dec_valid_node_count(sbi, dn->inode, !ofs);
goto fail;
Expand Down Expand Up @@ -1352,7 +1353,7 @@ static int read_node_page(struct page *page, int op_flags)
return LOCKED_PAGE;
}

err = f2fs_get_node_info(sbi, page->index, &ni);
err = f2fs_get_node_info(sbi, page->index, &ni, false);
if (err)
return err;

Expand Down Expand Up @@ -1604,7 +1605,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
nid = nid_of_node(page);
f2fs_bug_on(sbi, page->index != nid);

if (f2fs_get_node_info(sbi, nid, &ni))
if (f2fs_get_node_info(sbi, nid, &ni, !do_balance))
goto redirty_out;

if (wbc->for_reclaim) {
Expand Down Expand Up @@ -2705,7 +2706,7 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
goto recover_xnid;

/* 1: invalidate the previous xattr nid */
err = f2fs_get_node_info(sbi, prev_xnid, &ni);
err = f2fs_get_node_info(sbi, prev_xnid, &ni, false);
if (err)
return err;

Expand Down Expand Up @@ -2745,7 +2746,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
struct page *ipage;
int err;

err = f2fs_get_node_info(sbi, ino, &old_ni);
err = f2fs_get_node_info(sbi, ino, &old_ni, false);
if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,

f2fs_wait_on_page_writeback(dn.node_page, NODE, true, true);

err = f2fs_get_node_info(sbi, dn.nid, &ni);
err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
if (err)
goto err;

Expand Down
2 changes: 1 addition & 1 deletion fs/f2fs/segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ static int __revoke_inmem_pages(struct inode *inode,
goto next;
}

err = f2fs_get_node_info(sbi, dn.nid, &ni);
err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
if (err) {
f2fs_put_dnode(&dn);
return err;
Expand Down

0 comments on commit 7e035df

Please sign in to comment.