xref: /linux/fs/bcachefs/progress.c (revision 4a4b30ea80d8cb5e8c4c62bb86201f4ea0d9b030)
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 			.type		= BCH_DISK_ACCOUNTING_btree,
21 			.btree.id	= i,
22 		};
23 
24 		u64 v;
25 		bch2_accounting_mem_read(c, disk_accounting_pos_to_bpos(&acc), &v, 1);
26 		s->nodes_total += div64_ul(v, btree_sectors(c));
27 	}
28 }
29 
progress_update_p(struct progress_indicator_state * s)30 static inline bool progress_update_p(struct progress_indicator_state *s)
31 {
32 	bool ret = time_after_eq(jiffies, s->next_print);
33 
34 	if (ret)
35 		s->next_print = jiffies + HZ * 10;
36 	return ret;
37 }
38 
bch2_progress_update_iter(struct btree_trans * trans,struct progress_indicator_state * s,struct btree_iter * iter,const char * msg)39 void bch2_progress_update_iter(struct btree_trans *trans,
40 			       struct progress_indicator_state *s,
41 			       struct btree_iter *iter,
42 			       const char *msg)
43 {
44 	struct bch_fs *c = trans->c;
45 	struct btree *b = path_l(btree_iter_path(trans, iter))->b;
46 
47 	s->nodes_seen += b != s->last_node;
48 	s->last_node = b;
49 
50 	if (progress_update_p(s)) {
51 		struct printbuf buf = PRINTBUF;
52 		unsigned percent = s->nodes_total
53 			? div64_u64(s->nodes_seen * 100, s->nodes_total)
54 			: 0;
55 
56 		prt_printf(&buf, "%s: %d%%, done %llu/%llu nodes, at ",
57 			   msg, percent, s->nodes_seen, s->nodes_total);
58 		bch2_bbpos_to_text(&buf, BBPOS(iter->btree_id, iter->pos));
59 
60 		bch_info(c, "%s", buf.buf);
61 		printbuf_exit(&buf);
62 	}
63 }
64