summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_update_interior.h
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_update_interior.h')
-rw-r--r--libbcachefs/btree_update_interior.h47
1 files changed, 39 insertions, 8 deletions
diff --git a/libbcachefs/btree_update_interior.h b/libbcachefs/btree_update_interior.h
index 23ee3980..0b58ccc9 100644
--- a/libbcachefs/btree_update_interior.h
+++ b/libbcachefs/btree_update_interior.h
@@ -2,6 +2,7 @@
#define _BCACHEFS_BTREE_UPDATE_INTERIOR_H
#include "btree_cache.h"
+#include "btree_locking.h"
#include "btree_update.h"
struct btree_reserve {
@@ -61,9 +62,12 @@ struct btree_update {
BTREE_INTERIOR_UPDATING_ROOT,
BTREE_INTERIOR_UPDATING_AS,
} mode;
+
+ unsigned must_rewrite:1;
+ unsigned nodes_written:1;
+
enum btree_id btree_id;
- unsigned flags;
struct btree_reserve *reserve;
/*
@@ -120,8 +124,6 @@ struct btree_update {
u64 inline_keys[BKEY_BTREE_PTR_U64s_MAX * 3];
};
-#define BTREE_INTERIOR_UPDATE_MUST_REWRITE (1 << 0)
-
#define for_each_pending_btree_node_free(c, as, p) \
list_for_each_entry(as, &c->btree_interior_update_list, list) \
for (p = as->pending; p < as->pending + as->nr_pending; p++)
@@ -146,8 +148,34 @@ void bch2_btree_interior_update_will_free_node(struct btree_update *,
void bch2_btree_insert_node(struct btree_update *, struct btree *,
struct btree_iter *, struct keylist *);
int bch2_btree_split_leaf(struct bch_fs *, struct btree_iter *, unsigned);
-int bch2_foreground_maybe_merge(struct bch_fs *, struct btree_iter *,
- enum btree_node_sibling);
+
+int __bch2_foreground_maybe_merge(struct bch_fs *, struct btree_iter *,
+ unsigned, enum btree_node_sibling);
+
+static inline int bch2_foreground_maybe_merge_sibling(struct bch_fs *c,
+ struct btree_iter *iter,
+ unsigned level,
+ enum btree_node_sibling sib)
+{
+ struct btree *b;
+
+ if (!bch2_btree_node_relock(iter, level))
+ return 0;
+
+ b = iter->l[level].b;
+ if (b->sib_u64s[sib] > c->btree_foreground_merge_threshold)
+ return 0;
+
+ return __bch2_foreground_maybe_merge(c, iter, level, sib);
+}
+
+static inline void bch2_foreground_maybe_merge(struct bch_fs *c,
+ struct btree_iter *iter,
+ unsigned level)
+{
+ bch2_foreground_maybe_merge_sibling(c, iter, level, btree_prev_sib);
+ bch2_foreground_maybe_merge_sibling(c, iter, level, btree_next_sib);
+}
void bch2_btree_set_root_for_read(struct bch_fs *, struct btree *);
void bch2_btree_root_alloc(struct bch_fs *, enum btree_id);
@@ -220,16 +248,17 @@ static inline struct btree_node_entry *want_new_bset(struct bch_fs *c,
struct bset *i = btree_bset_last(b);
unsigned offset = max_t(unsigned, b->written << 9,
bset_byte_offset(b, vstruct_end(i)));
- ssize_t n = (ssize_t) btree_bytes(c) - (ssize_t)
+ ssize_t remaining_space = (ssize_t) btree_bytes(c) - (ssize_t)
(offset + sizeof(struct btree_node_entry) +
b->whiteout_u64s * sizeof(u64) +
b->uncompacted_whiteout_u64s * sizeof(u64));
EBUG_ON(offset > btree_bytes(c));
- if ((unlikely(bset_written(b, i)) && n > 0) ||
+ if ((unlikely(bset_written(b, i)) &&
+ remaining_space > block_bytes(c)) ||
(unlikely(vstruct_bytes(i) > btree_write_set_buffer(b)) &&
- n > btree_write_set_buffer(b)))
+ remaining_space > btree_write_set_buffer(b)))
return (void *) b->data + offset;
return NULL;
@@ -312,4 +341,6 @@ static inline bool journal_res_insert_fits(struct btree_insert *trans,
return u64s <= trans->journal_res.u64s;
}
+ssize_t bch2_btree_updates_print(struct bch_fs *, char *);
+
#endif /* _BCACHEFS_BTREE_UPDATE_INTERIOR_H */