-40eaef7e8049b75ff7e5da42227295c754d9c906
+969fbff4ef3a75ae25ef7cca17dd4e028443bfc2
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);
/*
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);
&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;
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) {
}
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;
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
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 *);
* 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
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
#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);
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;
}
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);
{
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);
}
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(), \
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(), \
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;
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);
-
- 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;
-
- idx++;
- if (idx == keys->gap)
- idx += keys->size - keys->nr;
+ 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 (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;
+
+ iters++;
+ if (iters == 10) {
+ *idx = 0;
+ goto search;
+ }
}
return NULL;
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)
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)
} 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);
: "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;