// SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h"
#include "bbpos.h"
#include "alloc_background.h"
#include "backpointers.h"
#include "bkey_buf.h"
#include "btree_cache.h"
#include "btree_update.h"
#include "btree_update_interior.h"
#include "btree_write_buffer.h"
#include "checksum.h"
#include "disk_accounting.h"
#include "error.h"
#include "progress.h"
#include "recovery_passes.h"
#include <linux/mm.h>
static int bch2_bucket_bitmap_set(struct bch_dev *, struct bucket_bitmap *, u64);
static inline struct bbpos bp_to_bbpos(struct bch_backpointer bp)
{
return (struct bbpos) {
.btree = bp.btree_id,
.pos = bp.pos,
};
}
int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
struct bkey_validate_context from)
{
struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
int ret = 0;
bkey_fsck_err_on(bp.v->level > BTREE_MAX_DEPTH,
c, backpointer_level_bad,
"backpointer level bad: %u >= %u",
bp.v->level, BTREE_MAX_DEPTH);
bkey_fsck_err_on(bp.k->p.inode == BCH_SB_MEMBER_INVALID,
c, backpointer_dev_bad,
"backpointer for BCH_SB_MEMBER_INVALID");
fsck_err:
return ret;
}
void bch2_backpointer_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
{
struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
struct bch_dev *ca;
u32 bucket_offset;
struct bpos bucket;
scoped_guard(rcu) {
ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
if (ca)
bucket = bp_pos_to_bucket_and_offset(ca, bp.k->p, &bucket_offset);
}
if (ca)
prt_printf(out, "bucket=%llu:%llu:%u ", bucket.inode, bucket.offset, bucket_offset);
else
prt_printf(out, "sector=%llu:%llu ", bp.k->p.inode, bp.k->p