Commit 51654002 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bio per journal buf

Prep work for having multiple journal writes in flight.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 52f7d75e
...@@ -1235,13 +1235,17 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq) ...@@ -1235,13 +1235,17 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
void bch2_dev_journal_exit(struct bch_dev *ca) void bch2_dev_journal_exit(struct bch_dev *ca)
{ {
kfree(ca->journal.bio); struct journal_device *ja = &ca->journal;
kfree(ca->journal.buckets);
kfree(ca->journal.bucket_seq); for (unsigned i = 0; i < ARRAY_SIZE(ja->bio); i++) {
kfree(ja->bio[i]);
ja->bio[i] = NULL;
}
ca->journal.bio = NULL; kfree(ja->buckets);
ca->journal.buckets = NULL; kfree(ja->bucket_seq);
ca->journal.bucket_seq = NULL; ja->buckets = NULL;
ja->bucket_seq = NULL;
} }
int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb)
...@@ -1251,14 +1255,13 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) ...@@ -1251,14 +1255,13 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb)
bch2_sb_field_get(sb, journal); bch2_sb_field_get(sb, journal);
struct bch_sb_field_journal_v2 *journal_buckets_v2 = struct bch_sb_field_journal_v2 *journal_buckets_v2 =
bch2_sb_field_get(sb, journal_v2); bch2_sb_field_get(sb, journal_v2);
unsigned i, nr_bvecs;
ja->nr = 0; ja->nr = 0;
if (journal_buckets_v2) { if (journal_buckets_v2) {
unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2); unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2);
for (i = 0; i < nr; i++) for (unsigned i = 0; i < nr; i++)
ja->nr += le64_to_cpu(journal_buckets_v2->d[i].nr); ja->nr += le64_to_cpu(journal_buckets_v2->d[i].nr);
} else if (journal_buckets) { } else if (journal_buckets) {
ja->nr = bch2_nr_journal_buckets(journal_buckets); ja->nr = bch2_nr_journal_buckets(journal_buckets);
...@@ -1268,13 +1271,14 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) ...@@ -1268,13 +1271,14 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb)
if (!ja->bucket_seq) if (!ja->bucket_seq)
return -BCH_ERR_ENOMEM_dev_journal_init; return -BCH_ERR_ENOMEM_dev_journal_init;
nr_bvecs = DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE); unsigned nr_bvecs = DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE);
ca->journal.bio = bio_kmalloc(nr_bvecs, GFP_KERNEL); for (unsigned i = 0; i < ARRAY_SIZE(ja->bio); i++) {
if (!ca->journal.bio) ja->bio[i] = bio_kmalloc(nr_bvecs, GFP_KERNEL);
return -BCH_ERR_ENOMEM_dev_journal_init; if (!ja->bio[i])
return -BCH_ERR_ENOMEM_dev_journal_init;
bio_init(ca->journal.bio, NULL, ca->journal.bio->bi_inline_vecs, nr_bvecs, 0); bio_init(ja->bio[i], NULL, ja->bio[i]->bi_inline_vecs, nr_bvecs, 0);
}
ja->buckets = kcalloc(ja->nr, sizeof(u64), GFP_KERNEL); ja->buckets = kcalloc(ja->nr, sizeof(u64), GFP_KERNEL);
if (!ja->buckets) if (!ja->buckets)
...@@ -1282,14 +1286,14 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) ...@@ -1282,14 +1286,14 @@ int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb)
if (journal_buckets_v2) { if (journal_buckets_v2) {
unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2); unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2);
unsigned j, dst = 0; unsigned dst = 0;
for (i = 0; i < nr; i++) for (unsigned i = 0; i < nr; i++)
for (j = 0; j < le64_to_cpu(journal_buckets_v2->d[i].nr); j++) for (unsigned j = 0; j < le64_to_cpu(journal_buckets_v2->d[i].nr); j++)
ja->buckets[dst++] = ja->buckets[dst++] =
le64_to_cpu(journal_buckets_v2->d[i].start) + j; le64_to_cpu(journal_buckets_v2->d[i].start) + j;
} else if (journal_buckets) { } else if (journal_buckets) {
for (i = 0; i < ja->nr; i++) for (unsigned i = 0; i < ja->nr; i++)
ja->buckets[i] = le64_to_cpu(journal_buckets->buckets[i]); ja->buckets[i] = le64_to_cpu(journal_buckets->buckets[i]);
} }
......
...@@ -1721,13 +1721,14 @@ static CLOSURE_CALLBACK(do_journal_write) ...@@ -1721,13 +1721,14 @@ static CLOSURE_CALLBACK(do_journal_write)
{ {
closure_type(j, struct journal, io); closure_type(j, struct journal, io);
struct bch_fs *c = container_of(j, struct bch_fs, journal); struct bch_fs *c = container_of(j, struct bch_fs, journal);
struct bch_dev *ca; unsigned buf_idx = journal_last_unwritten_seq(j) & JOURNAL_BUF_MASK;
struct journal_buf *w = journal_last_unwritten_buf(j); struct journal_buf *w = j->buf + buf_idx;
struct bio *bio;
unsigned sectors = vstruct_sectors(w->data, c->block_bits); unsigned sectors = vstruct_sectors(w->data, c->block_bits);
extent_for_each_ptr(bkey_i_to_s_extent(&w->key), ptr) { extent_for_each_ptr(bkey_i_to_s_extent(&w->key), ptr) {
ca = bch_dev_bkey_exists(c, ptr->dev); struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
struct journal_device *ja = &ca->journal;
if (!percpu_ref_tryget(&ca->io_ref)) { if (!percpu_ref_tryget(&ca->io_ref)) {
/* XXX: fix this */ /* XXX: fix this */
bch_err(c, "missing device for journal write\n"); bch_err(c, "missing device for journal write\n");
...@@ -1737,7 +1738,7 @@ static CLOSURE_CALLBACK(do_journal_write) ...@@ -1737,7 +1738,7 @@ static CLOSURE_CALLBACK(do_journal_write)
this_cpu_add(ca->io_done->sectors[WRITE][BCH_DATA_journal], this_cpu_add(ca->io_done->sectors[WRITE][BCH_DATA_journal],
sectors); sectors);
bio = ca->journal.bio; struct bio *bio = ja->bio[buf_idx];
bio_reset(bio, ca->disk_sb.bdev, REQ_OP_WRITE|REQ_SYNC|REQ_META); bio_reset(bio, ca->disk_sb.bdev, REQ_OP_WRITE|REQ_SYNC|REQ_META);
bio->bi_iter.bi_sector = ptr->offset; bio->bi_iter.bi_sector = ptr->offset;
bio->bi_end_io = journal_write_endio; bio->bi_end_io = journal_write_endio;
...@@ -1756,8 +1757,7 @@ static CLOSURE_CALLBACK(do_journal_write) ...@@ -1756,8 +1757,7 @@ static CLOSURE_CALLBACK(do_journal_write)
trace_and_count(c, journal_write, bio); trace_and_count(c, journal_write, bio);
closure_bio_submit(bio, cl); closure_bio_submit(bio, cl);
ca->journal.bucket_seq[ca->journal.cur_idx] = ja->bucket_seq[ja->cur_idx] = le64_to_cpu(w->data->seq);
le64_to_cpu(w->data->seq);
} }
continue_at(cl, journal_write_done, j->wq); continue_at(cl, journal_write_done, j->wq);
...@@ -1939,9 +1939,9 @@ CLOSURE_CALLBACK(bch2_journal_write) ...@@ -1939,9 +1939,9 @@ CLOSURE_CALLBACK(bch2_journal_write)
{ {
closure_type(j, struct journal, io); closure_type(j, struct journal, io);
struct bch_fs *c = container_of(j, struct bch_fs, journal); struct bch_fs *c = container_of(j, struct bch_fs, journal);
struct journal_buf *w = journal_last_unwritten_buf(j); unsigned buf_idx = journal_last_unwritten_seq(j) & JOURNAL_BUF_MASK;
struct journal_buf *w = j->buf + buf_idx;
struct bch_replicas_padded replicas; struct bch_replicas_padded replicas;
struct bio *bio;
struct printbuf journal_debug_buf = PRINTBUF; struct printbuf journal_debug_buf = PRINTBUF;
unsigned nr_rw_members = 0; unsigned nr_rw_members = 0;
int ret; int ret;
...@@ -2023,7 +2023,8 @@ CLOSURE_CALLBACK(bch2_journal_write) ...@@ -2023,7 +2023,8 @@ CLOSURE_CALLBACK(bch2_journal_write)
for_each_rw_member(c, ca) { for_each_rw_member(c, ca) {
percpu_ref_get(&ca->io_ref); percpu_ref_get(&ca->io_ref);
bio = ca->journal.bio; struct journal_device *ja = &ca->journal;
struct bio *bio = ja->bio[buf_idx];
bio_reset(bio, ca->disk_sb.bdev, bio_reset(bio, ca->disk_sb.bdev,
REQ_OP_WRITE|REQ_SYNC|REQ_META|REQ_PREFLUSH); REQ_OP_WRITE|REQ_SYNC|REQ_META|REQ_PREFLUSH);
bio->bi_end_io = journal_write_endio; bio->bi_end_io = journal_write_endio;
......
...@@ -315,7 +315,7 @@ struct journal_device { ...@@ -315,7 +315,7 @@ struct journal_device {
u64 *buckets; u64 *buckets;
/* Bio for journal reads/writes to this device */ /* Bio for journal reads/writes to this device */
struct bio *bio; struct bio *bio[JOURNAL_BUF_NR];
/* for bch_journal_read_device */ /* for bch_journal_read_device */
struct closure read; struct closure read;
......
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