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 @@ ...@@ -12,7 +12,7 @@
#include "debug.h" #include "debug.h"
#include "ec.h" #include "ec.h"
#include "error.h" #include "error.h"
#include "journal_io.h" #include "recovery.h"
#include "trace.h" #include "trace.h"
#include <linux/kthread.h> #include <linux/kthread.h>
...@@ -261,13 +261,13 @@ static void bch2_alloc_read_key(struct bch_fs *c, struct bkey_s_c k) ...@@ -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); 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_trans trans;
struct btree_iter *iter; struct btree_iter *iter;
struct bkey_s_c k; struct bkey_s_c k;
struct bch_dev *ca; struct bch_dev *ca;
struct journal_key *j;
unsigned i; unsigned i;
int ret; int ret;
...@@ -282,14 +282,9 @@ int bch2_alloc_read(struct bch_fs *c, struct list_head *journal_replay_list) ...@@ -282,14 +282,9 @@ int bch2_alloc_read(struct bch_fs *c, struct list_head *journal_replay_list)
if (ret) if (ret)
return ret; return ret;
list_for_each_entry(r, journal_replay_list, list) { for_each_journal_key(*journal_keys, j)
struct bkey_i *k, *n; if (j->btree_id == BTREE_ID_ALLOC)
struct jset_entry *entry; bch2_alloc_read_key(c, bkey_i_to_s_c(j->k));
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));
}
percpu_down_write(&c->mark_lock); percpu_down_write(&c->mark_lock);
bch2_dev_usage_from_buckets(c); bch2_dev_usage_from_buckets(c);
......
...@@ -25,7 +25,8 @@ void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_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, \ .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 *); int bch2_alloc_replay_key(struct bch_fs *, struct bkey_i *);
static inline void bch2_wake_allocator(struct bch_dev *ca) static inline void bch2_wake_allocator(struct bch_dev *ca)
......
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
#include "error.h" #include "error.h"
#include "extents.h" #include "extents.h"
#include "journal.h" #include "journal.h"
#include "journal_io.h"
#include "keylist.h" #include "keylist.h"
#include "move.h" #include "move.h"
#include "recovery.h"
#include "replicas.h" #include "replicas.h"
#include "super-io.h" #include "super-io.h"
#include "trace.h" #include "trace.h"
...@@ -273,7 +273,7 @@ static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r) ...@@ -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); (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) bool initial, bool metadata_only)
{ {
enum btree_id ids[BTREE_ID_NR]; enum btree_id ids[BTREE_ID_NR];
...@@ -292,25 +292,21 @@ static int bch2_gc_btrees(struct bch_fs *c, struct list_head *journal, ...@@ -292,25 +292,21 @@ static int bch2_gc_btrees(struct bch_fs *c, struct list_head *journal,
if (ret) if (ret)
return ret; return ret;
if (journal && !metadata_only && if (journal_keys && !metadata_only &&
btree_node_type_needs_gc(type)) { btree_node_type_needs_gc(type)) {
struct bkey_i *k, *n; struct journal_key *j;
struct jset_entry *j;
struct journal_replay *r;
int ret; int ret;
list_for_each_entry(r, journal, list) for_each_journal_key(*journal_keys, j)
for_each_jset_key(k, n, j, &r->j) { if (j->btree_id == id) {
if (type == __btree_node_type(j->level, j->btree_id)) {
ret = bch2_gc_mark_key(c, ret = bch2_gc_mark_key(c,
bkey_i_to_s_c(k), bkey_i_to_s_c(j->k),
&max_stale, initial); &max_stale, initial);
if (ret) if (ret)
return ret; return ret;
} }
} }
} }
}
return 0; return 0;
} }
...@@ -695,7 +691,7 @@ static int bch2_gc_start(struct bch_fs *c, ...@@ -695,7 +691,7 @@ static int bch2_gc_start(struct bch_fs *c,
* move around - if references move backwards in the ordering GC * move around - if references move backwards in the ordering GC
* uses, GC could skip past them * 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) bool initial, bool metadata_only)
{ {
struct bch_dev *ca; struct bch_dev *ca;
...@@ -716,7 +712,7 @@ int bch2_gc(struct bch_fs *c, struct list_head *journal, ...@@ -716,7 +712,7 @@ int bch2_gc(struct bch_fs *c, struct list_head *journal,
bch2_mark_superblocks(c); 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) if (ret)
goto out; goto out;
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#include "btree_types.h" #include "btree_types.h"
void bch2_coalesce(struct bch_fs *); 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 *); void bch2_gc_thread_stop(struct bch_fs *);
int bch2_gc_thread_start(struct bch_fs *); int bch2_gc_thread_start(struct bch_fs *);
void bch2_mark_dev_superblock(struct bch_fs *, struct bch_dev *, unsigned); void bch2_mark_dev_superblock(struct bch_fs *, struct bch_dev *, unsigned);
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include "ec.h" #include "ec.h"
#include "error.h" #include "error.h"
#include "io.h" #include "io.h"
#include "journal_io.h"
#include "keylist.h" #include "keylist.h"
#include "recovery.h"
#include "super-io.h" #include "super-io.h"
#include "util.h" #include "util.h"
...@@ -1235,9 +1235,9 @@ static void bch2_stripe_read_key(struct bch_fs *c, struct bkey_s_c k) ...@@ -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); 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_trans trans;
struct btree_iter *iter; struct btree_iter *iter;
struct bkey_s_c k; struct bkey_s_c k;
...@@ -1258,14 +1258,9 @@ int bch2_stripes_read(struct bch_fs *c, struct list_head *journal_replay_list) ...@@ -1258,14 +1258,9 @@ int bch2_stripes_read(struct bch_fs *c, struct list_head *journal_replay_list)
if (ret) if (ret)
return ret; return ret;
list_for_each_entry(r, journal_replay_list, list) { for_each_journal_key(*journal_keys, i)
struct bkey_i *k, *n; if (i->btree_id == BTREE_ID_EC)
struct jset_entry *entry; bch2_stripe_read_key(c, bkey_i_to_s_c(i->k));
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));
}
return 0; return 0;
} }
......
...@@ -150,7 +150,8 @@ void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *); ...@@ -150,7 +150,8 @@ void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *);
void bch2_ec_flush_new_stripes(struct bch_fs *); 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_stripes_write(struct bch_fs *, unsigned, bool *);
int bch2_ec_mem_alloc(struct bch_fs *, bool); int bch2_ec_mem_alloc(struct bch_fs *, bool);
......
This diff is collapsed.
...@@ -2,6 +2,22 @@ ...@@ -2,6 +2,22 @@
#ifndef _BCACHEFS_RECOVERY_H #ifndef _BCACHEFS_RECOVERY_H
#define _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_recovery(struct bch_fs *);
int bch2_fs_initialize(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