diff --git a/.bcachefs_revision b/.bcachefs_revision index c1cb5fdb..96185653 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -40eaef7e8049b75ff7e5da42227295c754d9c906 +969fbff4ef3a75ae25ef7cca17dd4e028443bfc2 diff --git a/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h index 1bea79cf..f9fde128 100644 --- a/libbcachefs/bcachefs_format.h +++ b/libbcachefs/bcachefs_format.h @@ -1553,6 +1553,7 @@ LE64_BITMASK(BCH_SB_INODES_USE_KEY_CACHE,struct bch_sb, flags[3], 29, 30); LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DELAY,struct bch_sb, flags[3], 30, 62); LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DISABLED,struct bch_sb, flags[3], 62, 63); LE64_BITMASK(BCH_SB_JOURNAL_RECLAIM_DELAY,struct bch_sb, flags[4], 0, 32); +/* Obsolete, always enabled: */ LE64_BITMASK(BCH_SB_JOURNAL_TRANSACTION_NAMES,struct bch_sb, flags[4], 32, 33); /* diff --git a/libbcachefs/btree_io.c b/libbcachefs/btree_io.c index 7a883922..ff390c51 100644 --- a/libbcachefs/btree_io.c +++ b/libbcachefs/btree_io.c @@ -1146,10 +1146,12 @@ static void btree_node_read_work(struct work_struct *work) struct bch_io_failures failed = { .nr = 0 }; struct printbuf buf = PRINTBUF; bool saw_error = false; + bool retry = false; bool can_retry; goto start; while (1) { + retry = true; bch_info(c, "retrying read"); ca = bch_dev_bkey_exists(c, rb->pick.ptr.dev); rb->have_ioref = bch2_dev_get_ioref(ca, READ); @@ -1180,8 +1182,11 @@ start: &failed, &rb->pick) > 0; if (!bio->bi_status && - !bch2_btree_node_read_done(c, ca, b, can_retry)) + !bch2_btree_node_read_done(c, ca, b, can_retry)) { + if (retry) + bch_info(c, "retry success"); break; + } saw_error = true; diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c index e7541af9..b81a55b2 100644 --- a/libbcachefs/btree_iter.c +++ b/libbcachefs/btree_iter.c @@ -2248,14 +2248,38 @@ static inline struct bkey_i *btree_trans_peek_updates(struct btree_trans *trans, return NULL; } +struct bkey_i *bch2_btree_journal_peek(struct btree_trans *trans, + struct btree_iter *iter, + struct bpos start_pos, + struct bpos end_pos) +{ + struct bkey_i *k; + + if (bpos_cmp(start_pos, iter->journal_pos) < 0) + iter->journal_idx = 0; + + k = bch2_journal_keys_peek_upto(trans->c, iter->btree_id, 0, + start_pos, end_pos, + &iter->journal_idx); + + iter->journal_pos = k ? k->k.p : end_pos; + return k; +} + +struct bkey_i *bch2_btree_journal_peek_slot(struct btree_trans *trans, + struct btree_iter *iter, + struct bpos pos) +{ + return bch2_btree_journal_peek(trans, iter, pos, pos); +} + static noinline struct bkey_s_c btree_trans_peek_journal(struct btree_trans *trans, struct btree_iter *iter, struct bkey_s_c k) { struct bkey_i *next_journal = - bch2_journal_keys_peek_upto(trans->c, iter->btree_id, 0, - iter->path->pos, + bch2_btree_journal_peek(trans, iter, iter->path->pos, k.k ? k.k->p : iter->path->l[0].b->key.k.p); if (next_journal) { @@ -2804,10 +2828,8 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) } if (unlikely(iter->flags & BTREE_ITER_WITH_JOURNAL) && - (next_update = bch2_journal_keys_peek_slot(trans->c, - iter->btree_id, - iter->path->level, - iter->pos))) { + (next_update = bch2_btree_journal_peek_slot(trans, + iter, iter->pos))) { iter->k = next_update->k; k = bkey_i_to_s_c(next_update); goto out; @@ -3074,6 +3096,8 @@ static void __bch2_trans_iter_init(struct btree_trans *trans, iter->k.type = KEY_TYPE_deleted; iter->k.p = pos; iter->k.size = 0; + iter->journal_idx = 0; + iter->journal_pos = POS_MIN; #ifdef CONFIG_BCACHEFS_DEBUG iter->ip_allocated = ip; #endif diff --git a/libbcachefs/btree_iter.h b/libbcachefs/btree_iter.h index dad05ea0..f2b302c8 100644 --- a/libbcachefs/btree_iter.h +++ b/libbcachefs/btree_iter.h @@ -138,6 +138,9 @@ struct btree_path *bch2_path_get(struct btree_trans *, enum btree_id, struct bpo unsigned, unsigned, unsigned, unsigned long); inline struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *, struct bkey *); +struct bkey_i *bch2_btree_journal_peek_slot(struct btree_trans *, + struct btree_iter *, struct bpos); + #ifdef CONFIG_BCACHEFS_DEBUG void bch2_trans_verify_paths(struct btree_trans *); void bch2_trans_verify_locks(struct btree_trans *); diff --git a/libbcachefs/btree_types.h b/libbcachefs/btree_types.h index e4ed46a4..a1c04419 100644 --- a/libbcachefs/btree_types.h +++ b/libbcachefs/btree_types.h @@ -292,6 +292,10 @@ struct btree_iter { * bch2_btree_iter_next_slot() can correctly advance pos. */ struct bkey k; + + /* BTREE_ITER_WITH_JOURNAL: */ + size_t journal_idx; + struct bpos journal_pos; #ifdef CONFIG_BCACHEFS_DEBUG unsigned long ip_allocated; #endif @@ -393,7 +397,6 @@ struct btree_trans { bool in_traverse_all:1; bool restarted:1; bool memory_allocation_failure:1; - bool journal_transaction_names:1; bool is_initial_gc:1; /* * For when bch2_trans_update notices we'll be splitting a compressed diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c index 58bb687a..e34bc967 100644 --- a/libbcachefs/btree_update_leaf.c +++ b/libbcachefs/btree_update_leaf.c @@ -305,7 +305,7 @@ static inline int bch2_trans_journal_res_get(struct btree_trans *trans, #define JSET_ENTRY_LOG_U64s 4 -static noinline void journal_transaction_name(struct btree_trans *trans) +static void journal_transaction_name(struct btree_trans *trans) { struct bch_fs *c = trans->c; struct jset_entry *entry = journal_res_entry(&c->journal, &trans->journal_res); @@ -684,8 +684,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, if (ret) return ret; - if (unlikely(trans->journal_transaction_names)) - journal_transaction_name(trans); + journal_transaction_name(trans); } else { trans->journal_res.seq = c->journal.replay_journal_seq; } @@ -1118,10 +1117,8 @@ int __bch2_trans_commit(struct btree_trans *trans) trans->journal_u64s = trans->extra_journal_entries.nr; trans->journal_preres_u64s = 0; - trans->journal_transaction_names = READ_ONCE(c->opts.journal_transaction_names); - - if (trans->journal_transaction_names) - trans->journal_u64s += JSET_ENTRY_LOG_U64s; + /* For journalling transaction name: */ + trans->journal_u64s += JSET_ENTRY_LOG_U64s; trans_for_each_update(trans, i) { BUG_ON(!i->path->should_be_locked); diff --git a/libbcachefs/checksum.c b/libbcachefs/checksum.c index 50157b40..317efd04 100644 --- a/libbcachefs/checksum.c +++ b/libbcachefs/checksum.c @@ -116,7 +116,12 @@ static inline int do_encrypt(struct crypto_sync_skcipher *tfm, { struct scatterlist sg; - sg_init_one(&sg, buf, len); + sg_init_table(&sg, 1); + sg_set_page(&sg, + is_vmalloc_addr(buf) + ? vmalloc_to_page(buf) + : virt_to_page(buf), + len, offset_in_page(buf)); return do_encrypt_sg(tfm, nonce, &sg, len); } diff --git a/libbcachefs/opts.h b/libbcachefs/opts.h index 6a1cd41e..54e3575f 100644 --- a/libbcachefs/opts.h +++ b/libbcachefs/opts.h @@ -165,22 +165,22 @@ enum opt_type { OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ OPT_FN(bch2_opt_target), \ BCH_SB_METADATA_TARGET, 0, \ - "(target)", "Device or disk group for metadata writes") \ + "(target)", "Device or label for metadata writes") \ x(foreground_target, u16, \ OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ OPT_FN(bch2_opt_target), \ BCH_SB_FOREGROUND_TARGET, 0, \ - "(target)", "Device or disk group for foreground writes") \ + "(target)", "Device or label for foreground writes") \ x(background_target, u16, \ OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ OPT_FN(bch2_opt_target), \ BCH_SB_BACKGROUND_TARGET, 0, \ - "(target)", "Device or disk group to move data to in the background")\ + "(target)", "Device or label to move data to in the background")\ x(promote_target, u16, \ OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ OPT_FN(bch2_opt_target), \ BCH_SB_PROMOTE_TARGET, 0, \ - "(target)", "Device or disk group to promote data to on read")\ + "(target)", "Device or label to promote data to on read") \ x(erasure_code, u16, \ OPT_FS|OPT_INODE|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ @@ -331,11 +331,6 @@ enum opt_type { OPT_BOOL(), \ BCH2_NO_SB_OPT, false, \ NULL, "Only read the journal, skip the rest of recovery")\ - x(journal_transaction_names, u8, \ - OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \ - OPT_BOOL(), \ - BCH_SB_JOURNAL_TRANSACTION_NAMES, true, \ - NULL, "Log transaction function names in journal") \ x(noexcl, u8, \ OPT_FS|OPT_MOUNT, \ OPT_BOOL(), \ diff --git a/libbcachefs/recovery.c b/libbcachefs/recovery.c index 36ab2e3b..04afe245 100644 --- a/libbcachefs/recovery.c +++ b/libbcachefs/recovery.c @@ -86,9 +86,9 @@ static inline struct journal_key *idx_to_key(struct journal_keys *keys, size_t i return keys->d + idx_to_pos(keys, idx); } -size_t bch2_journal_key_search(struct journal_keys *keys, - enum btree_id id, unsigned level, - struct bpos pos) +static size_t bch2_journal_key_search(struct journal_keys *keys, + enum btree_id id, unsigned level, + struct bpos pos) { size_t l = 0, r = keys->nr, m; @@ -111,21 +111,31 @@ size_t bch2_journal_key_search(struct journal_keys *keys, struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *c, enum btree_id btree_id, unsigned level, struct bpos pos, - struct bpos end_pos) + struct bpos end_pos, size_t *idx) { struct journal_keys *keys = &c->journal_keys; - size_t idx = bch2_journal_key_search(keys, btree_id, level, pos); + unsigned iters = 0; +search: + if (!*idx) + *idx = bch2_journal_key_search(keys, btree_id, level, pos); - while (idx < keys->size && - keys->d[idx].btree_id == btree_id && - keys->d[idx].level == level && - bpos_cmp(keys->d[idx].k->k.p, end_pos) <= 0) { - if (!keys->d[idx].overwritten) - return keys->d[idx].k; + while (*idx < keys->size && + keys->d[*idx].btree_id == btree_id && + keys->d[*idx].level == level && + bpos_cmp(keys->d[*idx].k->k.p, end_pos) <= 0) { + if (bpos_cmp(keys->d[*idx].k->k.p, pos) >= 0 && + !keys->d[*idx].overwritten) + return keys->d[*idx].k; - idx++; - if (idx == keys->gap) - idx += keys->size - keys->nr; + (*idx)++; + if (*idx == keys->gap) + *idx += keys->size - keys->nr; + + iters++; + if (iters == 10) { + *idx = 0; + goto search; + } } return NULL; @@ -134,7 +144,9 @@ struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *c, enum btree_id btree struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *c, enum btree_id btree_id, unsigned level, struct bpos pos) { - return bch2_journal_keys_peek_upto(c, btree_id, level, pos, pos); + size_t idx = 0; + + return bch2_journal_keys_peek_upto(c, btree_id, level, pos, pos, &idx); } static void journal_iters_fix(struct bch_fs *c) @@ -1246,7 +1258,7 @@ use_clean: set_bit(BCH_FS_MAY_GO_RW, &c->flags); - bch_verbose(c, "starting journal replay, %zu keys", c->journal_keys.nr); + bch_info(c, "starting journal replay, %zu keys", c->journal_keys.nr); err = "journal replay failed"; ret = bch2_journal_replay(c); if (ret) diff --git a/libbcachefs/recovery.h b/libbcachefs/recovery.h index e05aac64..52db06b2 100644 --- a/libbcachefs/recovery.h +++ b/libbcachefs/recovery.h @@ -28,10 +28,8 @@ struct btree_and_journal_iter { } last; }; -size_t bch2_journal_key_search(struct journal_keys *, enum btree_id, - unsigned, struct bpos); struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *, enum btree_id, - unsigned, struct bpos, struct bpos); + unsigned, struct bpos, struct bpos, size_t *); struct bkey_i *bch2_journal_keys_peek_slot(struct bch_fs *, enum btree_id, unsigned, struct bpos); diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c index a2b789b4..0b9fbb52 100644 --- a/libbcachefs/super-io.c +++ b/libbcachefs/super-io.c @@ -1058,7 +1058,7 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, : "unknown"); pr_newline(out); - pr_buf(out, "Group:"); + pr_buf(out, "Label:"); pr_tab(out); if (BCH_MEMBER_GROUP(m)) { unsigned idx = BCH_MEMBER_GROUP(m) - 1;