summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_update_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_update_leaf.c')
-rw-r--r--libbcachefs/btree_update_leaf.c132
1 files changed, 83 insertions, 49 deletions
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c
index 154a819b..a2b37dd4 100644
--- a/libbcachefs/btree_update_leaf.c
+++ b/libbcachefs/btree_update_leaf.c
@@ -316,15 +316,10 @@ bch2_trans_journal_preres_get_cold(struct btree_trans *trans, unsigned u64s,
static __always_inline int bch2_trans_journal_res_get(struct btree_trans *trans,
unsigned flags)
{
- struct bch_fs *c = trans->c;
- int ret;
-
- ret = bch2_journal_res_get(&c->journal, &trans->journal_res,
- trans->journal_u64s,
- flags|
- (trans->flags & JOURNAL_WATERMARK_MASK));
-
- return ret == -EAGAIN ? BTREE_INSERT_NEED_JOURNAL_RES : ret;
+ return bch2_journal_res_get(&trans->c->journal, &trans->journal_res,
+ trans->journal_u64s,
+ flags|
+ (trans->flags & JOURNAL_WATERMARK_MASK));
}
#define JSET_ENTRY_LOG_U64s 4
@@ -343,23 +338,20 @@ static void journal_transaction_name(struct btree_trans *trans)
strncpy(l->d, trans->fn, JSET_ENTRY_LOG_U64s * sizeof(u64));
}
-static inline enum btree_insert_ret
-btree_key_can_insert(struct btree_trans *trans,
- struct btree *b,
- unsigned u64s)
+static inline int btree_key_can_insert(struct btree_trans *trans,
+ struct btree *b, unsigned u64s)
{
struct bch_fs *c = trans->c;
if (!bch2_btree_node_insert_fits(c, b, u64s))
- return BTREE_INSERT_BTREE_NODE_FULL;
+ return -BCH_ERR_btree_insert_btree_node_full;
- return BTREE_INSERT_OK;
+ return 0;
}
-static enum btree_insert_ret
-btree_key_can_insert_cached(struct btree_trans *trans,
- struct btree_path *path,
- unsigned u64s)
+static int btree_key_can_insert_cached(struct btree_trans *trans,
+ struct btree_path *path,
+ unsigned u64s)
{
struct bch_fs *c = trans->c;
struct bkey_cached *ck = (void *) path->l[0].b;
@@ -372,7 +364,7 @@ btree_key_can_insert_cached(struct btree_trans *trans,
if (!test_bit(BKEY_CACHED_DIRTY, &ck->flags) &&
bch2_btree_key_cache_must_wait(c) &&
!(trans->flags & BTREE_INSERT_JOURNAL_RECLAIM))
- return BTREE_INSERT_NEED_JOURNAL_RECLAIM;
+ return -BCH_ERR_btree_insert_need_journal_reclaim;
/*
* bch2_varint_decode can read past the end of the buffer by at most 7
@@ -381,7 +373,7 @@ btree_key_can_insert_cached(struct btree_trans *trans,
u64s += 1;
if (u64s <= ck->u64s)
- return BTREE_INSERT_OK;
+ return 0;
new_u64s = roundup_pow_of_two(u64s);
new_k = krealloc(ck->k, new_u64s * sizeof(u64), GFP_NOFS);
@@ -646,21 +638,13 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
trans->journal_res.seq = c->journal.replay_journal_seq;
}
- if (unlikely(trans->extra_journal_entries.nr)) {
- memcpy_u64s_small(journal_res_entry(&c->journal, &trans->journal_res),
- trans->extra_journal_entries.data,
- trans->extra_journal_entries.nr);
-
- trans->journal_res.offset += trans->extra_journal_entries.nr;
- trans->journal_res.u64s -= trans->extra_journal_entries.nr;
- }
-
/*
* Not allowed to fail after we've gotten our journal reservation - we
* have to use it:
*/
- if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) {
+ if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG) &&
+ !(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) {
if (bch2_journal_seq_verify)
trans_for_each_update(trans, i)
i->k->k.version.lo = trans->journal_res.seq;
@@ -671,7 +655,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
if (trans->fs_usage_deltas &&
bch2_trans_fs_usage_apply(trans, trans->fs_usage_deltas))
- return BTREE_INSERT_NEED_MARK_REPLICAS;
+ return -BCH_ERR_btree_insert_need_mark_replicas;
trans_for_each_update(trans, i)
if (BTREE_NODE_TYPE_HAS_MEM_TRIGGERS & (1U << i->bkey_type)) {
@@ -686,6 +670,15 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
return ret;
}
+ if (unlikely(trans->extra_journal_entries.nr)) {
+ memcpy_u64s_small(journal_res_entry(&c->journal, &trans->journal_res),
+ trans->extra_journal_entries.data,
+ trans->extra_journal_entries.nr);
+
+ trans->journal_res.offset += trans->extra_journal_entries.nr;
+ trans->journal_res.u64s -= trans->extra_journal_entries.nr;
+ }
+
if (likely(!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))) {
trans_for_each_update(trans, i) {
struct journal *j = &c->journal;
@@ -844,7 +837,7 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
&trans->journal_preres, trans->journal_preres_u64s,
JOURNAL_RES_GET_NONBLOCK|
(trans->flags & JOURNAL_WATERMARK_MASK));
- if (unlikely(ret == -EAGAIN))
+ if (unlikely(ret == -BCH_ERR_journal_preres_get_blocked))
ret = bch2_trans_journal_preres_get_cold(trans,
trans->journal_preres_u64s, trace_ip);
if (unlikely(ret))
@@ -900,12 +893,12 @@ int bch2_trans_commit_error(struct btree_trans *trans,
struct bch_fs *c = trans->c;
switch (ret) {
- case BTREE_INSERT_BTREE_NODE_FULL:
+ case -BCH_ERR_btree_insert_btree_node_full:
ret = bch2_btree_split_leaf(trans, i->path, trans->flags);
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
trace_and_count(c, trans_restart_btree_node_split, trans, trace_ip, i->path);
break;
- case BTREE_INSERT_NEED_MARK_REPLICAS:
+ case -BCH_ERR_btree_insert_need_mark_replicas:
bch2_trans_unlock(trans);
ret = bch2_replicas_delta_list_mark(c, trans->fs_usage_deltas);
@@ -916,7 +909,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
if (ret)
trace_and_count(c, trans_restart_mark_replicas, trans, trace_ip);
break;
- case BTREE_INSERT_NEED_JOURNAL_RES:
+ case -BCH_ERR_journal_res_get_blocked:
bch2_trans_unlock(trans);
if ((trans->flags & BTREE_INSERT_JOURNAL_RECLAIM) &&
@@ -933,7 +926,7 @@ int bch2_trans_commit_error(struct btree_trans *trans,
if (ret)
trace_and_count(c, trans_restart_journal_res_get, trans, trace_ip);
break;
- case BTREE_INSERT_NEED_JOURNAL_RECLAIM:
+ case -BCH_ERR_btree_insert_need_journal_reclaim:
bch2_trans_unlock(trans);
trace_and_count(c, trans_blocked_journal_reclaim, trans, trace_ip);
@@ -970,7 +963,7 @@ bch2_trans_commit_get_rw_cold(struct btree_trans *trans)
if (likely(!(trans->flags & BTREE_INSERT_LAZY_RW)) ||
test_bit(BCH_FS_STARTED, &c->flags))
- return -EROFS;
+ return -BCH_ERR_erofs_trans_commit;
bch2_trans_unlock(trans);
@@ -1734,18 +1727,25 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
return ret;
}
-int bch2_trans_log_msg(struct btree_trans *trans, const char *msg)
+static int __bch2_trans_log_msg(darray_u64 *entries, const char *fmt, va_list args)
{
- unsigned len = strlen(msg);
- unsigned u64s = DIV_ROUND_UP(len, sizeof(u64));
+ struct printbuf buf = PRINTBUF;
struct jset_entry_log *l;
+ unsigned u64s;
int ret;
- ret = darray_make_room(&trans->extra_journal_entries, jset_u64s(u64s));
+ prt_vprintf(&buf, fmt, args);
+ ret = buf.allocation_failure ? -ENOMEM : 0;
if (ret)
- return ret;
+ goto err;
- l = (void *) &darray_top(trans->extra_journal_entries);
+ u64s = DIV_ROUND_UP(buf.pos, sizeof(u64));
+
+ ret = darray_make_room(entries, jset_u64s(u64s));
+ if (ret)
+ goto err;
+
+ l = (void *) &darray_top(*entries);
l->entry.u64s = cpu_to_le16(u64s);
l->entry.btree_id = 0;
l->entry.level = 1;
@@ -1753,10 +1753,44 @@ int bch2_trans_log_msg(struct btree_trans *trans, const char *msg)
l->entry.pad[0] = 0;
l->entry.pad[1] = 0;
l->entry.pad[2] = 0;
- memcpy(l->d, msg, len);
- while (len & 7)
- l->d[len++] = '\0';
+ memcpy(l->d, buf.buf, buf.pos);
+ while (buf.pos & 7)
+ l->d[buf.pos++] = '\0';
+
+ entries->nr += jset_u64s(u64s);
+err:
+ printbuf_exit(&buf);
+ return ret;
+}
+
+int bch2_trans_log_msg(struct btree_trans *trans, const char *fmt, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, fmt);
+ ret = __bch2_trans_log_msg(&trans->extra_journal_entries, fmt, args);
+ va_end(args);
+
+ return ret;
+}
+
+int bch2_fs_log_msg(struct bch_fs *c, const char *fmt, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, fmt);
+
+ if (!test_bit(JOURNAL_STARTED, &c->journal.flags)) {
+ ret = __bch2_trans_log_msg(&c->journal.early_journal_entries, fmt, args);
+ } else {
+ ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_LAZY_RW,
+ __bch2_trans_log_msg(&trans.extra_journal_entries, fmt, args));
+ }
+
+ va_end(args);
+
+ return ret;
- trans->extra_journal_entries.nr += jset_u64s(u64s);
- return 0;
}