#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
}
if (ret) {
- bch_err(c, "%s: error getting btree node: %s",
- __func__, bch2_err_str(ret));
+ bch_err_msg(c, ret, "getting btree node");
break;
}
ret = PTR_ERR_OR_ZERO(cur);
if (ret) {
- bch_err(c, "%s: error getting btree node: %s",
- __func__, bch2_err_str(ret));
+ bch_err_msg(c, ret, "getting btree node");
goto err;
}
bch2_trans_init(&trans, c, 0, 0);
- for (i = 0; i < BTREE_ID_NR && !ret; i++) {
- b = c->btree_roots[i].b;
+ for (i = 0; i < btree_id_nr_alive(c)&& !ret; i++) {
+ struct btree_root *r = bch2_btree_id_root(c, i);
+
+ if (!r->alive)
+ continue;
+
+ b = r->b;
if (btree_node_fake(b))
continue;
new = kmalloc(bkey_bytes(k->k), GFP_KERNEL);
if (!new) {
- bch_err(c, "%s: error allocating new key", __func__);
+ bch_err_msg(c, ret, "allocating new key");
ret = -BCH_ERR_ENOMEM_gc_repair_key;
goto err;
}
fsck_err:
err:
if (ret)
- bch_err(c, "error from %s(): %s", __func__, bch2_err_str(ret));
+ bch_err_fn(c, ret);
return ret;
}
return ret;
mutex_lock(&c->btree_root_lock);
- b = c->btree_roots[btree_id].b;
+ b = bch2_btree_id_root(c, btree_id)->b;
if (!btree_node_fake(b)) {
struct bkey_s_c k = bkey_i_to_s_c(&b->key);
ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level,
false, &k, true);
- if (ret) {
- bch_err(c, "%s: error from bch2_gc_mark_key: %s",
- __func__, bch2_err_str(ret));
+ if (ret)
goto fsck_err;
- }
if (b->c.level) {
bch2_bkey_buf_reassemble(&cur, c, k);
continue;
}
} else if (ret) {
- bch_err(c, "%s: error getting btree node: %s",
- __func__, bch2_err_str(ret));
+ bch_err_msg(c, ret, "getting btree node");
break;
}
struct printbuf buf = PRINTBUF;
int ret = 0;
- b = c->btree_roots[btree_id].b;
+ b = bch2_btree_id_root(c, btree_id)->b;
if (btree_node_fake(b))
return 0;
six_unlock_read(&b->c.lock);
if (ret < 0)
- bch_err(c, "error from %s(): %s", __func__, bch2_err_str(ret));
+ bch_err_fn(c, ret);
printbuf_exit(&buf);
return ret;
}
? bch2_gc_btree_init(&trans, ids[i], metadata_only)
: bch2_gc_btree(&trans, ids[i], initial, metadata_only);
+ for (i = BTREE_ID_NR; i < btree_id_nr_alive(c) && !ret; i++) {
+ if (!bch2_btree_id_root(c, i)->alive)
+ continue;
+
+ ret = initial
+ ? bch2_gc_btree_init(&trans, i, metadata_only)
+ : bch2_gc_btree(&trans, i, initial, metadata_only);
+ }
+
if (ret < 0)
- bch_err(c, "error from %s(): %s", __func__, bch2_err_str(ret));
+ bch_err_fn(c, ret);
bch2_trans_exit(&trans);
return ret;
for_each_member_device(ca, c, dev) {
struct bch_dev_usage *dst = ca->usage_base;
struct bch_dev_usage *src = (void *)
- bch2_acc_percpu_u64s((void *) ca->usage_gc,
+ bch2_acc_percpu_u64s((u64 __percpu *) ca->usage_gc,
dev_usage_u64s());
copy_dev_field(buckets_ec, "buckets_ec");
unsigned nr = fs_usage_u64s(c);
struct bch_fs_usage *dst = c->usage_base;
struct bch_fs_usage *src = (void *)
- bch2_acc_percpu_u64s((void *) c->usage_gc, nr);
+ bch2_acc_percpu_u64s((u64 __percpu *) c->usage_gc, nr);
copy_fs_field(hidden, "hidden");
copy_fs_field(btree, "btree");
if (ca)
percpu_ref_put(&ca->ref);
if (ret)
- bch_err(c, "error from %s(): %s", __func__, bch2_err_str(ret));
+ bch_err_fn(c, ret);
percpu_up_write(&c->mark_lock);
printbuf_exit(&buf);
" 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);
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) &&
+ c->curr_recovery_pass <= BCH_RECOVERY_PASS_check_allocations &&
+ c->opts.fix_errors != FSCK_OPT_NO)) {
bch_info(c, "Starting topology repair pass");
ret = bch2_repair_topology(c);
if (ret)
if (ret == -BCH_ERR_need_topology_repair &&
!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) &&
- !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) {
+ c->curr_recovery_pass <= BCH_RECOVERY_PASS_check_allocations) {
set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
SET_BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb, true);
ret = 0;
* allocator thread - issue wakeup in case they blocked on gc_lock:
*/
closure_wake_up(&c->freelist_wait);
+
+ if (ret)
+ bch_err_fn(c, ret);
return 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,