diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-12-04 08:51:28 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-12-04 08:51:28 -0500 |
commit | 2b43cae5ddfa6485f89c5c9debdf04eaa370731c (patch) | |
tree | 9ab7c6a9930e60784fc2af778914392fbb6cc80f | |
parent | 6a5576e721c1f29808e748fcbe61c4062a914037 (diff) |
bcachefs: fix for spinning on journal reservation
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 11 | ||||
-rw-r--r-- | fs/bcachefs/journal.c | 14 | ||||
-rw-r--r-- | fs/bcachefs/journal.h | 19 |
3 files changed, 22 insertions, 22 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index a958036bd70d..7eca9203be01 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -486,7 +486,6 @@ static inline int do_btree_insert_at(struct btree_insert *trans, &trans->journal_res, u64s, JOURNAL_RES_GET_NONBLOCK)) == -EAGAIN) { struct btree_iter *iter = NULL; - struct closure cl; trans_for_each_iter(trans, i) iter = i->iter; @@ -494,13 +493,9 @@ static inline int do_btree_insert_at(struct btree_insert *trans, if (iter) bch2_btree_iter_unlock(iter); - closure_init_stack(&cl); - - while ((ret = bch2_journal_open_seq_async(&c->journal, - trans->journal_res.seq, - &cl)) == -EAGAIN) - closure_sync(&cl); - + ret = bch2_journal_res_get(&c->journal, + &trans->journal_res, u64s, + JOURNAL_RES_GET_CHECK); if (ret) return ret; diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 379b502afbec..261149adf162 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -342,7 +342,7 @@ static int __journal_res_get(struct journal *j, struct journal_res *res, struct journal_buf *buf; int ret; retry: - if (journal_res_get_fast(j, res)) + if (journal_res_get_fast(j, res, flags)) return 0; spin_lock(&j->lock); @@ -351,7 +351,7 @@ retry: * that just did journal_entry_open() and call journal_entry_close() * unnecessarily */ - if (journal_res_get_fast(j, res)) { + if (journal_res_get_fast(j, res, flags)) { spin_unlock(&j->lock); return 0; } @@ -377,11 +377,11 @@ retry: return -EROFS; case JOURNAL_ENTRY_INUSE: /* - * haven't finished writing out the previous entry, can't start - * another yet: - * signal to caller which sequence number we're trying to open: + * The current journal entry is still open, but we failed to get + * a journal reservation because there's not enough space in it, + * and we can't close it and start another because we haven't + * finished writing out the previous entry: */ - res->seq = journal_cur_seq(j) + 1; spin_unlock(&j->lock); trace_journal_entry_full(c); goto blocked; @@ -393,8 +393,6 @@ retry: /* We now have a new, closed journal buf - see if we can open it: */ ret = journal_entry_open(j); - if (!ret) - res->seq = journal_cur_seq(j); spin_unlock(&j->lock); if (ret < 0) diff --git a/fs/bcachefs/journal.h b/fs/bcachefs/journal.h index 0595597f08e9..3a0837481100 100644 --- a/fs/bcachefs/journal.h +++ b/fs/bcachefs/journal.h @@ -271,8 +271,12 @@ static inline void bch2_journal_res_put(struct journal *j, int bch2_journal_res_get_slowpath(struct journal *, struct journal_res *, unsigned); +#define JOURNAL_RES_GET_NONBLOCK (1 << 0) +#define JOURNAL_RES_GET_CHECK (1 << 1) + static inline int journal_res_get_fast(struct journal *j, - struct journal_res *res) + struct journal_res *res, + unsigned flags) { union journal_res_state old, new; u64 v = atomic64_read(&j->reservations.counter); @@ -287,6 +291,9 @@ static inline int journal_res_get_fast(struct journal *j, if (new.cur_entry_offset + res->u64s > j->cur_entry_u64s) return 0; + if (flags & JOURNAL_RES_GET_CHECK) + return 1; + new.cur_entry_offset += res->u64s; journal_state_inc(&new); } while ((v = atomic64_cmpxchg(&j->reservations.counter, @@ -299,8 +306,6 @@ static inline int journal_res_get_fast(struct journal *j, return 1; } -#define JOURNAL_RES_GET_NONBLOCK (1 << 0) - static inline int bch2_journal_res_get(struct journal *j, struct journal_res *res, unsigned u64s, unsigned flags) { @@ -311,15 +316,17 @@ static inline int bch2_journal_res_get(struct journal *j, struct journal_res *re res->u64s = u64s; - if (journal_res_get_fast(j, res)) + if (journal_res_get_fast(j, res, flags)) goto out; ret = bch2_journal_res_get_slowpath(j, res, flags); if (ret) return ret; out: - lock_acquire_shared(&j->res_map, 0, 0, NULL, _THIS_IP_); - EBUG_ON(!res->ref); + if (!(flags & JOURNAL_RES_GET_CHECK)) { + lock_acquire_shared(&j->res_map, 0, 0, NULL, _THIS_IP_); + EBUG_ON(!res->ref); + } return 0; } |