X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fjournal_sb.c;h=ae4fb8c3a2bc26fe937c5bc88f8b5b78143e91b0;hb=1f79cf3825e94fcb146d417b6dda9b94c93c7a53;hp=8efe7b7e3dcbdb575dcbc91120318eedf5bb743a;hpb=fd249e130f2c7f1e8e13b8d240f8c4ad9a43ed0a;p=bcachefs-tools-debian diff --git a/libbcachefs/journal_sb.c b/libbcachefs/journal_sb.c index 8efe7b7..ae4fb8c 100644 --- a/libbcachefs/journal_sb.c +++ b/libbcachefs/journal_sb.c @@ -2,6 +2,7 @@ #include "bcachefs.h" #include "journal_sb.h" +#include "darray.h" #include @@ -20,8 +21,8 @@ static int bch2_sb_journal_validate(struct bch_sb *sb, struct printbuf *err) { struct bch_sb_field_journal *journal = field_to_type(f, journal); - struct bch_member *m = bch2_sb_get_members(sb)->members + sb->dev_idx; - int ret = -EINVAL; + struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx); + int ret = -BCH_ERR_invalid_sb_journal; unsigned nr; unsigned i; u64 *b; @@ -30,9 +31,9 @@ static int bch2_sb_journal_validate(struct bch_sb *sb, if (!nr) return 0; - b = kmalloc_array(sizeof(u64), nr, GFP_KERNEL); + b = kmalloc_array(nr, sizeof(u64), GFP_KERNEL); if (!b) - return -ENOMEM; + return -BCH_ERR_ENOMEM_sb_journal_validate; for (i = 0; i < nr; i++) b[i] = le64_to_cpu(journal->buckets[i]); @@ -40,25 +41,25 @@ static int bch2_sb_journal_validate(struct bch_sb *sb, sort(b, nr, sizeof(u64), u64_cmp, NULL); if (!b[0]) { - pr_buf(err, "journal bucket at sector 0"); + prt_printf(err, "journal bucket at sector 0"); goto err; } - if (b[0] < le16_to_cpu(m->first_bucket)) { - pr_buf(err, "journal bucket %llu before first bucket %u", - b[0], le16_to_cpu(m->first_bucket)); + if (b[0] < le16_to_cpu(m.first_bucket)) { + prt_printf(err, "journal bucket %llu before first bucket %u", + b[0], le16_to_cpu(m.first_bucket)); goto err; } - if (b[nr - 1] >= le64_to_cpu(m->nbuckets)) { - pr_buf(err, "journal bucket %llu past end of device (nbuckets %llu)", - b[nr - 1], le64_to_cpu(m->nbuckets)); + if (b[nr - 1] >= le64_to_cpu(m.nbuckets)) { + prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)", + b[nr - 1], le64_to_cpu(m.nbuckets)); goto err; } for (i = 0; i + 1 < nr; i++) if (b[i] == b[i + 1]) { - pr_buf(err, "duplicate journal buckets %llu", b[i]); + prt_printf(err, "duplicate journal buckets %llu", b[i]); goto err; } @@ -74,10 +75,10 @@ static void bch2_sb_journal_to_text(struct printbuf *out, struct bch_sb *sb, struct bch_sb_field_journal *journal = field_to_type(f, journal); unsigned i, nr = bch2_nr_journal_buckets(journal); - pr_buf(out, "Buckets: "); + prt_printf(out, "Buckets: "); for (i = 0; i < nr; i++) - pr_buf(out, " %llu", le64_to_cpu(journal->buckets[i])); - pr_newline(out); + prt_printf(out, " %llu", le64_to_cpu(journal->buckets[i])); + prt_newline(out); } const struct bch_sb_field_ops bch_sb_field_ops_journal = { @@ -103,8 +104,8 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb, struct printbuf *err) { struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2); - struct bch_member *m = bch2_sb_get_members(sb)->members + sb->dev_idx; - int ret = -EINVAL; + struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx); + int ret = -BCH_ERR_invalid_sb_journal; unsigned nr; unsigned i; struct u64_range *b; @@ -113,9 +114,9 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb, if (!nr) return 0; - b = kmalloc_array(sizeof(*b), nr, GFP_KERNEL); + b = kmalloc_array(nr, sizeof(*b), GFP_KERNEL); if (!b) - return -ENOMEM; + return -BCH_ERR_ENOMEM_sb_journal_v2_validate; for (i = 0; i < nr; i++) { b[i].start = le64_to_cpu(journal->d[i].start); @@ -125,31 +126,25 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb, sort(b, nr, sizeof(*b), u64_range_cmp, NULL); if (!b[0].start) { - pr_buf(err, "journal bucket at sector 0"); + prt_printf(err, "journal bucket at sector 0"); goto err; } - if (b[0].start < le16_to_cpu(m->first_bucket)) { - pr_buf(err, "journal bucket %llu before first bucket %u", - b[0].start, le16_to_cpu(m->first_bucket)); + if (b[0].start < le16_to_cpu(m.first_bucket)) { + prt_printf(err, "journal bucket %llu before first bucket %u", + b[0].start, le16_to_cpu(m.first_bucket)); goto err; } - if (b[nr - 1].end > le64_to_cpu(m->nbuckets)) { - pr_buf(err, "journal bucket %llu past end of device (nbuckets %llu)", - b[nr - 1].end - 1, le64_to_cpu(m->nbuckets)); + if (b[nr - 1].end > le64_to_cpu(m.nbuckets)) { + prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)", + b[nr - 1].end - 1, le64_to_cpu(m.nbuckets)); goto err; } for (i = 0; i + 1 < nr; i++) { - if (b[i].end == b[i + 1].start) { - pr_buf(err, "contiguous journal buckets ranges %llu-%llu, %llu-%llu", - b[i].start, b[i].end, b[i + 1].start, b[i + 1].end); - goto err; - } - if (b[i].end > b[i + 1].start) { - pr_buf(err, "duplicate journal buckets in ranges %llu-%llu, %llu-%llu", + prt_printf(err, "duplicate journal buckets in ranges %llu-%llu, %llu-%llu", b[i].start, b[i].end, b[i + 1].start, b[i + 1].end); goto err; } @@ -167,12 +162,12 @@ static void bch2_sb_journal_v2_to_text(struct printbuf *out, struct bch_sb *sb, struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2); unsigned i, nr = bch2_sb_field_journal_v2_nr_entries(journal); - pr_buf(out, "Buckets: "); + prt_printf(out, "Buckets: "); for (i = 0; i < nr; i++) - pr_buf(out, " %llu-%llu", + prt_printf(out, " %llu-%llu", le64_to_cpu(journal->d[i].start), le64_to_cpu(journal->d[i].start) + le64_to_cpu(journal->d[i].nr)); - pr_newline(out); + prt_newline(out); } const struct bch_sb_field_ops bch_sb_field_ops_journal_v2 = { @@ -180,43 +175,45 @@ const struct bch_sb_field_ops bch_sb_field_ops_journal_v2 = { .to_text = bch2_sb_journal_v2_to_text, }; -int bch2_journal_buckets_to_sb(struct bch_fs *c, struct bch_dev *ca) +int bch2_journal_buckets_to_sb(struct bch_fs *c, struct bch_dev *ca, + u64 *buckets, unsigned nr) { - struct journal_device *ja = &ca->journal; struct bch_sb_field_journal_v2 *j; - unsigned i, dst = 0, nr = 1; + unsigned i, dst = 0, nr_compacted = 1; - lockdep_assert_held(&c->sb_lock); + if (c) + lockdep_assert_held(&c->sb_lock); - if (!ja->nr) { + if (!nr) { bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal); bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal_v2); return 0; } - for (i = 0; i + 1 < ja->nr; i++) - if (ja->buckets[i] + 1 != ja->buckets[i + 1]) - nr++; + for (i = 0; i + 1 < nr; i++) + if (buckets[i] + 1 != buckets[i + 1]) + nr_compacted++; - j = bch2_sb_resize_journal_v2(&ca->disk_sb, - (sizeof(*j) + sizeof(j->d[0]) * nr) / sizeof(u64)); + j = bch2_sb_field_resize(&ca->disk_sb, journal_v2, + (sizeof(*j) + sizeof(j->d[0]) * nr_compacted) / sizeof(u64)); if (!j) - return -ENOSPC; + return -BCH_ERR_ENOSPC_sb_journal; bch2_sb_field_delete(&ca->disk_sb, BCH_SB_FIELD_journal); - j->d[dst].start = le64_to_cpu(ja->buckets[0]); - j->d[dst].nr = le64_to_cpu(1); + j->d[dst].start = cpu_to_le64(buckets[0]); + j->d[dst].nr = cpu_to_le64(1); - for (i = 1; i < ja->nr; i++) { - if (ja->buckets[i] == ja->buckets[i - 1] + 1) { + for (i = 1; i < nr; i++) { + if (buckets[i] == buckets[i - 1] + 1) { le64_add_cpu(&j->d[dst].nr, 1); } else { dst++; - j->d[dst].start = le64_to_cpu(ja->buckets[i]); - j->d[dst].nr = le64_to_cpu(1); + j->d[dst].start = cpu_to_le64(buckets[i]); + j->d[dst].nr = cpu_to_le64(1); } } + BUG_ON(dst + 1 != nr_compacted); return 0; }