mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
bcachefs: convert journal replay ptrs to darray
Eliminates some error paths - no longer have a hardcoded BCH_REPLICAS_MAX limit. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
5b6271b509
commit
a555bcf4fa
@ -1153,7 +1153,6 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
|
|||||||
struct journal_replay *i, **_i;
|
struct journal_replay *i, **_i;
|
||||||
struct genradix_iter iter;
|
struct genradix_iter iter;
|
||||||
bool had_entries = false;
|
bool had_entries = false;
|
||||||
unsigned ptr;
|
|
||||||
u64 last_seq = cur_seq, nr, seq;
|
u64 last_seq = cur_seq, nr, seq;
|
||||||
|
|
||||||
genradix_for_each_reverse(&c->journal_entries, iter, _i) {
|
genradix_for_each_reverse(&c->journal_entries, iter, _i) {
|
||||||
@ -1207,8 +1206,8 @@ int bch2_fs_journal_start(struct journal *j, u64 cur_seq)
|
|||||||
p = journal_seq_pin(j, seq);
|
p = journal_seq_pin(j, seq);
|
||||||
|
|
||||||
p->devs.nr = 0;
|
p->devs.nr = 0;
|
||||||
for (ptr = 0; ptr < i->nr_ptrs; ptr++)
|
darray_for_each(i->ptrs, ptr)
|
||||||
bch2_dev_list_add_dev(&p->devs, i->ptrs[ptr].dev);
|
bch2_dev_list_add_dev(&p->devs, ptr->dev);
|
||||||
|
|
||||||
had_entries = true;
|
had_entries = true;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,6 @@ static int journal_entry_add(struct bch_fs *c, struct bch_dev *ca,
|
|||||||
{
|
{
|
||||||
struct genradix_iter iter;
|
struct genradix_iter iter;
|
||||||
struct journal_replay **_i, *i, *dup;
|
struct journal_replay **_i, *i, *dup;
|
||||||
struct journal_ptr *ptr;
|
|
||||||
size_t bytes = vstruct_bytes(j);
|
size_t bytes = vstruct_bytes(j);
|
||||||
u64 last_seq = !JSET_NO_FLUSH(j) ? le64_to_cpu(j->last_seq) : 0;
|
u64 last_seq = !JSET_NO_FLUSH(j) ? le64_to_cpu(j->last_seq) : 0;
|
||||||
int ret = JOURNAL_ENTRY_ADD_OK;
|
int ret = JOURNAL_ENTRY_ADD_OK;
|
||||||
@ -156,45 +155,29 @@ replace:
|
|||||||
if (!i)
|
if (!i)
|
||||||
return -BCH_ERR_ENOMEM_journal_entry_add;
|
return -BCH_ERR_ENOMEM_journal_entry_add;
|
||||||
|
|
||||||
i->nr_ptrs = 0;
|
darray_init(&i->ptrs);
|
||||||
i->csum_good = entry_ptr.csum_good;
|
i->csum_good = entry_ptr.csum_good;
|
||||||
i->ignore = false;
|
i->ignore = false;
|
||||||
unsafe_memcpy(&i->j, j, bytes, "embedded variable length struct");
|
unsafe_memcpy(&i->j, j, bytes, "embedded variable length struct");
|
||||||
i->ptrs[i->nr_ptrs++] = entry_ptr;
|
darray_push(&i->ptrs, entry_ptr);
|
||||||
|
|
||||||
if (dup) {
|
if (dup) {
|
||||||
if (dup->nr_ptrs >= ARRAY_SIZE(dup->ptrs)) {
|
|
||||||
bch_err(c, "found too many copies of journal entry %llu",
|
|
||||||
le64_to_cpu(i->j.seq));
|
|
||||||
dup->nr_ptrs = ARRAY_SIZE(dup->ptrs) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The first ptr should represent the jset we kept: */
|
/* The first ptr should represent the jset we kept: */
|
||||||
memcpy(i->ptrs + i->nr_ptrs,
|
darray_for_each(dup->ptrs, ptr)
|
||||||
dup->ptrs,
|
darray_push(&i->ptrs, *ptr);
|
||||||
sizeof(dup->ptrs[0]) * dup->nr_ptrs);
|
|
||||||
i->nr_ptrs += dup->nr_ptrs;
|
|
||||||
__journal_replay_free(c, dup);
|
__journal_replay_free(c, dup);
|
||||||
}
|
}
|
||||||
|
|
||||||
*_i = i;
|
*_i = i;
|
||||||
return 0;
|
|
||||||
found:
|
found:
|
||||||
for (ptr = i->ptrs; ptr < i->ptrs + i->nr_ptrs; ptr++) {
|
darray_for_each(i->ptrs, ptr)
|
||||||
if (ptr->dev == ca->dev_idx) {
|
if (ptr->dev == ca->dev_idx) {
|
||||||
bch_err(c, "duplicate journal entry %llu on same device",
|
bch_err(c, "duplicate journal entry %llu on same device",
|
||||||
le64_to_cpu(i->j.seq));
|
le64_to_cpu(i->j.seq));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (i->nr_ptrs >= ARRAY_SIZE(i->ptrs)) {
|
ret = darray_push(&i->ptrs, entry_ptr);
|
||||||
bch_err(c, "found too many copies of journal entry %llu",
|
|
||||||
le64_to_cpu(i->j.seq));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
i->ptrs[i->nr_ptrs++] = entry_ptr;
|
|
||||||
out:
|
out:
|
||||||
fsck_err:
|
fsck_err:
|
||||||
return ret;
|
return ret;
|
||||||
@ -1102,16 +1085,15 @@ static CLOSURE_CALLBACK(bch2_journal_read_device)
|
|||||||
if (!r)
|
if (!r)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (i = 0; i < r->nr_ptrs; i++) {
|
darray_for_each(r->ptrs, i)
|
||||||
if (r->ptrs[i].dev == ca->dev_idx) {
|
if (i->dev == ca->dev_idx) {
|
||||||
unsigned wrote = bucket_remainder(ca, r->ptrs[i].sector) +
|
unsigned wrote = bucket_remainder(ca, i->sector) +
|
||||||
vstruct_sectors(&r->j, c->block_bits);
|
vstruct_sectors(&r->j, c->block_bits);
|
||||||
|
|
||||||
ja->cur_idx = r->ptrs[i].bucket;
|
ja->cur_idx = i->bucket;
|
||||||
ja->sectors_free = ca->mi.bucket_size - wrote;
|
ja->sectors_free = ca->mi.bucket_size - wrote;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
found:
|
found:
|
||||||
mutex_unlock(&jlist->lock);
|
mutex_unlock(&jlist->lock);
|
||||||
@ -1158,21 +1140,16 @@ err:
|
|||||||
void bch2_journal_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
void bch2_journal_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||||
struct journal_replay *j)
|
struct journal_replay *j)
|
||||||
{
|
{
|
||||||
unsigned i;
|
darray_for_each(j->ptrs, i) {
|
||||||
|
struct bch_dev *ca = bch_dev_bkey_exists(c, i->dev);
|
||||||
for (i = 0; i < j->nr_ptrs; i++) {
|
|
||||||
struct bch_dev *ca = bch_dev_bkey_exists(c, j->ptrs[i].dev);
|
|
||||||
u64 offset;
|
u64 offset;
|
||||||
|
|
||||||
div64_u64_rem(j->ptrs[i].sector, ca->mi.bucket_size, &offset);
|
div64_u64_rem(i->sector, ca->mi.bucket_size, &offset);
|
||||||
|
|
||||||
if (i)
|
if (i != j->ptrs.data)
|
||||||
prt_printf(out, " ");
|
prt_printf(out, " ");
|
||||||
prt_printf(out, "%u:%u:%u (sector %llu)",
|
prt_printf(out, "%u:%u:%u (sector %llu)",
|
||||||
j->ptrs[i].dev,
|
i->dev, i->bucket, i->bucket_offset, i->sector);
|
||||||
j->ptrs[i].bucket,
|
|
||||||
j->ptrs[i].bucket_offset,
|
|
||||||
j->ptrs[i].sector);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,32 +1330,31 @@ int bch2_journal_read(struct bch_fs *c,
|
|||||||
.e.data_type = BCH_DATA_journal,
|
.e.data_type = BCH_DATA_journal,
|
||||||
.e.nr_required = 1,
|
.e.nr_required = 1,
|
||||||
};
|
};
|
||||||
unsigned ptr;
|
|
||||||
|
|
||||||
i = *_i;
|
i = *_i;
|
||||||
if (!i || i->ignore)
|
if (!i || i->ignore)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (ptr = 0; ptr < i->nr_ptrs; ptr++) {
|
darray_for_each(i->ptrs, ptr) {
|
||||||
struct bch_dev *ca = bch_dev_bkey_exists(c, i->ptrs[ptr].dev);
|
struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
|
||||||
|
|
||||||
if (!i->ptrs[ptr].csum_good)
|
if (!ptr->csum_good)
|
||||||
bch_err_dev_offset(ca, i->ptrs[ptr].sector,
|
bch_err_dev_offset(ca, ptr->sector,
|
||||||
"invalid journal checksum, seq %llu%s",
|
"invalid journal checksum, seq %llu%s",
|
||||||
le64_to_cpu(i->j.seq),
|
le64_to_cpu(i->j.seq),
|
||||||
i->csum_good ? " (had good copy on another device)" : "");
|
i->csum_good ? " (had good copy on another device)" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = jset_validate(c,
|
ret = jset_validate(c,
|
||||||
bch_dev_bkey_exists(c, i->ptrs[0].dev),
|
bch_dev_bkey_exists(c, i->ptrs.data[0].dev),
|
||||||
&i->j,
|
&i->j,
|
||||||
i->ptrs[0].sector,
|
i->ptrs.data[0].sector,
|
||||||
READ);
|
READ);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
for (ptr = 0; ptr < i->nr_ptrs; ptr++)
|
darray_for_each(i->ptrs, ptr)
|
||||||
replicas.e.devs[replicas.e.nr_devs++] = i->ptrs[ptr].dev;
|
replicas.e.devs[replicas.e.nr_devs++] = ptr->dev;
|
||||||
|
|
||||||
bch2_replicas_entry_sort(&replicas.e);
|
bch2_replicas_entry_sort(&replicas.e);
|
||||||
|
|
||||||
|
@ -2,19 +2,22 @@
|
|||||||
#ifndef _BCACHEFS_JOURNAL_IO_H
|
#ifndef _BCACHEFS_JOURNAL_IO_H
|
||||||
#define _BCACHEFS_JOURNAL_IO_H
|
#define _BCACHEFS_JOURNAL_IO_H
|
||||||
|
|
||||||
|
#include "darray.h"
|
||||||
|
|
||||||
|
struct journal_ptr {
|
||||||
|
bool csum_good;
|
||||||
|
u8 dev;
|
||||||
|
u32 bucket;
|
||||||
|
u32 bucket_offset;
|
||||||
|
u64 sector;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only used for holding the journal entries we read in btree_journal_read()
|
* Only used for holding the journal entries we read in btree_journal_read()
|
||||||
* during cache_registration
|
* during cache_registration
|
||||||
*/
|
*/
|
||||||
struct journal_replay {
|
struct journal_replay {
|
||||||
struct journal_ptr {
|
DARRAY_PREALLOCATED(struct journal_ptr, 8) ptrs;
|
||||||
bool csum_good;
|
|
||||||
u8 dev;
|
|
||||||
u32 bucket;
|
|
||||||
u32 bucket_offset;
|
|
||||||
u64 sector;
|
|
||||||
} ptrs[BCH_REPLICAS_MAX];
|
|
||||||
unsigned nr_ptrs;
|
|
||||||
|
|
||||||
bool csum_good;
|
bool csum_good;
|
||||||
bool ignore;
|
bool ignore;
|
||||||
|
Loading…
Reference in New Issue
Block a user