Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcachefs: bio per journal buf

Prep work for having multiple journal writes in flight.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>

+34 -29
+22 -18
fs/bcachefs/journal.c
··· 1235 1235 1236 1236 void bch2_dev_journal_exit(struct bch_dev *ca) 1237 1237 { 1238 - kfree(ca->journal.bio); 1239 - kfree(ca->journal.buckets); 1240 - kfree(ca->journal.bucket_seq); 1238 + struct journal_device *ja = &ca->journal; 1241 1239 1242 - ca->journal.bio = NULL; 1243 - ca->journal.buckets = NULL; 1244 - ca->journal.bucket_seq = NULL; 1240 + for (unsigned i = 0; i < ARRAY_SIZE(ja->bio); i++) { 1241 + kfree(ja->bio[i]); 1242 + ja->bio[i] = NULL; 1243 + } 1244 + 1245 + kfree(ja->buckets); 1246 + kfree(ja->bucket_seq); 1247 + ja->buckets = NULL; 1248 + ja->bucket_seq = NULL; 1245 1249 } 1246 1250 1247 1251 int bch2_dev_journal_init(struct bch_dev *ca, struct bch_sb *sb) ··· 1255 1251 bch2_sb_field_get(sb, journal); 1256 1252 struct bch_sb_field_journal_v2 *journal_buckets_v2 = 1257 1253 bch2_sb_field_get(sb, journal_v2); 1258 - unsigned i, nr_bvecs; 1259 1254 1260 1255 ja->nr = 0; 1261 1256 1262 1257 if (journal_buckets_v2) { 1263 1258 unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2); 1264 1259 1265 - for (i = 0; i < nr; i++) 1260 + for (unsigned i = 0; i < nr; i++) 1266 1261 ja->nr += le64_to_cpu(journal_buckets_v2->d[i].nr); 1267 1262 } else if (journal_buckets) { 1268 1263 ja->nr = bch2_nr_journal_buckets(journal_buckets); ··· 1271 1268 if (!ja->bucket_seq) 1272 1269 return -BCH_ERR_ENOMEM_dev_journal_init; 1273 1270 1274 - nr_bvecs = DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE); 1271 + unsigned nr_bvecs = DIV_ROUND_UP(JOURNAL_ENTRY_SIZE_MAX, PAGE_SIZE); 1275 1272 1276 - ca->journal.bio = bio_kmalloc(nr_bvecs, GFP_KERNEL); 1277 - if (!ca->journal.bio) 1278 - return -BCH_ERR_ENOMEM_dev_journal_init; 1279 - 1280 - bio_init(ca->journal.bio, NULL, ca->journal.bio->bi_inline_vecs, nr_bvecs, 0); 1273 + for (unsigned i = 0; i < ARRAY_SIZE(ja->bio); i++) { 1274 + ja->bio[i] = bio_kmalloc(nr_bvecs, GFP_KERNEL); 1275 + if (!ja->bio[i]) 1276 + return -BCH_ERR_ENOMEM_dev_journal_init; 1277 + bio_init(ja->bio[i], NULL, ja->bio[i]->bi_inline_vecs, nr_bvecs, 0); 1278 + } 1281 1279 1282 1280 ja->buckets = kcalloc(ja->nr, sizeof(u64), GFP_KERNEL); 1283 1281 if (!ja->buckets) ··· 1286 1282 1287 1283 if (journal_buckets_v2) { 1288 1284 unsigned nr = bch2_sb_field_journal_v2_nr_entries(journal_buckets_v2); 1289 - unsigned j, dst = 0; 1285 + unsigned dst = 0; 1290 1286 1291 - for (i = 0; i < nr; i++) 1292 - for (j = 0; j < le64_to_cpu(journal_buckets_v2->d[i].nr); j++) 1287 + for (unsigned i = 0; i < nr; i++) 1288 + for (unsigned j = 0; j < le64_to_cpu(journal_buckets_v2->d[i].nr); j++) 1293 1289 ja->buckets[dst++] = 1294 1290 le64_to_cpu(journal_buckets_v2->d[i].start) + j; 1295 1291 } else if (journal_buckets) { 1296 - for (i = 0; i < ja->nr; i++) 1292 + for (unsigned i = 0; i < ja->nr; i++) 1297 1293 ja->buckets[i] = le64_to_cpu(journal_buckets->buckets[i]); 1298 1294 } 1299 1295
+11 -10
fs/bcachefs/journal_io.c
··· 1721 1721 { 1722 1722 closure_type(j, struct journal, io); 1723 1723 struct bch_fs *c = container_of(j, struct bch_fs, journal); 1724 - struct bch_dev *ca; 1725 - struct journal_buf *w = journal_last_unwritten_buf(j); 1726 - struct bio *bio; 1724 + unsigned buf_idx = journal_last_unwritten_seq(j) & JOURNAL_BUF_MASK; 1725 + struct journal_buf *w = j->buf + buf_idx; 1727 1726 unsigned sectors = vstruct_sectors(w->data, c->block_bits); 1728 1727 1729 1728 extent_for_each_ptr(bkey_i_to_s_extent(&w->key), ptr) { 1730 - ca = bch_dev_bkey_exists(c, ptr->dev); 1729 + struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); 1730 + struct journal_device *ja = &ca->journal; 1731 + 1731 1732 if (!percpu_ref_tryget(&ca->io_ref)) { 1732 1733 /* XXX: fix this */ 1733 1734 bch_err(c, "missing device for journal write\n"); ··· 1738 1737 this_cpu_add(ca->io_done->sectors[WRITE][BCH_DATA_journal], 1739 1738 sectors); 1740 1739 1741 - bio = ca->journal.bio; 1740 + struct bio *bio = ja->bio[buf_idx]; 1742 1741 bio_reset(bio, ca->disk_sb.bdev, REQ_OP_WRITE|REQ_SYNC|REQ_META); 1743 1742 bio->bi_iter.bi_sector = ptr->offset; 1744 1743 bio->bi_end_io = journal_write_endio; ··· 1757 1756 trace_and_count(c, journal_write, bio); 1758 1757 closure_bio_submit(bio, cl); 1759 1758 1760 - ca->journal.bucket_seq[ca->journal.cur_idx] = 1761 - le64_to_cpu(w->data->seq); 1759 + ja->bucket_seq[ja->cur_idx] = le64_to_cpu(w->data->seq); 1762 1760 } 1763 1761 1764 1762 continue_at(cl, journal_write_done, j->wq); ··· 1939 1939 { 1940 1940 closure_type(j, struct journal, io); 1941 1941 struct bch_fs *c = container_of(j, struct bch_fs, journal); 1942 - struct journal_buf *w = journal_last_unwritten_buf(j); 1942 + unsigned buf_idx = journal_last_unwritten_seq(j) & JOURNAL_BUF_MASK; 1943 + struct journal_buf *w = j->buf + buf_idx; 1943 1944 struct bch_replicas_padded replicas; 1944 - struct bio *bio; 1945 1945 struct printbuf journal_debug_buf = PRINTBUF; 1946 1946 unsigned nr_rw_members = 0; 1947 1947 int ret; ··· 2023 2023 for_each_rw_member(c, ca) { 2024 2024 percpu_ref_get(&ca->io_ref); 2025 2025 2026 - bio = ca->journal.bio; 2026 + struct journal_device *ja = &ca->journal; 2027 + struct bio *bio = ja->bio[buf_idx]; 2027 2028 bio_reset(bio, ca->disk_sb.bdev, 2028 2029 REQ_OP_WRITE|REQ_SYNC|REQ_META|REQ_PREFLUSH); 2029 2030 bio->bi_end_io = journal_write_endio;
+1 -1
fs/bcachefs/journal_types.h
··· 315 315 u64 *buckets; 316 316 317 317 /* Bio for journal reads/writes to this device */ 318 - struct bio *bio; 318 + struct bio *bio[JOURNAL_BUF_NR]; 319 319 320 320 /* for bch_journal_read_device */ 321 321 struct closure read;