mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-08 00:00:12 +03:00
Update bcachefs sources to 66119f8201e1 bcachefs: Improve bch2_reconcile_status_to_text()
This commit is contained in:
parent
63a9fe9b02
commit
7bf5599c8c
@ -1 +1 @@
|
||||
581f7e27bc9728b15e7f45d10784542b4ab23a90
|
||||
66119f8201e1dc63d7e9ed11874265ff64750218
|
||||
|
||||
@ -469,7 +469,7 @@ int __bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
|
||||
|
||||
int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
|
||||
{
|
||||
struct reconcile_scan s = { .type = REBALANCE_SCAN_pending };
|
||||
struct reconcile_scan s = { .type = RECONCILE_SCAN_pending };
|
||||
|
||||
try(bch2_set_reconcile_needs_scan(c, s, false));
|
||||
|
||||
|
||||
@ -336,7 +336,7 @@ void bch2_bkey_val_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
bch2_bkey_to_text(out, k.k);
|
||||
|
||||
if (bkey_val_bytes(k.k)) {
|
||||
guard(printbuf_atomic)(out);
|
||||
guard(printbuf_indent)(out);
|
||||
prt_printf(out, ": ");
|
||||
bch2_val_to_text(out, c, k);
|
||||
}
|
||||
|
||||
@ -672,6 +672,8 @@ static void bkey_strip_reconcile(const struct bch_fs *c, struct bkey_s k)
|
||||
break;
|
||||
}
|
||||
} while (dropped);
|
||||
|
||||
bch2_bkey_drop_ptrs(k, p, entry, p.ptr.dev == BCH_SB_MEMBER_INVALID);
|
||||
}
|
||||
|
||||
static bool bkey_has_reconcile(const struct bch_fs *c, struct bkey_s_c k)
|
||||
@ -679,7 +681,9 @@ static bool bkey_has_reconcile(const struct bch_fs *c, struct bkey_s_c k)
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
const union bch_extent_entry *entry;
|
||||
bkey_extent_entry_for_each(ptrs, entry)
|
||||
if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_reconcile)
|
||||
if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_reconcile ||
|
||||
(extent_entry_type(entry) == BCH_EXTENT_ENTRY_ptr &&
|
||||
entry->ptr.dev == BCH_SB_MEMBER_INVALID))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -716,6 +720,17 @@ static int btree_update_nodes_written_trans(struct btree_trans *trans,
|
||||
try(bch2_bkey_set_needs_reconcile(trans, NULL, &opts, &i->key,
|
||||
SET_NEEDS_REBALANCE_foreground, 0));
|
||||
|
||||
/*
|
||||
* This is not strictly the best way of doing this, what we
|
||||
* really want is a flag for 'did
|
||||
* bch2_bkey_set_needs_reconcile() change anything, and do we
|
||||
* need to update the node key'; there's no reason we couldn't
|
||||
* be calling bch2_bkey_set_needs_reconcile() at node allocation
|
||||
* time to better handle the case where we have to pad with
|
||||
* invalid pointers because we don't currently have devices
|
||||
* available to meet the desired replication level.
|
||||
*/
|
||||
|
||||
if (bkey_has_reconcile(c, bkey_i_to_s_c(&i->key))) {
|
||||
CLASS(btree_iter_uninit, iter)(trans);
|
||||
int ret = bch2_btree_node_get_iter(trans, &iter, i->b);
|
||||
|
||||
@ -1397,7 +1397,6 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
if (c)
|
||||
prt_printf(out, "durability: %u ", bch2_bkey_durability_safe(c, k));
|
||||
|
||||
prt_newline(out);
|
||||
guard(printbuf_atomic)(out);
|
||||
guard(rcu)();
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "init/progress.h"
|
||||
|
||||
#include "fs/inode.h"
|
||||
#include "fs/namei.h"
|
||||
|
||||
#include "snapshots/subvolume.h"
|
||||
|
||||
@ -32,6 +33,56 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched/cputime.h>
|
||||
|
||||
#define RECONCILE_WORK_IDS() \
|
||||
x(none) \
|
||||
x(hipri) \
|
||||
x(normal) \
|
||||
x(pending)
|
||||
|
||||
enum reconcile_work_id {
|
||||
#define x(t) RECONCILE_WORK_##t,
|
||||
RECONCILE_WORK_IDS()
|
||||
#undef x
|
||||
};
|
||||
|
||||
#define x(n) #n,
|
||||
|
||||
static const char * const reconcile_opts[] = {
|
||||
BCH_REBALANCE_OPTS()
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const reconcile_work_ids[] = {
|
||||
RECONCILE_WORK_IDS()
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const rebalance_scan_strs[] = {
|
||||
RECONCILE_SCAN_TYPES()
|
||||
};
|
||||
|
||||
#undef x
|
||||
|
||||
static const enum btree_id reconcile_work_btree[] = {
|
||||
[RECONCILE_WORK_hipri] = BTREE_ID_reconcile_hipri,
|
||||
[RECONCILE_WORK_normal] = BTREE_ID_reconcile_work,
|
||||
[RECONCILE_WORK_pending] = BTREE_ID_reconcile_pending,
|
||||
};
|
||||
|
||||
static enum reconcile_work_id btree_to_reconcile_work_id(enum btree_id btree)
|
||||
{
|
||||
switch (btree) {
|
||||
case BTREE_ID_reconcile_hipri:
|
||||
return RECONCILE_WORK_hipri;
|
||||
case BTREE_ID_reconcile_work:
|
||||
return RECONCILE_WORK_normal;
|
||||
case BTREE_ID_reconcile_pending:
|
||||
return RECONCILE_WORK_pending;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/* bch_extent_reconcile: */
|
||||
|
||||
int bch2_extent_reconcile_validate(struct bch_fs *c,
|
||||
@ -78,13 +129,6 @@ const struct bch_extent_reconcile *bch2_bkey_reconcile_opts(const struct bch_fs
|
||||
return bch2_bkey_ptrs_reconcile_opts(c, bch2_bkey_ptrs_c(k));
|
||||
}
|
||||
|
||||
static const char * const reconcile_opts[] = {
|
||||
#define x(n) #n,
|
||||
BCH_REBALANCE_OPTS()
|
||||
#undef x
|
||||
NULL
|
||||
};
|
||||
|
||||
void bch2_extent_rebalance_v1_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
const struct bch_extent_rebalance_v1 *r)
|
||||
{
|
||||
@ -191,20 +235,20 @@ void bch2_extent_reconcile_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: check in bkey_validate that if r->hipri or r->pending are set,
|
||||
* r->data_replicas are also set
|
||||
*/
|
||||
static enum reconcile_work_id rb_work_id(const struct bch_extent_reconcile *r)
|
||||
{
|
||||
if (!r || !r->need_rb)
|
||||
return RECONCILE_WORK_none;
|
||||
if (r->hipri)
|
||||
return RECONCILE_WORK_hipri;
|
||||
if (!r->pending)
|
||||
return RECONCILE_WORK_normal;
|
||||
return RECONCILE_WORK_pending;
|
||||
}
|
||||
|
||||
static enum btree_id rb_work_btree(const struct bch_extent_reconcile *r)
|
||||
{
|
||||
if (!r || !r->need_rb)
|
||||
return 0;
|
||||
if (r->hipri)
|
||||
return BTREE_ID_reconcile_hipri;
|
||||
if (r->pending)
|
||||
return BTREE_ID_reconcile_pending;
|
||||
return BTREE_ID_reconcile_work;
|
||||
return reconcile_work_btree[rb_work_id(r)];
|
||||
}
|
||||
|
||||
static inline unsigned rb_accounting_counters(const struct bch_extent_reconcile *r)
|
||||
@ -1005,30 +1049,23 @@ int bch2_bkey_get_io_opts(struct btree_trans *trans,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const bch2_reconcile_state_strs[] = {
|
||||
#define x(t) #t,
|
||||
BCH_REBALANCE_STATES()
|
||||
NULL
|
||||
#undef x
|
||||
};
|
||||
|
||||
#define REBALANCE_SCAN_COOKIE_device 32
|
||||
#define REBALANCE_SCAN_COOKIE_pending 2
|
||||
#define REBALANCE_SCAN_COOKIE_metadata 1
|
||||
#define REBALANCE_SCAN_COOKIE_fs 0
|
||||
#define RECONCILE_SCAN_COOKIE_device 32
|
||||
#define RECONCILE_SCAN_COOKIE_pending 2
|
||||
#define RECONCILE_SCAN_COOKIE_metadata 1
|
||||
#define RECONCILE_SCAN_COOKIE_fs 0
|
||||
|
||||
static u64 reconcile_scan_encode(struct reconcile_scan s)
|
||||
{
|
||||
switch (s.type) {
|
||||
case REBALANCE_SCAN_fs:
|
||||
return REBALANCE_SCAN_COOKIE_fs;
|
||||
case REBALANCE_SCAN_metadata:
|
||||
return REBALANCE_SCAN_COOKIE_metadata;
|
||||
case REBALANCE_SCAN_pending:
|
||||
return REBALANCE_SCAN_COOKIE_pending;
|
||||
case REBALANCE_SCAN_device:
|
||||
return REBALANCE_SCAN_COOKIE_device + s.dev;
|
||||
case REBALANCE_SCAN_inum:
|
||||
case RECONCILE_SCAN_fs:
|
||||
return RECONCILE_SCAN_COOKIE_fs;
|
||||
case RECONCILE_SCAN_metadata:
|
||||
return RECONCILE_SCAN_COOKIE_metadata;
|
||||
case RECONCILE_SCAN_pending:
|
||||
return RECONCILE_SCAN_COOKIE_pending;
|
||||
case RECONCILE_SCAN_device:
|
||||
return RECONCILE_SCAN_COOKIE_device + s.dev;
|
||||
case RECONCILE_SCAN_inum:
|
||||
return s.inum;
|
||||
default:
|
||||
BUG();
|
||||
@ -1038,21 +1075,39 @@ static u64 reconcile_scan_encode(struct reconcile_scan s)
|
||||
static struct reconcile_scan reconcile_scan_decode(struct bch_fs *c, u64 v)
|
||||
{
|
||||
if (v >= BCACHEFS_ROOT_INO)
|
||||
return (struct reconcile_scan) { .type = REBALANCE_SCAN_inum, .inum = v, };
|
||||
if (v >= REBALANCE_SCAN_COOKIE_device)
|
||||
return (struct reconcile_scan) { .type = RECONCILE_SCAN_inum, .inum = v, };
|
||||
if (v >= RECONCILE_SCAN_COOKIE_device)
|
||||
return (struct reconcile_scan) {
|
||||
.type = REBALANCE_SCAN_device,
|
||||
.dev = v - REBALANCE_SCAN_COOKIE_device,
|
||||
.type = RECONCILE_SCAN_device,
|
||||
.dev = v - RECONCILE_SCAN_COOKIE_device,
|
||||
};
|
||||
if (v == REBALANCE_SCAN_COOKIE_pending)
|
||||
return (struct reconcile_scan) { .type = REBALANCE_SCAN_pending };
|
||||
if (v == REBALANCE_SCAN_COOKIE_metadata)
|
||||
return (struct reconcile_scan) { .type = REBALANCE_SCAN_metadata };
|
||||
if (v == REBALANCE_SCAN_COOKIE_fs)
|
||||
return (struct reconcile_scan) { .type = REBALANCE_SCAN_fs};
|
||||
if (v == RECONCILE_SCAN_COOKIE_pending)
|
||||
return (struct reconcile_scan) { .type = RECONCILE_SCAN_pending };
|
||||
if (v == RECONCILE_SCAN_COOKIE_metadata)
|
||||
return (struct reconcile_scan) { .type = RECONCILE_SCAN_metadata };
|
||||
if (v == RECONCILE_SCAN_COOKIE_fs)
|
||||
return (struct reconcile_scan) { .type = RECONCILE_SCAN_fs};
|
||||
|
||||
bch_err(c, "unknown realance scan cookie %llu", v);
|
||||
return (struct reconcile_scan) { .type = REBALANCE_SCAN_fs};
|
||||
return (struct reconcile_scan) { .type = RECONCILE_SCAN_fs};
|
||||
}
|
||||
|
||||
static void reconcile_scan_to_text(struct printbuf *out,
|
||||
struct bch_fs *c, struct reconcile_scan s)
|
||||
{
|
||||
prt_str(out, rebalance_scan_strs[s.type]);
|
||||
switch (s.type) {
|
||||
case RECONCILE_SCAN_device:
|
||||
prt_str(out, ": ");
|
||||
bch2_prt_member_name(out, c, s.dev);
|
||||
break;
|
||||
case RECONCILE_SCAN_inum:
|
||||
prt_str(out, ": ");
|
||||
bch2_trans_do(c, bch2_inum_snapshot_to_path(trans, s.inum, 0, NULL, out));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int bch2_set_reconcile_needs_scan_trans(struct btree_trans *trans, struct reconcile_scan s)
|
||||
@ -1088,7 +1143,7 @@ int bch2_set_reconcile_needs_scan(struct bch_fs *c, struct reconcile_scan s, boo
|
||||
int bch2_set_fs_needs_reconcile(struct bch_fs *c)
|
||||
{
|
||||
return bch2_set_reconcile_needs_scan(c,
|
||||
(struct reconcile_scan) { .type = REBALANCE_SCAN_fs },
|
||||
(struct reconcile_scan) { .type = RECONCILE_SCAN_fs },
|
||||
true);
|
||||
}
|
||||
|
||||
@ -1307,6 +1362,7 @@ static int bch2_extent_set_rb_pending(struct btree_trans *trans,
|
||||
BUG_ON(!r);
|
||||
|
||||
r->pending = true;
|
||||
r->hipri = false;
|
||||
|
||||
return bch2_trans_commit(trans, NULL, NULL, 0);
|
||||
}
|
||||
@ -1320,7 +1376,6 @@ static int __do_reconcile_extent(struct moving_context *ctxt,
|
||||
u32 restart_count = trans->restart_count;
|
||||
|
||||
ctxt->stats = &c->reconcile.work_stats;
|
||||
c->reconcile.state = BCH_REBALANCE_working;
|
||||
|
||||
int ret = bch2_move_extent(ctxt, NULL, snapshot_io_opts,
|
||||
reconcile_set_data_opts, NULL,
|
||||
@ -1355,11 +1410,13 @@ static int __do_reconcile_extent(struct moving_context *ctxt,
|
||||
|
||||
static int do_reconcile_extent(struct moving_context *ctxt,
|
||||
struct per_snapshot_io_opts *snapshot_io_opts,
|
||||
struct bbpos pos)
|
||||
struct bpos work_pos)
|
||||
{
|
||||
struct bbpos data_pos = rb_work_to_data_pos(work_pos);
|
||||
|
||||
struct btree_trans *trans = ctxt->trans;
|
||||
|
||||
CLASS(btree_iter, iter)(trans, pos.btree, pos.pos, BTREE_ITER_all_snapshots);
|
||||
CLASS(btree_iter, iter)(trans, data_pos.btree, data_pos.pos, BTREE_ITER_all_snapshots);
|
||||
struct bkey_s_c k = bkey_try(bch2_btree_iter_peek_slot(&iter));
|
||||
|
||||
return __do_reconcile_extent(ctxt, snapshot_io_opts, &iter, k);
|
||||
@ -1546,14 +1603,12 @@ static int do_reconcile_scan(struct moving_context *ctxt,
|
||||
bch2_move_stats_init(&r->scan_stats, "reconcile_scan");
|
||||
ctxt->stats = &r->scan_stats;
|
||||
|
||||
r->state = BCH_REBALANCE_scanning;
|
||||
|
||||
struct reconcile_scan s = reconcile_scan_decode(c, cookie_pos.offset);
|
||||
if (s.type == REBALANCE_SCAN_fs) {
|
||||
if (s.type == RECONCILE_SCAN_fs) {
|
||||
try(do_reconcile_scan_fs(ctxt, snapshot_io_opts, false));
|
||||
} else if (s.type == REBALANCE_SCAN_metadata) {
|
||||
} else if (s.type == RECONCILE_SCAN_metadata) {
|
||||
try(do_reconcile_scan_fs(ctxt, snapshot_io_opts, true));
|
||||
} else if (s.type == REBALANCE_SCAN_device) {
|
||||
} else if (s.type == RECONCILE_SCAN_device) {
|
||||
r->scan_start = BBPOS(BTREE_ID_backpointers, POS(s.dev, 0));
|
||||
r->scan_end = BBPOS(BTREE_ID_backpointers, POS(s.dev, U64_MAX));
|
||||
|
||||
@ -1576,7 +1631,7 @@ static int do_reconcile_scan(struct moving_context *ctxt,
|
||||
bch2_disk_reservation_put(c, &res.r);
|
||||
do_reconcile_scan_bp(trans, bkey_s_c_to_backpointer(k), &last_flushed);
|
||||
})));
|
||||
} else if (s.type == REBALANCE_SCAN_inum) {
|
||||
} else if (s.type == RECONCILE_SCAN_inum) {
|
||||
r->scan_start = BBPOS(BTREE_ID_extents, POS(s.inum, 0));
|
||||
r->scan_end = BBPOS(BTREE_ID_extents, POS(s.inum, U64_MAX));
|
||||
|
||||
@ -1610,10 +1665,10 @@ static void reconcile_wait(struct bch_fs *c)
|
||||
|
||||
r->wait_iotime_end = now + (min_member_capacity >> 6);
|
||||
|
||||
if (r->state != BCH_REBALANCE_waiting) {
|
||||
if (r->running) {
|
||||
r->wait_iotime_start = now;
|
||||
r->wait_wallclock_start = ktime_get_real_ns();
|
||||
r->state = BCH_REBALANCE_waiting;
|
||||
r->running = false;
|
||||
}
|
||||
|
||||
bch2_kthread_io_clock_wait_once(clock, r->wait_iotime_end, MAX_SCHEDULE_TIMEOUT);
|
||||
@ -1649,7 +1704,8 @@ static int do_reconcile(struct moving_context *ctxt)
|
||||
BTREE_ID_reconcile_pending,
|
||||
};
|
||||
unsigned i = 0;
|
||||
struct bpos work_pos = POS_MIN;
|
||||
|
||||
r->work_pos = BBPOS(scan_btrees[i], POS_MIN);
|
||||
|
||||
struct bkey_i_cookie pending_cookie;
|
||||
bkey_init(&pending_cookie.k);
|
||||
@ -1666,11 +1722,11 @@ static int do_reconcile(struct moving_context *ctxt)
|
||||
if (kick != r->kick) {
|
||||
kick = r->kick;
|
||||
i = 0;
|
||||
work_pos = POS_MIN;
|
||||
r->work_pos = BBPOS(scan_btrees[i], POS_MIN);
|
||||
work.nr = 0;
|
||||
}
|
||||
|
||||
struct bkey_s_c k = next_reconcile_entry(trans, &work, scan_btrees[i], &work_pos);
|
||||
struct bkey_s_c k = next_reconcile_entry(trans, &work, r->work_pos.btree, &r->work_pos.pos);
|
||||
ret = bkey_err(k);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1679,16 +1735,19 @@ static int do_reconcile(struct moving_context *ctxt)
|
||||
if (++i == ARRAY_SIZE(scan_btrees))
|
||||
break;
|
||||
|
||||
work_pos = POS_MIN;
|
||||
r->work_pos = BBPOS(scan_btrees[i], POS_MIN);
|
||||
|
||||
if (scan_btrees[i] == BTREE_ID_reconcile_pending &&
|
||||
if (r->work_pos.btree == BTREE_ID_reconcile_pending &&
|
||||
bkey_deleted(&pending_cookie.k))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
r->running = true;
|
||||
r->work_pos.pos = k.k->p;
|
||||
|
||||
if (k.k->type == KEY_TYPE_cookie &&
|
||||
reconcile_scan_decode(c, k.k->p.offset).type == REBALANCE_SCAN_pending)
|
||||
reconcile_scan_decode(c, k.k->p.offset).type == RECONCILE_SCAN_pending)
|
||||
bkey_reassemble(&pending_cookie.k_i, k);
|
||||
|
||||
if (k.k->type == KEY_TYPE_cookie)
|
||||
@ -1701,8 +1760,7 @@ static int do_reconcile(struct moving_context *ctxt)
|
||||
bkey_s_c_to_backpointer(k));
|
||||
else
|
||||
ret = lockrestart_do(trans,
|
||||
do_reconcile_extent(ctxt, &snapshot_io_opts,
|
||||
rb_work_to_data_pos(k.k->p)));
|
||||
do_reconcile_extent(ctxt, &snapshot_io_opts, k.k->p));
|
||||
|
||||
if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) {
|
||||
ret = 0;
|
||||
@ -1712,8 +1770,8 @@ static int do_reconcile(struct moving_context *ctxt)
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (scan_btrees[i] == BTREE_ID_reconcile_scan)
|
||||
work_pos = bpos_successor(work_pos);
|
||||
if (r->work_pos.btree == BTREE_ID_reconcile_scan)
|
||||
r->work_pos.pos = bpos_successor(r->work_pos.pos);
|
||||
}
|
||||
|
||||
if (!ret && !bkey_deleted(&pending_cookie.k))
|
||||
@ -1782,13 +1840,10 @@ void bch2_reconcile_status_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
}
|
||||
|
||||
prt_newline(out);
|
||||
guard(printbuf_indent_nextline)(out);
|
||||
|
||||
prt_str(out, bch2_reconcile_state_strs[r->state]);
|
||||
prt_newline(out);
|
||||
guard(printbuf_indent)(out);
|
||||
|
||||
switch (r->state) {
|
||||
case BCH_REBALANCE_waiting: {
|
||||
if (!r->running) {
|
||||
prt_printf(out, "waiting:\n");
|
||||
u64 now = atomic64_read(&c->io_clock[WRITE].now);
|
||||
|
||||
prt_printf(out, "io wait duration:\t");
|
||||
@ -1802,16 +1857,28 @@ void bch2_reconcile_status_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
prt_printf(out, "duration waited:\t");
|
||||
bch2_pr_time_units(out, ktime_get_real_ns() - r->wait_wallclock_start);
|
||||
prt_newline(out);
|
||||
break;
|
||||
}
|
||||
case BCH_REBALANCE_working:
|
||||
bch2_move_stats_to_text(out, &r->work_stats);
|
||||
break;
|
||||
case BCH_REBALANCE_scanning:
|
||||
bch2_move_stats_to_text(out, &r->scan_stats);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
struct bbpos work_pos = r->work_pos;
|
||||
barrier();
|
||||
|
||||
if (work_pos.btree == BTREE_ID_reconcile_scan &&
|
||||
work_pos.pos.inode == 0) {
|
||||
prt_printf(out, "scanning:\n");
|
||||
reconcile_scan_to_text(out, c,
|
||||
reconcile_scan_decode(c, work_pos.pos.offset));
|
||||
} else if (work_pos.btree == BTREE_ID_reconcile_scan) {
|
||||
prt_printf(out, "processing metadata: %s %llu\n",
|
||||
reconcile_work_ids[work_pos.pos.inode - 1],
|
||||
work_pos.pos.offset);
|
||||
|
||||
} else {
|
||||
prt_printf(out, "processing data: %s ",
|
||||
reconcile_work_ids[btree_to_reconcile_work_id(work_pos.btree)]);
|
||||
|
||||
bch2_bbpos_to_text(out, rb_work_to_data_pos(work_pos.pos));
|
||||
prt_newline(out);
|
||||
}
|
||||
}
|
||||
|
||||
struct task_struct *t;
|
||||
scoped_guard(rcu) {
|
||||
|
||||
@ -114,13 +114,18 @@ int bch2_bkey_set_needs_reconcile(struct btree_trans *,
|
||||
struct per_snapshot_io_opts *, struct bch_inode_opts *,
|
||||
struct bkey_i *, enum set_needs_reconcile_ctx, u32);
|
||||
|
||||
#define RECONCILE_SCAN_TYPES() \
|
||||
x(fs) \
|
||||
x(metadata) \
|
||||
x(pending) \
|
||||
x(device) \
|
||||
x(inum)
|
||||
|
||||
struct reconcile_scan {
|
||||
enum reconcile_scan_type {
|
||||
REBALANCE_SCAN_fs,
|
||||
REBALANCE_SCAN_metadata,
|
||||
REBALANCE_SCAN_pending,
|
||||
REBALANCE_SCAN_device,
|
||||
REBALANCE_SCAN_inum,
|
||||
#define x(t) RECONCILE_SCAN_##t,
|
||||
RECONCILE_SCAN_TYPES()
|
||||
#undef x
|
||||
} type;
|
||||
|
||||
union {
|
||||
|
||||
@ -5,26 +5,16 @@
|
||||
#include "btree/bbpos_types.h"
|
||||
#include "move_types.h"
|
||||
|
||||
#define BCH_REBALANCE_STATES() \
|
||||
x(waiting) \
|
||||
x(working) \
|
||||
x(scanning)
|
||||
|
||||
enum bch_reconcile_states {
|
||||
#define x(t) BCH_REBALANCE_##t,
|
||||
BCH_REBALANCE_STATES()
|
||||
#undef x
|
||||
};
|
||||
|
||||
struct bch_fs_reconcile {
|
||||
struct task_struct __rcu *thread;
|
||||
u32 kick;
|
||||
|
||||
enum bch_reconcile_states state;
|
||||
bool running;
|
||||
u64 wait_iotime_start;
|
||||
u64 wait_iotime_end;
|
||||
u64 wait_wallclock_start;
|
||||
|
||||
struct bbpos work_pos;
|
||||
struct bch_move_stats work_stats;
|
||||
|
||||
struct bbpos scan_start;
|
||||
|
||||
@ -595,8 +595,10 @@ void bch2_data_update_to_text(struct printbuf *out, struct data_update *m)
|
||||
|
||||
prt_str_indented(out, "old key:\t");
|
||||
bch2_bkey_val_to_text(out, m->op.c, bkey_i_to_s_c(m->k.k));
|
||||
prt_newline(out);
|
||||
|
||||
bch2_write_op_to_text(out, &m->op);
|
||||
prt_printf(out, "write: ");
|
||||
__bch2_write_op_to_text(out, &m->op);
|
||||
}
|
||||
|
||||
void bch2_data_update_inflight_to_text(struct printbuf *out, struct data_update *m)
|
||||
@ -613,7 +615,7 @@ void bch2_data_update_inflight_to_text(struct printbuf *out, struct data_update
|
||||
} else {
|
||||
prt_printf(out, "write:\n");
|
||||
guard(printbuf_indent)(out);
|
||||
bch2_write_op_to_text(out, &m->op);
|
||||
__bch2_write_op_to_text(out, &m->op);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1754,7 +1754,7 @@ static const char * const bch2_write_flags[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
void bch2_write_op_to_text(struct printbuf *out, struct bch_write_op *op)
|
||||
void __bch2_write_op_to_text(struct printbuf *out, struct bch_write_op *op)
|
||||
{
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 32);
|
||||
@ -1784,6 +1784,11 @@ void bch2_write_op_to_text(struct printbuf *out, struct bch_write_op *op)
|
||||
|
||||
prt_printf(out, "ref:\t%u\n", closure_nr_remaining(&op->cl));
|
||||
prt_printf(out, "ret\t%s\n", bch2_err_str(op->error));
|
||||
}
|
||||
|
||||
void bch2_write_op_to_text(struct printbuf *out, struct bch_write_op *op)
|
||||
{
|
||||
__bch2_write_op_to_text(out, op);
|
||||
|
||||
if (op->flags & BCH_WRITE_move) {
|
||||
prt_printf(out, "update:\n");
|
||||
|
||||
@ -70,6 +70,7 @@ static inline struct bch_write_bio *wbio_init(struct bio *bio)
|
||||
return wbio;
|
||||
}
|
||||
|
||||
void __bch2_write_op_to_text(struct printbuf *, struct bch_write_op *);
|
||||
void bch2_write_op_to_text(struct printbuf *, struct bch_write_op *);
|
||||
|
||||
void bch2_fs_io_write_exit(struct bch_fs *);
|
||||
|
||||
@ -528,9 +528,27 @@ static int __bch2_inum_to_path(struct btree_trans *trans,
|
||||
DARRAY(subvol_inum) inums = {};
|
||||
|
||||
if (!snapshot) {
|
||||
if (subvol) {
|
||||
ret = bch2_subvolume_get_snapshot(trans, subvol, &snapshot);
|
||||
if (ret)
|
||||
goto disconnected;
|
||||
} else {
|
||||
struct bkey_s_c k;
|
||||
for_each_btree_key_max_norestart(trans, iter,
|
||||
BTREE_ID_inodes,
|
||||
POS(0, inum),
|
||||
SPOS(0, inum, U32_MAX),
|
||||
BTREE_ITER_all_snapshots, k, ret) {
|
||||
if (bkey_is_inode(k.k)) {
|
||||
snapshot = k.k->p.snapshot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!snapshot)
|
||||
goto disconnected;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
||||
@ -605,8 +605,8 @@ int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca,
|
||||
new_state == BCH_MEMBER_STATE_failed;
|
||||
|
||||
struct reconcile_scan s = new_state == BCH_MEMBER_STATE_rw
|
||||
? (struct reconcile_scan) { .type = REBALANCE_SCAN_pending }
|
||||
: (struct reconcile_scan) { .type = REBALANCE_SCAN_device, .dev = ca->dev_idx };
|
||||
? (struct reconcile_scan) { .type = RECONCILE_SCAN_pending }
|
||||
: (struct reconcile_scan) { .type = RECONCILE_SCAN_device, .dev = ca->dev_idx };
|
||||
|
||||
if (do_reconcile_scan)
|
||||
try(bch2_set_reconcile_needs_scan(c, s, false));
|
||||
@ -811,7 +811,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path, struct printbuf *err)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
struct reconcile_scan s = { .type = REBALANCE_SCAN_pending };
|
||||
struct reconcile_scan s = { .type = RECONCILE_SCAN_pending };
|
||||
if (test_bit(BCH_FS_started, &c->flags)) {
|
||||
/*
|
||||
* Technically incorrect, but 'bcachefs image update' is the
|
||||
@ -1012,7 +1012,7 @@ int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets, struct p
|
||||
}
|
||||
|
||||
bool wakeup_reconcile_pending = nbuckets > ca->mi.nbuckets;
|
||||
struct reconcile_scan s = { .type = REBALANCE_SCAN_pending };
|
||||
struct reconcile_scan s = { .type = RECONCILE_SCAN_pending };
|
||||
if (wakeup_reconcile_pending)
|
||||
try(bch2_set_reconcile_needs_scan(c, s, false));
|
||||
|
||||
|
||||
@ -547,7 +547,7 @@ static int opt_hook_io(struct bch_fs *c, struct bch_dev *ca, u64 inum, enum bch_
|
||||
case Opt_data_replicas:
|
||||
case Opt_erasure_code: {
|
||||
struct reconcile_scan s = {
|
||||
.type = !inum ? REBALANCE_SCAN_fs : REBALANCE_SCAN_inum,
|
||||
.type = !inum ? RECONCILE_SCAN_fs : RECONCILE_SCAN_inum,
|
||||
.inum = inum,
|
||||
};
|
||||
|
||||
@ -558,15 +558,15 @@ static int opt_hook_io(struct bch_fs *c, struct bch_dev *ca, u64 inum, enum bch_
|
||||
case Opt_metadata_checksum:
|
||||
case Opt_metadata_replicas:
|
||||
try(bch2_set_reconcile_needs_scan(c,
|
||||
(struct reconcile_scan) { .type = REBALANCE_SCAN_metadata, .dev = inum }, post));
|
||||
(struct reconcile_scan) { .type = RECONCILE_SCAN_metadata, .dev = inum }, post));
|
||||
break;
|
||||
case Opt_durability:
|
||||
if (!post && v > ca->mi.durability)
|
||||
try(bch2_set_reconcile_needs_scan(c,
|
||||
(struct reconcile_scan) { .type = REBALANCE_SCAN_pending}, post));
|
||||
(struct reconcile_scan) { .type = RECONCILE_SCAN_pending}, post));
|
||||
|
||||
try(bch2_set_reconcile_needs_scan(c,
|
||||
(struct reconcile_scan) { .type = REBALANCE_SCAN_device, .dev = inum }, post));
|
||||
(struct reconcile_scan) { .type = RECONCILE_SCAN_device, .dev = inum }, post));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -277,8 +277,8 @@ void bch2_member_to_text(struct printbuf *out,
|
||||
prt_printf(out, "Freespace initialized:\t%llu\n", BCH_MEMBER_FREESPACE_INITIALIZED(m));
|
||||
prt_printf(out, "Resize on mount:\t%llu\n", BCH_MEMBER_RESIZE_ON_MOUNT(m));
|
||||
|
||||
prt_printf(out, "Last device name:\t%.*s", (int) sizeof(m->device_name), m->device_name);
|
||||
prt_printf(out, "Last device model:\t%.*s", (int) sizeof(m->device_model), m->device_model);
|
||||
prt_printf(out, "Last device name:\t%.*s\n", (int) sizeof(m->device_name), m->device_name);
|
||||
prt_printf(out, "Last device model:\t%.*s\n", (int) sizeof(m->device_model), m->device_model);
|
||||
}
|
||||
|
||||
static void bch2_member_to_text_short_sb(struct printbuf *out,
|
||||
|
||||
@ -410,4 +410,15 @@ void bch2_dev_btree_bitmap_mark(struct bch_fs *, struct bkey_s_c);
|
||||
int bch2_sb_member_alloc(struct bch_fs *);
|
||||
void bch2_sb_members_clean_deleted(struct bch_fs *);
|
||||
|
||||
static inline void bch2_prt_member_name(struct printbuf *out, struct bch_fs *c, unsigned idx)
|
||||
{
|
||||
guard(rcu)();
|
||||
guard(printbuf_atomic)(out);
|
||||
struct bch_dev *ca = c ? bch2_dev_rcu_noerror(c, idx) : NULL;
|
||||
if (ca)
|
||||
prt_str(out, ca->name);
|
||||
else
|
||||
prt_printf(out, "(invalid device %u)", idx);
|
||||
}
|
||||
|
||||
#endif /* _BCACHEFS_SB_MEMBERS_H */
|
||||
|
||||
@ -299,18 +299,12 @@ DEFINE_GUARD(printbuf_atomic, struct printbuf *,
|
||||
printbuf_atomic_inc(_T),
|
||||
printbuf_atomic_dec(_T));
|
||||
|
||||
static inline void printbuf_indent_add_2(struct printbuf *out)
|
||||
{
|
||||
bch2_printbuf_indent_add(out, 2);
|
||||
}
|
||||
|
||||
static inline void printbuf_indent_sub_2(struct printbuf *out)
|
||||
{
|
||||
bch2_printbuf_indent_sub(out, 2);
|
||||
}
|
||||
|
||||
DEFINE_GUARD(printbuf_indent, struct printbuf *,
|
||||
printbuf_indent_add_2(_T),
|
||||
printbuf_indent_sub_2(_T));
|
||||
bch2_printbuf_indent_add(_T, 2),
|
||||
bch2_printbuf_indent_sub(_T, 2));
|
||||
|
||||
DEFINE_GUARD(printbuf_indent_nextline, struct printbuf *,
|
||||
bch2_printbuf_indent_add_nextline(_T, 2),
|
||||
bch2_printbuf_indent_sub(_T, 2));
|
||||
|
||||
#endif /* _BCACHEFS_PRINTBUF_H */
|
||||
|
||||
@ -125,7 +125,7 @@ static int bch2_write_inode_trans(struct btree_trans *trans,
|
||||
if (*reconcile_changed)
|
||||
try(bch2_set_reconcile_needs_scan_trans(trans,
|
||||
(struct reconcile_scan) {
|
||||
.type = REBALANCE_SCAN_inum,
|
||||
.type = RECONCILE_SCAN_inum,
|
||||
.inum = inode_u.bi_inum }));
|
||||
|
||||
try(bch2_inode_write(trans, &iter, &inode_u));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user