bcachefs: Use deferred btree updates for inode updates
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
3e5d6c59be
commit
5154704b29
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user