1 // SPDX-License-Identifier: GPL-2.0
2 #include "bcachefs.h"
3 #include "bbpos.h"
4 #include "disk_accounting.h"
5 #include "progress.h"
6
bch2_progress_init(struct progress_indicator_state * s,struct bch_fs * c,u64 btree_id_mask)7 void bch2_progress_init(struct progress_indicator_state *s,
8 struct bch_fs *c,
9 u64 btree_id_mask)
10 {
11 memset(s, 0, sizeof(*s));
12
13 s->next_print = jiffies + HZ * 10;
14
15 for (unsigned i = 0; i < BTREE_ID_NR; i++) {
16 if (!(btree_id_mask & BIT_ULL(i)))
17 continue;
18
19 struct disk_accounting_pos acc;
20 disk_accounting_key_init(acc, btree, .id = i);
21
22 u64 v;
23 bch2_accounting_mem_read(c, disk_accounting_pos_to_bpos(&acc), &v, 1);
24 s->nodes_total += div64_ul(v, btree_sectors(c));
25 }
26 }
27
progress_update_p(struct progress_indicator_state * s)28 static inline bool progress_update_p(struct progress_indicator_state *s)
29 {
30 bool ret = time_after_eq(jiffies, s->next_print);
31
32 if (ret)
33 s->next_print = jiffies + HZ * 10;
34 return ret;
35 }
36
bch2_progress_update_iter(struct btree_trans * trans,struct progress_indicator_state * s,struct btree_iter * iter,const char * msg)37 void bch2_progress_update_iter(struct btree_trans *trans,
38 struct progress_indicator_state *s,
39 struct btree_iter *iter,
40 const char *msg)
41 {
42 struct bch_fs *c = trans->c;
43 struct btree *b = path_l(btree_iter_path(trans, iter))->b;
44
45 s->nodes_seen += b != s->last_node;
46 s->last_node = b;
47
48 if (progress_update_p(s)) {
49 struct printbuf buf = PRINTBUF;
50 unsigned percent = s->nodes_total
51 ? div64_u64(s->nodes_seen * 100, s->nodes_total)
52 : 0;
53
54 prt_printf(&buf, "%s: %d%%, done %llu/%llu nodes, at ",
55 msg, percent, s->nodes_seen, s->nodes_total);
56 bch2_bbpos_to_text(&buf, BBPOS(iter->btree_id, iter->pos));
57
58 bch_info(c, "%s", buf.buf);
59 printbuf_exit(&buf);
60 }
61 }
62