bcachefs: Further improve btree_update_to_text()
Print start and end level of the btree update; also a bit of cleanup. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
9fb3036fe3
commit
d880a43836
@ -26,9 +26,9 @@
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
const char * const bch2_btree_update_modes[] = {
|
||||
static const char * const bch2_btree_update_modes[] = {
|
||||
#define x(t) #t,
|
||||
BCH_WATERMARKS()
|
||||
BTREE_UPDATE_MODES()
|
||||
#undef x
|
||||
NULL
|
||||
};
|
||||
@ -850,15 +850,17 @@ static void btree_update_updated_node(struct btree_update *as, struct btree *b)
|
||||
{
|
||||
struct bch_fs *c = as->c;
|
||||
|
||||
mutex_lock(&c->btree_interior_update_lock);
|
||||
list_add_tail(&as->unwritten_list, &c->btree_interior_updates_unwritten);
|
||||
|
||||
BUG_ON(as->mode != BTREE_UPDATE_none);
|
||||
BUG_ON(as->update_level_end < b->c.level);
|
||||
BUG_ON(!btree_node_dirty(b));
|
||||
BUG_ON(!b->c.level);
|
||||
|
||||
mutex_lock(&c->btree_interior_update_lock);
|
||||
list_add_tail(&as->unwritten_list, &c->btree_interior_updates_unwritten);
|
||||
|
||||
as->mode = BTREE_UPDATE_node;
|
||||
as->b = b;
|
||||
as->update_level_end = b->c.level;
|
||||
|
||||
set_btree_node_write_blocked(b);
|
||||
list_add(&as->write_blocked_list, &b->write_blocked);
|
||||
@ -1100,7 +1102,7 @@ static void bch2_btree_update_done(struct btree_update *as, struct btree_trans *
|
||||
|
||||
static struct btree_update *
|
||||
bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
|
||||
unsigned level, bool split, unsigned flags)
|
||||
unsigned level_start, bool split, unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_update *as;
|
||||
@ -1108,7 +1110,7 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
|
||||
int disk_res_flags = (flags & BCH_TRANS_COMMIT_no_enospc)
|
||||
? BCH_DISK_RESERVATION_NOFAIL : 0;
|
||||
unsigned nr_nodes[2] = { 0, 0 };
|
||||
unsigned update_level = level;
|
||||
unsigned level_end = level_start;
|
||||
enum bch_watermark watermark = flags & BCH_WATERMARK_MASK;
|
||||
int ret = 0;
|
||||
u32 restart_count = trans->restart_count;
|
||||
@ -1140,17 +1142,17 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
|
||||
}
|
||||
|
||||
while (1) {
|
||||
nr_nodes[!!update_level] += 1 + split;
|
||||
update_level++;
|
||||
nr_nodes[!!level_end] += 1 + split;
|
||||
level_end++;
|
||||
|
||||
ret = bch2_btree_path_upgrade(trans, path, update_level + 1);
|
||||
ret = bch2_btree_path_upgrade(trans, path, level_end + 1);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (!btree_path_node(path, update_level)) {
|
||||
if (!btree_path_node(path, level_end)) {
|
||||
/* Allocating new root? */
|
||||
nr_nodes[1] += split;
|
||||
update_level = BTREE_MAX_DEPTH;
|
||||
level_end = BTREE_MAX_DEPTH;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1158,11 +1160,11 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
|
||||
* Always check for space for two keys, even if we won't have to
|
||||
* split at prior level - it might have been a merge instead:
|
||||
*/
|
||||
if (bch2_btree_node_insert_fits(path->l[update_level].b,
|
||||
if (bch2_btree_node_insert_fits(path->l[level_end].b,
|
||||
BKEY_BTREE_PTR_U64s_MAX * 2))
|
||||
break;
|
||||
|
||||
split = path->l[update_level].b->nr.live_u64s > BTREE_SPLIT_THRESHOLD(c);
|
||||
split = path->l[level_end].b->nr.live_u64s > BTREE_SPLIT_THRESHOLD(c);
|
||||
}
|
||||
|
||||
if (!down_read_trylock(&c->gc_lock)) {
|
||||
@ -1176,14 +1178,15 @@ bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
|
||||
as = mempool_alloc(&c->btree_interior_update_pool, GFP_NOFS);
|
||||
memset(as, 0, sizeof(*as));
|
||||
closure_init(&as->cl, NULL);
|
||||
as->c = c;
|
||||
as->start_time = start_time;
|
||||
as->ip_started = _RET_IP_;
|
||||
as->mode = BTREE_UPDATE_none;
|
||||
as->watermark = watermark;
|
||||
as->took_gc_lock = true;
|
||||
as->btree_id = path->btree_id;
|
||||
as->update_level = update_level;
|
||||
as->c = c;
|
||||
as->start_time = start_time;
|
||||
as->ip_started = _RET_IP_;
|
||||
as->mode = BTREE_UPDATE_none;
|
||||
as->watermark = watermark;
|
||||
as->took_gc_lock = true;
|
||||
as->btree_id = path->btree_id;
|
||||
as->update_level_start = level_start;
|
||||
as->update_level_end = level_end;
|
||||
INIT_LIST_HEAD(&as->list);
|
||||
INIT_LIST_HEAD(&as->unwritten_list);
|
||||
INIT_LIST_HEAD(&as->write_blocked_list);
|
||||
@ -1373,12 +1376,12 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
|
||||
}
|
||||
|
||||
static void
|
||||
__bch2_btree_insert_keys_interior(struct btree_update *as,
|
||||
struct btree_trans *trans,
|
||||
struct btree_path *path,
|
||||
struct btree *b,
|
||||
struct btree_node_iter node_iter,
|
||||
struct keylist *keys)
|
||||
bch2_btree_insert_keys_interior(struct btree_update *as,
|
||||
struct btree_trans *trans,
|
||||
struct btree_path *path,
|
||||
struct btree *b,
|
||||
struct btree_node_iter node_iter,
|
||||
struct keylist *keys)
|
||||
{
|
||||
struct bkey_i *insert = bch2_keylist_front(keys);
|
||||
struct bkey_packed *k;
|
||||
@ -1534,7 +1537,7 @@ static void btree_split_insert_keys(struct btree_update *as,
|
||||
|
||||
bch2_btree_node_iter_init(&node_iter, b, &bch2_keylist_front(keys)->k.p);
|
||||
|
||||
__bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
|
||||
bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
|
||||
|
||||
BUG_ON(bch2_btree_node_check_topology(trans, b));
|
||||
}
|
||||
@ -1714,27 +1717,6 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static void
|
||||
bch2_btree_insert_keys_interior(struct btree_update *as,
|
||||
struct btree_trans *trans,
|
||||
struct btree_path *path,
|
||||
struct btree *b,
|
||||
struct keylist *keys)
|
||||
{
|
||||
struct btree_path *linked;
|
||||
unsigned i;
|
||||
|
||||
__bch2_btree_insert_keys_interior(as, trans, path, b,
|
||||
path->l[b->c.level].iter, keys);
|
||||
|
||||
btree_update_updated_node(as, b);
|
||||
|
||||
trans_for_each_path_with_node(trans, b, linked, i)
|
||||
bch2_btree_node_iter_peek(&linked->l[b->c.level].iter, b);
|
||||
|
||||
bch2_trans_verify_paths(trans);
|
||||
}
|
||||
|
||||
/**
|
||||
* bch2_btree_insert_node - insert bkeys into a given btree node
|
||||
*
|
||||
@ -1755,7 +1737,8 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
|
||||
struct keylist *keys)
|
||||
{
|
||||
struct bch_fs *c = as->c;
|
||||
struct btree_path *path = trans->paths + path_idx;
|
||||
struct btree_path *path = trans->paths + path_idx, *linked;
|
||||
unsigned i;
|
||||
int old_u64s = le16_to_cpu(btree_bset_last(b)->u64s);
|
||||
int old_live_u64s = b->nr.live_u64s;
|
||||
int live_u64s_added, u64s_added;
|
||||
@ -1784,7 +1767,13 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
|
||||
return ret;
|
||||
}
|
||||
|
||||
bch2_btree_insert_keys_interior(as, trans, path, b, keys);
|
||||
bch2_btree_insert_keys_interior(as, trans, path, b,
|
||||
path->l[b->c.level].iter, keys);
|
||||
|
||||
trans_for_each_path_with_node(trans, b, linked, i)
|
||||
bch2_btree_node_iter_peek(&linked->l[b->c.level].iter, b);
|
||||
|
||||
bch2_trans_verify_paths(trans);
|
||||
|
||||
live_u64s_added = (int) b->nr.live_u64s - old_live_u64s;
|
||||
u64s_added = (int) le16_to_cpu(btree_bset_last(b)->u64s) - old_u64s;
|
||||
@ -1798,6 +1787,7 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
|
||||
bch2_maybe_compact_whiteouts(c, b))
|
||||
bch2_trans_node_reinit_iter(trans, b);
|
||||
|
||||
btree_update_updated_node(as, b);
|
||||
bch2_btree_node_unlock_write(trans, path, b);
|
||||
|
||||
BUG_ON(bch2_btree_node_check_topology(trans, b));
|
||||
@ -1807,7 +1797,7 @@ split:
|
||||
* We could attempt to avoid the transaction restart, by calling
|
||||
* bch2_btree_path_upgrade() and allocating more nodes:
|
||||
*/
|
||||
if (b->c.level >= as->update_level) {
|
||||
if (b->c.level >= as->update_level_end) {
|
||||
trace_and_count(c, trans_restart_split_race, trans, _THIS_IP_, b);
|
||||
return btree_trans_restart(trans, BCH_ERR_transaction_restart_split_race);
|
||||
}
|
||||
@ -2519,9 +2509,11 @@ void bch2_btree_root_alloc_fake(struct bch_fs *c, enum btree_id id, unsigned lev
|
||||
|
||||
static void bch2_btree_update_to_text(struct printbuf *out, struct btree_update *as)
|
||||
{
|
||||
prt_printf(out, "%ps: btree=%s watermark=%s mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n",
|
||||
prt_printf(out, "%ps: btree=%s l=%u-%u watermark=%s mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n",
|
||||
(void *) as->ip_started,
|
||||
bch2_btree_id_str(as->btree_id),
|
||||
as->update_level_start,
|
||||
as->update_level_end,
|
||||
bch2_watermarks[as->watermark],
|
||||
bch2_btree_update_modes[as->mode],
|
||||
as->nodes_written,
|
||||
|
@ -57,7 +57,8 @@ struct btree_update {
|
||||
unsigned took_gc_lock:1;
|
||||
|
||||
enum btree_id btree_id;
|
||||
unsigned update_level;
|
||||
unsigned update_level_start;
|
||||
unsigned update_level_end;
|
||||
|
||||
struct disk_reservation disk_res;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user