summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-12-04 08:51:28 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-12-04 08:51:28 -0500
commit2b43cae5ddfa6485f89c5c9debdf04eaa370731c (patch)
tree9ab7c6a9930e60784fc2af778914392fbb6cc80f
parent6a5576e721c1f29808e748fcbe61c4062a914037 (diff)
bcachefs: fix for spinning on journal reservation
-rw-r--r--fs/bcachefs/btree_update_leaf.c11
-rw-r--r--fs/bcachefs/journal.c14
-rw-r--r--fs/bcachefs/journal.h19
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;
}