Commit d0734356 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Deduplicate keys in the journal before replay

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 644d180b
......@@ -12,7 +12,7 @@
#include "debug.h"
#include "ec.h"
#include "error.h"
#include "journal_io.h"
#include "recovery.h"
#include "trace.h"
#include <linux/kthread.h>
......@@ -261,13 +261,13 @@ static void bch2_alloc_read_key(struct bch_fs *c, struct bkey_s_c k)
percpu_up_read(&c->mark_lock);
}
int bch2_alloc_read(struct bch_fs *c, struct list_head *journal_replay_list)
int bch2_alloc_read(struct bch_fs *c, struct journal_keys *journal_keys)
{
struct journal_replay *r;
struct btree_trans trans;
struct btree_iter *iter;
struct bkey_s_c k;
struct bch_dev *ca;
struct journal_key *j;
unsigned i;
int ret;
......@@ -282,14 +282,9 @@ int bch2_alloc_read(struct bch_fs *c, struct list_head *journal_replay_list)
if (ret)
return ret;
list_for_each_entry(r, journal_replay_list, list) {
struct bkey_i *k, *n;
struct jset_entry *entry;
for_each_jset_key(k, n, entry, &r->j)
if (entry->btree_id == BTREE_ID_ALLOC)
bch2_alloc_read_key(c, bkey_i_to_s_c(k));
}
for_each_journal_key(*journal_keys, j)
if (j->btree_id == BTREE_ID_ALLOC)
bch2_alloc_read_key(c, bkey_i_to_s_c(j->k));
percpu_down_write(&c->mark_lock);
bch2_dev_usage_from_buckets(c);
......
......@@ -25,7 +25,8 @@ void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
.val_to_text = bch2_alloc_to_text, \
}
int bch2_alloc_read(struct bch_fs *, struct list_head *);
struct journal_keys;
int bch2_alloc_read(struct bch_fs *, struct journal_keys *);
int bch2_alloc_replay_key(struct bch_fs *, struct bkey_i *);
static inline void bch2_wake_allocator(struct bch_dev *ca)
......
......@@ -19,9 +19,9 @@
#include "error.h"
#include "extents.h"
#include "journal.h"
#include "journal_io.h"
#include "keylist.h"
#include "move.h"
#include "recovery.h"
#include "replicas.h"
#include "super-io.h"
#include "trace.h"
......@@ -273,7 +273,7 @@ static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r)
(int) btree_id_to_gc_phase(r);
}
static int bch2_gc_btrees(struct bch_fs *c, struct list_head *journal,
static int bch2_gc_btrees(struct bch_fs *c, struct journal_keys *journal_keys,
bool initial, bool metadata_only)
{
enum btree_id ids[BTREE_ID_NR];
......@@ -292,25 +292,21 @@ static int bch2_gc_btrees(struct bch_fs *c, struct list_head *journal,
if (ret)
return ret;
if (journal && !metadata_only &&
if (journal_keys && !metadata_only &&
btree_node_type_needs_gc(type)) {
struct bkey_i *k, *n;
struct jset_entry *j;
struct journal_replay *r;
struct journal_key *j;
int ret;
list_for_each_entry(r, journal, list)
for_each_jset_key(k, n, j, &r->j) {
if (type == __btree_node_type(j->level, j->btree_id)) {
for_each_journal_key(*journal_keys, j)
if (j->btree_id == id) {
ret = bch2_gc_mark_key(c,
bkey_i_to_s_c(k),
bkey_i_to_s_c(j->k),
&max_stale, initial);
if (ret)
return ret;
}
}
}
}
return 0;
}
......@@ -695,7 +691,7 @@ static int bch2_gc_start(struct bch_fs *c,
* move around - if references move backwards in the ordering GC
* uses, GC could skip past them
*/
int bch2_gc(struct bch_fs *c, struct list_head *journal,
int bch2_gc(struct bch_fs *c, struct journal_keys *journal_keys,
bool initial, bool metadata_only)
{
struct bch_dev *ca;
......@@ -716,7 +712,7 @@ int bch2_gc(struct bch_fs *c, struct list_head *journal,
bch2_mark_superblocks(c);
ret = bch2_gc_btrees(c, journal, initial, metadata_only);
ret = bch2_gc_btrees(c, journal_keys, initial, metadata_only);
if (ret)
goto out;
......
......@@ -5,7 +5,9 @@
#include "btree_types.h"
void bch2_coalesce(struct bch_fs *);
int bch2_gc(struct bch_fs *, struct list_head *, bool, bool);
struct journal_keys;
int bch2_gc(struct bch_fs *, struct journal_keys *, bool, bool);
void bch2_gc_thread_stop(struct bch_fs *);
int bch2_gc_thread_start(struct bch_fs *);
void bch2_mark_dev_superblock(struct bch_fs *, struct bch_dev *, unsigned);
......
......@@ -12,8 +12,8 @@
#include "ec.h"
#include "error.h"
#include "io.h"
#include "journal_io.h"
#include "keylist.h"
#include "recovery.h"
#include "super-io.h"
#include "util.h"
......@@ -1235,9 +1235,9 @@ static void bch2_stripe_read_key(struct bch_fs *c, struct bkey_s_c k)
bch2_mark_key(c, k, true, 0, NULL, 0, 0);
}
int bch2_stripes_read(struct bch_fs *c, struct list_head *journal_replay_list)
int bch2_stripes_read(struct bch_fs *c, struct journal_keys *journal_keys)
{
struct journal_replay *r;
struct journal_key *i;
struct btree_trans trans;
struct btree_iter *iter;
struct bkey_s_c k;
......@@ -1258,14 +1258,9 @@ int bch2_stripes_read(struct bch_fs *c, struct list_head *journal_replay_list)
if (ret)
return ret;
list_for_each_entry(r, journal_replay_list, list) {
struct bkey_i *k, *n;
struct jset_entry *entry;
for_each_jset_key(k, n, entry, &r->j)
if (entry->btree_id == BTREE_ID_EC)
bch2_stripe_read_key(c, bkey_i_to_s_c(k));
}
for_each_journal_key(*journal_keys, i)
if (i->btree_id == BTREE_ID_EC)
bch2_stripe_read_key(c, bkey_i_to_s_c(i->k));
return 0;
}
......
......@@ -150,7 +150,8 @@ void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *);
void bch2_ec_flush_new_stripes(struct bch_fs *);
int bch2_stripes_read(struct bch_fs *, struct list_head *);
struct journal_keys;
int bch2_stripes_read(struct bch_fs *, struct journal_keys *);
int bch2_stripes_write(struct bch_fs *, unsigned, bool *);
int bch2_ec_mem_alloc(struct bch_fs *, bool);
......
This diff is collapsed.
......@@ -2,6 +2,22 @@
#ifndef _BCACHEFS_RECOVERY_H
#define _BCACHEFS_RECOVERY_H
struct journal_keys {
struct journal_key {
enum btree_id btree_id:8;
unsigned allocated:1;
struct bpos pos;
struct bkey_i *k;
u32 journal_seq;
u32 journal_offset;
} *d;
size_t nr;
u64 journal_seq_base;
};
#define for_each_journal_key(keys, i) \
for (i = (keys).d; i < (keys).d + (keys).nr; (i)++)
int bch2_fs_recovery(struct bch_fs *);
int bch2_fs_initialize(struct bch_fs *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment