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 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 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 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