diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-07-20 22:27:07 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:17 -0400 |
commit | 5154704b29e58a5fd9acd601b831d99298a76a6c (patch) | |
tree | c60f6a9cbc9361c869d23c87f8eb30af7228dda7 /fs | |
parent | 3e5d6c59bec6f989e103e364d6a044a8a77e3a13 (diff) |
bcachefs: Use deferred btree updates for inode updates
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/btree_iter.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_locking.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/fs-io.c | 35 | ||||
-rw-r--r-- | fs/bcachefs/fs.c | 23 | ||||
-rw-r--r-- | fs/bcachefs/fs.h | 1 |
5 files changed, 44 insertions, 18 deletions
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h index 52e0e003153b..a64ed6d32175 100644 --- a/fs/bcachefs/btree_iter.h +++ b/fs/bcachefs/btree_iter.h @@ -104,6 +104,7 @@ void bch2_btree_node_iter_fix(struct btree_iter *, struct btree *, unsigned, unsigned); int bch2_btree_iter_unlock(struct btree_iter *); +bool bch2_btree_iter_relock(struct btree_iter *); bool __bch2_btree_iter_upgrade(struct btree_iter *, unsigned); bool __bch2_btree_iter_upgrade_nounlock(struct btree_iter *, unsigned); diff --git a/fs/bcachefs/btree_locking.h b/fs/bcachefs/btree_locking.h index 48b50e066186..c036cd0458a4 100644 --- a/fs/bcachefs/btree_locking.h +++ b/fs/bcachefs/btree_locking.h @@ -203,8 +203,6 @@ static inline bool bch2_btree_node_relock(struct btree_iter *iter, __bch2_btree_node_relock(iter, level); } -bool bch2_btree_iter_relock(struct btree_iter *); - void bch2_btree_node_unlock_write(struct btree *, struct btree_iter *); void __bch2_btree_node_lock_write(struct btree *, struct btree_iter *); diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 7681cfbc6bed..f8657baf0521 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -287,11 +287,11 @@ static int bch2_extent_update(struct btree_trans *trans, bool direct, s64 *total_delta) { - struct btree_iter *inode_iter = NULL; struct bch_inode_unpacked inode_u; struct bkey_inode_buf inode_p; bool allocating = false; bool extended = false; + bool inode_locked = false; s64 i_sectors_delta; int ret; @@ -314,16 +314,20 @@ static int bch2_extent_update(struct btree_trans *trans, /* XXX: inode->i_size locking */ if (i_sectors_delta || new_i_size > inode->ei_inode.bi_size) { - inode_iter = bch2_trans_get_iter(trans, - BTREE_ID_INODES, - POS(k->k.p.inode, 0), - BTREE_ITER_SLOTS|BTREE_ITER_INTENT); - if (IS_ERR(inode_iter)) - return PTR_ERR(inode_iter); + bch2_btree_iter_unlock(extent_iter); + mutex_lock(&inode->ei_update_lock); - ret = bch2_btree_iter_traverse(inode_iter); - if (ret) - goto err; + if (!bch2_btree_iter_relock(extent_iter)) { + mutex_unlock(&inode->ei_update_lock); + return -EINTR; + } + + inode_locked = true; + + if (!inode->ei_inode_update) + inode->ei_inode_update = + bch2_deferred_update_alloc(trans->c, + BTREE_ID_INODES, 64); inode_u = inode->ei_inode; inode_u.bi_sectors += i_sectors_delta; @@ -337,7 +341,8 @@ static int bch2_extent_update(struct btree_trans *trans, bch2_inode_pack(&inode_p, &inode_u); bch2_trans_update(trans, - BTREE_INSERT_ENTRY(inode_iter, &inode_p.inode.k_i)); + BTREE_INSERT_DEFERRED(inode->ei_inode_update, + &inode_p.inode.k_i)); } ret = bch2_trans_commit(trans, disk_res, @@ -371,13 +376,15 @@ static int bch2_extent_update(struct btree_trans *trans, if (total_delta) *total_delta += i_sectors_delta; err: - if (!IS_ERR_OR_NULL(inode_iter)) - bch2_trans_iter_put(trans, inode_iter); + if (inode_locked) + mutex_unlock(&inode->ei_update_lock); + return ret; } static int bchfs_write_index_update(struct bch_write_op *wop) { + struct bch_fs *c = wop->c; struct bchfs_write_op *op = container_of(wop, struct bchfs_write_op, op); struct quota_res *quota_res = op->is_dio @@ -392,7 +399,7 @@ static int bchfs_write_index_update(struct bch_write_op *wop) BUG_ON(k->k.p.inode != inode->v.i_ino); - bch2_trans_init(&trans, wop->c); + bch2_trans_init(&trans, c); bch2_trans_preload_iters(&trans); iter = bch2_trans_get_iter(&trans, diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c index 02c7543e40c8..5f93ea76785f 100644 --- a/fs/bcachefs/fs.c +++ b/fs/bcachefs/fs.c @@ -156,12 +156,18 @@ int __must_check bch2_write_inode_trans(struct btree_trans *trans, inode_set_fn set, void *p) { + struct bch_fs *c = trans->c; struct btree_iter *iter; struct bkey_inode_buf *inode_p; int ret; lockdep_assert_held(&inode->ei_update_lock); + /* XXX: Don't do this with btree locks held */ + if (!inode->ei_inode_update) + inode->ei_inode_update = + bch2_deferred_update_alloc(c, BTREE_ID_INODES, 64); +#if 0 iter = bch2_trans_get_iter(trans, BTREE_ID_INODES, POS(inode->v.i_ino, 0), BTREE_ITER_SLOTS|BTREE_ITER_INTENT); @@ -172,7 +178,7 @@ int __must_check bch2_write_inode_trans(struct btree_trans *trans, ret = bch2_btree_iter_traverse(iter); if (ret) return ret; - +#endif *inode_u = inode->ei_inode; if (set) { @@ -186,7 +192,15 @@ int __must_check bch2_write_inode_trans(struct btree_trans *trans, return PTR_ERR(inode_p); bch2_inode_pack(inode_p, inode_u); - bch2_trans_update(trans, BTREE_INSERT_ENTRY(iter, &inode_p->inode.k_i)); + + if (!inode->ei_inode_update) + bch2_trans_update(trans, + BTREE_INSERT_ENTRY(iter, &inode_p->inode.k_i)); + else + bch2_trans_update(trans, + BTREE_INSERT_DEFERRED(inode->ei_inode_update, + &inode_p->inode.k_i)); + return 0; } @@ -1431,6 +1445,7 @@ static struct inode *bch2_alloc_inode(struct super_block *sb) mutex_init(&inode->ei_update_lock); pagecache_lock_init(&inode->ei_pagecache_lock); mutex_init(&inode->ei_quota_lock); + inode->ei_inode_update = NULL; inode->ei_journal_seq = 0; return &inode->v; @@ -1494,6 +1509,10 @@ static void bch2_evict_inode(struct inode *vinode) BUG_ON(!is_bad_inode(&inode->v) && inode->ei_quota_reserved); + if (inode->ei_inode_update) + bch2_deferred_update_free(c, inode->ei_inode_update); + inode->ei_inode_update = NULL; + if (!inode->v.i_nlink && !is_bad_inode(&inode->v)) { bch2_quota_acct(c, inode->ei_qid, Q_SPC, -((s64) inode->v.i_blocks), KEY_TYPE_QUOTA_WARN); diff --git a/fs/bcachefs/fs.h b/fs/bcachefs/fs.h index f949cd0d2a68..b9a8a9bc3e90 100644 --- a/fs/bcachefs/fs.h +++ b/fs/bcachefs/fs.h @@ -34,6 +34,7 @@ struct bch_inode_info { struct inode v; struct mutex ei_update_lock; + struct deferred_update *ei_inode_update; u64 ei_journal_seq; u64 ei_quota_reserved; unsigned long ei_last_dirtied; |