From: Kent Overstreet Date: Wed, 15 May 2019 13:49:46 +0000 (-0400) Subject: bcachefs: Fix a bug with spinning on the journal X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=87c3beb4a589312f2c150129309a48b5518385e7;p=linux.git bcachefs: Fix a bug with spinning on the journal Transactional triggers meant that when we failed to get a journal reservation, then bailed out into the error path to block on a journal reservation, the second blocking call into the journal code was asking for less space, which is not what we want. Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index d88f1c911d047..9bab213fd65b8 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -301,6 +301,7 @@ struct btree_trans { u64 *journal_seq; struct disk_reservation *disk_res; unsigned flags; + unsigned journal_u64s; struct btree_iter iters_onstack[2]; struct btree_insert_entry updates_onstack[6]; diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 7286a5b454810..88e038c1cceff 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -451,21 +451,13 @@ static int bch2_trans_journal_res_get(struct btree_trans *trans, unsigned flags) { struct bch_fs *c = trans->c; - struct btree_insert_entry *i; - unsigned u64s = 0; int ret; - if (unlikely(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) - return 0; - if (trans->flags & BTREE_INSERT_JOURNAL_RESERVED) flags |= JOURNAL_RES_GET_RESERVED; - trans_for_each_update(trans, i) - u64s += jset_u64s(i->k->k.u64s); - ret = bch2_journal_res_get(&c->journal, &trans->journal_res, - u64s, flags); + trans->journal_u64s, flags); return ret == -EAGAIN ? BTREE_INSERT_NEED_JOURNAL_RES : ret; } @@ -612,9 +604,16 @@ static inline int do_btree_insert_at(struct btree_trans *trans, * Don't get journal reservation until after we know insert will * succeed: */ - ret = bch2_trans_journal_res_get(trans, JOURNAL_RES_GET_NONBLOCK); - if (ret) - goto out; + if (likely(!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))) { + trans->journal_u64s = 0; + + trans_for_each_update(trans, i) + trans->journal_u64s += jset_u64s(i->k->k.u64s); + + ret = bch2_trans_journal_res_get(trans, JOURNAL_RES_GET_NONBLOCK); + if (ret) + goto out; + } if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) { if (journal_seq_verify(c))