Update bcachefs sources to d3422f9b18 bcachefs: Journal initialization fixes

This commit is contained in:
Kent Overstreet 2021-12-21 21:53:07 -05:00
parent 11e4e302de
commit 00f49f23b4
12 changed files with 65 additions and 48 deletions

View File

@ -1 +1 @@
ff3a76e1af04f51506f45e0f71d53f7e6dd51a75
d3422f9b18ea3154abe19d859f1a61c4fae9ccdc

View File

@ -152,6 +152,7 @@ long bch2_bucket_alloc_new_fs(struct bch_dev *ca)
for (b = buckets->first_bucket; b < buckets->nbuckets; b++)
if (is_available_bucket(buckets->b[b].mark) &&
(!ca->buckets_nouse || !test_bit(b, ca->buckets_nouse)) &&
!buckets->b[b].mark.owned_by_allocator)
goto success;
b = -1;

View File

@ -705,6 +705,7 @@ struct bch_fs {
struct btree_path_buf __percpu *btree_paths_bufs;
struct srcu_struct btree_trans_barrier;
bool btree_trans_barrier_initialized;
struct btree_key_cache btree_key_cache;

View File

@ -768,16 +768,17 @@ struct btree *bch2_btree_node_get(struct btree_trans *trans, struct btree_path *
EBUG_ON(level >= BTREE_MAX_DEPTH);
if (c->opts.btree_node_mem_ptr_optimization) {
b = btree_node_mem_ptr(k);
/*
* Check b->hash_val _before_ calling btree_node_lock() - this
* might not be the node we want anymore, and trying to lock the
* wrong node could cause an unneccessary transaction restart:
* Check b->hash_val _before_ calling btree_node_lock() - this might not
* be the node we want anymore, and trying to lock the wrong node could
* cause an unneccessary transaction restart:
*/
if (b && b->hash_val == btree_ptr_hash_val(k))
if (likely(c->opts.btree_node_mem_ptr_optimization &&
b &&
b->hash_val == btree_ptr_hash_val(k)))
goto lock_node;
}
retry:
b = btree_cache_find(bc, k);
if (unlikely(!b)) {

View File

@ -1818,12 +1818,14 @@ static struct btree_path *btree_path_alloc(struct btree_trans *trans,
return path;
}
struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached,
struct btree_path *bch2_path_get(struct btree_trans *trans,
enum btree_id btree_id, struct bpos pos,
unsigned locks_want, unsigned level,
bool intent, unsigned long ip)
unsigned flags, unsigned long ip)
{
struct btree_path *path, *path_pos = NULL;
bool cached = flags & BTREE_ITER_CACHED;
bool intent = flags & BTREE_ITER_INTENT;
int i;
BUG_ON(trans->restarted);
@ -1845,7 +1847,6 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached,
path_pos->level == level) {
__btree_path_get(path_pos, intent);
path = btree_path_set_pos(trans, path_pos, pos, intent, ip);
path->preserve = true;
} else {
path = btree_path_alloc(trans, path_pos);
path_pos = NULL;
@ -1854,7 +1855,6 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached,
path->pos = pos;
path->btree_id = btree_id;
path->cached = cached;
path->preserve = true;
path->uptodate = BTREE_ITER_NEED_TRAVERSE;
path->should_be_locked = false;
path->level = level;
@ -1869,6 +1869,9 @@ struct btree_path *bch2_path_get(struct btree_trans *trans, bool cached,
btree_trans_verify_sorted(trans);
}
if (!(flags & BTREE_ITER_NOPRESERVE))
path->preserve = true;
if (path->intent_ref)
locks_want = max(locks_want, level + 1);
@ -2625,13 +2628,8 @@ static void __bch2_trans_iter_init(struct btree_trans *trans,
iter->ip_allocated = ip;
#endif
iter->path = bch2_path_get(trans,
flags & BTREE_ITER_CACHED,
btree_id,
iter->pos,
locks_want,
depth,
flags & BTREE_ITER_INTENT, ip);
iter->path = bch2_path_get(trans, btree_id, iter->pos,
locks_want, depth, flags, ip);
}
void bch2_trans_iter_init(struct btree_trans *trans,
@ -2958,22 +2956,27 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
void bch2_fs_btree_iter_exit(struct bch_fs *c)
{
if (c->btree_trans_barrier_initialized)
cleanup_srcu_struct(&c->btree_trans_barrier);
mempool_exit(&c->btree_trans_mem_pool);
mempool_exit(&c->btree_paths_pool);
cleanup_srcu_struct(&c->btree_trans_barrier);
}
int bch2_fs_btree_iter_init(struct bch_fs *c)
{
unsigned nr = BTREE_ITER_MAX;
int ret;
INIT_LIST_HEAD(&c->btree_trans_list);
mutex_init(&c->btree_trans_lock);
return init_srcu_struct(&c->btree_trans_barrier) ?:
mempool_init_kmalloc_pool(&c->btree_paths_pool, 1,
ret = mempool_init_kmalloc_pool(&c->btree_paths_pool, 1,
sizeof(struct btree_path) * nr +
sizeof(struct btree_insert_entry) * nr) ?:
mempool_init_kmalloc_pool(&c->btree_trans_mem_pool, 1,
BTREE_TRANS_MEM_MAX);
BTREE_TRANS_MEM_MAX) ?:
init_srcu_struct(&c->btree_trans_barrier);
if (!ret)
c->btree_trans_barrier_initialized = true;
return ret;
}

View File

@ -134,9 +134,8 @@ bch2_btree_path_make_mut(struct btree_trans *, struct btree_path *,
bool, unsigned long);
int __must_check bch2_btree_path_traverse(struct btree_trans *,
struct btree_path *, unsigned);
struct btree_path *bch2_path_get(struct btree_trans *, bool, enum btree_id,
struct bpos, unsigned, unsigned, bool,
unsigned long);
struct btree_path *bch2_path_get(struct btree_trans *, enum btree_id, struct bpos,
unsigned, unsigned, unsigned, unsigned long);
inline struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *, struct bkey *);
#ifdef CONFIG_BCACHEFS_DEBUG

View File

@ -662,6 +662,7 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
rcu_read_lock();
tbl = rht_dereference_rcu(bc->table.tbl, &bc->table);
if (tbl)
for (i = 0; i < tbl->size; i++)
rht_for_each_entry_rcu(ck, pos, tbl, i, hash) {
bkey_cached_evict(bc, ck);

View File

@ -210,6 +210,7 @@ struct btree_node_iter {
#define __BTREE_ITER_ALL_SNAPSHOTS (1 << 11)
#define BTREE_ITER_ALL_SNAPSHOTS (1 << 12)
#define BTREE_ITER_FILTER_SNAPSHOTS (1 << 13)
#define BTREE_ITER_NOPRESERVE (1 << 14)
enum btree_path_uptodate {
BTREE_ITER_UPTODATE = 0,

View File

@ -1609,8 +1609,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
? bpos_predecessor(b->data->min_key)
: bpos_successor(b->data->max_key);
sib_path = bch2_path_get(trans, false, path->btree_id, sib_pos,
U8_MAX, level, true, _THIS_IP_);
sib_path = bch2_path_get(trans, path->btree_id, sib_pos,
U8_MAX, level, BTREE_ITER_INTENT, _THIS_IP_);
ret = bch2_btree_path_traverse(trans, sib_path, false);
if (ret)
goto err;

View File

@ -1271,24 +1271,23 @@ err:
* When deleting, check if we need to emit a whiteout (because we're overwriting
* something in an ancestor snapshot)
*/
static int need_whiteout_for_snapshot(struct btree_trans *trans, struct btree_iter *orig)
static int need_whiteout_for_snapshot(struct btree_trans *trans,
enum btree_id btree_id, struct bpos pos)
{
struct btree_iter iter;
struct bkey_s_c k;
u32 snapshot = orig->pos.snapshot;
u32 snapshot = pos.snapshot;
int ret;
if (!bch2_snapshot_parent(trans->c, snapshot))
if (!bch2_snapshot_parent(trans->c, pos.snapshot))
return 0;
bch2_trans_copy_iter(&iter, orig);
iter.flags &= BTREE_ITER_FILTER_SNAPSHOTS;
iter.flags |= BTREE_ITER_ALL_SNAPSHOTS;
pos.snapshot++;
bch2_btree_iter_advance(&iter);
for_each_btree_key_continue_norestart(iter, 0, k, ret) {
if (bkey_cmp(k.k->p, orig->pos))
for_each_btree_key_norestart(trans, iter, btree_id, pos,
BTREE_ITER_ALL_SNAPSHOTS|
BTREE_ITER_NOPRESERVE, k, ret) {
if (bkey_cmp(k.k->p, pos))
break;
if (bch2_snapshot_is_ancestor(trans->c, snapshot,
@ -1314,7 +1313,6 @@ int __must_check bch2_trans_update(struct btree_trans *trans, struct btree_iter
BUG_ON(trans->nr_updates >= BTREE_ITER_MAX);
BUG_ON(bpos_cmp(k->k.p, iter->path->pos));
BUG_ON(bpos_cmp(k->k.p, iter->pos));
n = (struct btree_insert_entry) {
.flags = flags,
@ -1335,7 +1333,7 @@ int __must_check bch2_trans_update(struct btree_trans *trans, struct btree_iter
if (bkey_deleted(&n.k->k) &&
(iter->flags & BTREE_ITER_FILTER_SNAPSHOTS)) {
int ret = need_whiteout_for_snapshot(trans, iter);
int ret = need_whiteout_for_snapshot(trans, n.btree_id, n.k->k.p);
if (unlikely(ret < 0))
return ret;

View File

@ -642,6 +642,7 @@ int bch2_journal_flush_seq(struct journal *j, u64 seq)
int bch2_journal_meta(struct journal *j)
{
struct journal_buf *buf;
struct journal_res res;
int ret;
@ -651,6 +652,10 @@ int bch2_journal_meta(struct journal *j)
if (ret)
return ret;
buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
buf->must_flush = true;
set_bit(JOURNAL_NEED_WRITE, &j->flags);
bch2_journal_res_put(j, &res);
return bch2_journal_flush_seq(j, res.seq);
@ -995,6 +1000,7 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
j->replay_journal_seq = last_seq;
j->replay_journal_seq_end = cur_seq;
j->last_seq_ondisk = last_seq;
j->flushed_seq_ondisk = last_seq;
j->pin.front = last_seq;
j->pin.back = cur_seq;
atomic64_set(&j->seq, cur_seq - 1);
@ -1011,6 +1017,9 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
if (seq < last_seq)
continue;
if (journal_entry_empty(&i->j))
j->last_empty_seq = le64_to_cpu(i->j.seq);
p = journal_seq_pin(j, seq);
p->devs.nr = 0;
@ -1018,6 +1027,9 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq,
bch2_dev_list_add_dev(&p->devs, i->ptrs[ptr].dev);
}
if (list_empty(journal_entries))
j->last_empty_seq = cur_seq;
spin_lock(&j->lock);
set_bit(JOURNAL_STARTED, &j->flags);

View File

@ -1448,7 +1448,7 @@ void bch2_journal_write(struct closure *cl)
SET_JSET_BIG_ENDIAN(jset, CPU_BIG_ENDIAN);
SET_JSET_CSUM_TYPE(jset, bch2_meta_checksum_type(c));
if (journal_entry_empty(jset))
if (!JSET_NO_FLUSH(jset) && journal_entry_empty(jset))
j->last_empty_seq = le64_to_cpu(jset->seq);
if (bch2_csum_type_is_encryption(JSET_CSUM_TYPE(jset)))