#include "reflink.h"
#include "replicas.h"
#include "super-io.h"
+#include "trace.h"
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/preempt.h>
#include <linux/rcupdate.h>
#include <linux/sched/task.h>
-#include <trace/events/bcachefs.h>
#define DROP_THIS_NODE 10
#define DROP_PREV_NODE 11
new = kmalloc_array(BKEY_BTREE_PTR_U64s_MAX, sizeof(u64), GFP_KERNEL);
if (!new)
- return -ENOMEM;
+ return -BCH_ERR_ENOMEM_gc_repair_key;
btree_ptr_to_v2(b, new);
b->data->min_key = new_min;
new = kmalloc_array(BKEY_BTREE_PTR_U64s_MAX, sizeof(u64), GFP_KERNEL);
if (!new)
- return -ENOMEM;
+ return -BCH_ERR_ENOMEM_gc_repair_key;
btree_ptr_to_v2(b, new);
b->data->max_key = new_max;
struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
enum bch_data_type data_type = bch2_bkey_ptr_data_type(*k, &entry->ptr);
- if (c->opts.reconstruct_alloc ||
- fsck_err_on(!g->gen_valid, c,
- "bucket %u:%zu data type %s ptr gen %u missing in alloc btree\n"
- "while marking %s",
- p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
- bch2_data_types[ptr_data_type(k->k, &p.ptr)],
- p.ptr.gen,
- (printbuf_reset(&buf),
- bch2_bkey_val_to_text(&buf, c, *k), buf.buf))) {
+ if (!g->gen_valid &&
+ (c->opts.reconstruct_alloc ||
+ fsck_err(c, "bucket %u:%zu data type %s ptr gen %u missing in alloc btree\n"
+ "while marking %s",
+ p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
+ bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+ p.ptr.gen,
+ (printbuf_reset(&buf),
+ bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))) {
if (!p.ptr.cached) {
g->gen_valid = true;
g->gen = p.ptr.gen;
}
}
- if (fsck_err_on(gen_cmp(p.ptr.gen, g->gen) > 0, c,
- "bucket %u:%zu data type %s ptr gen in the future: %u > %u\n"
- "while marking %s",
- p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
- bch2_data_types[ptr_data_type(k->k, &p.ptr)],
- p.ptr.gen, g->gen,
- (printbuf_reset(&buf),
- bch2_bkey_val_to_text(&buf, c, *k), buf.buf))) {
+ if (gen_cmp(p.ptr.gen, g->gen) > 0 &&
+ (c->opts.reconstruct_alloc ||
+ fsck_err(c, "bucket %u:%zu data type %s ptr gen in the future: %u > %u\n"
+ "while marking %s",
+ p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
+ bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+ p.ptr.gen, g->gen,
+ (printbuf_reset(&buf),
+ bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))) {
if (!p.ptr.cached) {
g->gen_valid = true;
g->gen = p.ptr.gen;
}
}
- if (fsck_err_on(gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX, c,
- "bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
- "while marking %s",
- p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
- bch2_data_types[ptr_data_type(k->k, &p.ptr)],
- p.ptr.gen,
- (printbuf_reset(&buf),
- bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))
+ if (gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX &&
+ (c->opts.reconstruct_alloc ||
+ fsck_err(c, "bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
+ "while marking %s",
+ p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
+ bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+ p.ptr.gen,
+ (printbuf_reset(&buf),
+ bch2_bkey_val_to_text(&buf, c, *k), buf.buf))))
do_update = true;
- if (fsck_err_on(!p.ptr.cached &&
- gen_cmp(p.ptr.gen, g->gen) < 0, c,
- "bucket %u:%zu data type %s stale dirty ptr: %u < %u\n"
- "while marking %s",
- p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
- bch2_data_types[ptr_data_type(k->k, &p.ptr)],
- p.ptr.gen, g->gen,
- (printbuf_reset(&buf),
- bch2_bkey_val_to_text(&buf, c, *k), buf.buf)))
+ if (!p.ptr.cached && gen_cmp(p.ptr.gen, g->gen) < 0 &&
+ (c->opts.reconstruct_alloc ||
+ fsck_err(c, "bucket %u:%zu data type %s stale dirty ptr: %u < %u\n"
+ "while marking %s",
+ p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
+ bch2_data_types[ptr_data_type(k->k, &p.ptr)],
+ p.ptr.gen, g->gen,
+ (printbuf_reset(&buf),
+ bch2_bkey_val_to_text(&buf, c, *k), buf.buf))))
do_update = true;
if (data_type != BCH_DATA_btree && p.ptr.gen != g->gen)
new = kmalloc(bkey_bytes(k->k), GFP_KERNEL);
if (!new) {
bch_err(c, "%s: error allocating new key", __func__);
- ret = -ENOMEM;
+ ret = -BCH_ERR_ENOMEM_gc_repair_key;
goto err;
}
if (level)
bch2_btree_node_update_key_early(trans, btree_id, level - 1, *k, new);
- if (c->opts.verbose) {
+ if (0) {
printbuf_reset(&buf);
bch2_bkey_val_to_text(&buf, c, *k);
bch_info(c, "updated %s", buf.buf);
sizeof(u64), GFP_KERNEL);
if (!c->usage_gc) {
bch_err(c, "error allocating c->usage_gc");
- return -ENOMEM;
+ return -BCH_ERR_ENOMEM_gc_start;
}
for_each_member_device(ca, c, i) {
if (!ca->usage_gc) {
bch_err(c, "error allocating ca->usage_gc");
percpu_ref_put(&ca->ref);
- return -ENOMEM;
+ return -BCH_ERR_ENOMEM_gc_start;
}
this_cpu_write(ca->usage_gc->d[BCH_DATA_free].buckets,
if (!buckets) {
percpu_ref_put(&ca->ref);
bch_err(c, "error allocating ca->buckets[gc]");
- return -ENOMEM;
+ return -BCH_ERR_ENOMEM_gc_alloc_start;
}
buckets->first_bucket = ca->mi.first_bucket;
" should be %u",
(bch2_bkey_val_to_text(&buf, c, k), buf.buf),
r->refcount)) {
- struct bkey_i *new = bch2_bkey_make_mut(trans, k);
+ struct bkey_i *new = bch2_bkey_make_mut(trans, iter, k, 0);
ret = PTR_ERR_OR_ZERO(new);
if (ret)
new->k.type = KEY_TYPE_deleted;
else
*bkey_refcount(new) = cpu_to_le64(r->refcount);
-
- ret = bch2_trans_update(trans, iter, new, 0);
}
fsck_err:
printbuf_exit(&buf);
r = genradix_ptr_alloc(&c->reflink_gc_table, c->reflink_gc_nr++,
GFP_KERNEL);
if (!r) {
- ret = -ENOMEM;
+ ret = -BCH_ERR_ENOMEM_gc_reflink_start;
break;
}
bch2_mark_superblocks(c);
- if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb) &&
- !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags) &&
- c->opts.fix_errors != FSCK_OPT_NO) {
+ if (IS_ENABLED(CONFIG_BCACHEFS_DEBUG) ||
+ (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb) &&
+ !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags) &&
+ c->opts.fix_errors != FSCK_OPT_NO)) {
bch_info(c, "Starting topology repair pass");
ret = bch2_repair_topology(c);
if (ret)
percpu_up_read(&c->mark_lock);
return 0;
update:
- u = bch2_bkey_make_mut(trans, k);
+ u = bch2_bkey_make_mut(trans, iter, k, 0);
ret = PTR_ERR_OR_ZERO(u);
if (ret)
return ret;
bch2_extent_normalize(c, bkey_i_to_s(u));
- return bch2_trans_update(trans, iter, u, 0);
+ return 0;
}
static int bch2_alloc_write_oldest_gen(struct btree_trans *trans, struct btree_iter *iter,
ca->oldest_gen = kvmalloc(ca->mi.nbuckets, GFP_KERNEL);
if (!ca->oldest_gen) {
percpu_ref_put(&ca->ref);
- ret = -ENOMEM;
+ ret = -BCH_ERR_ENOMEM_gc_gens;
goto err;
}