1 // SPDX-License-Identifier: GPL-2.0
4 #include "sb-counters.h"
6 /* BCH_SB_FIELD_counters */
8 static const char * const bch2_counter_names
[] = {
9 #define x(t, n, ...) (#t),
10 BCH_PERSISTENT_COUNTERS()
15 static size_t bch2_sb_counter_nr_entries(struct bch_sb_field_counters
*ctrs
)
20 return (__le64
*) vstruct_end(&ctrs
->field
) - &ctrs
->d
[0];
23 static int bch2_sb_counters_validate(struct bch_sb
*sb
, struct bch_sb_field
*f
,
24 enum bch_validate_flags flags
, struct printbuf
*err
)
29 static void bch2_sb_counters_to_text(struct printbuf
*out
, struct bch_sb
*sb
,
30 struct bch_sb_field
*f
)
32 struct bch_sb_field_counters
*ctrs
= field_to_type(f
, counters
);
33 unsigned int nr
= bch2_sb_counter_nr_entries(ctrs
);
35 for (unsigned i
= 0; i
< nr
; i
++)
36 prt_printf(out
, "%s \t%llu\n",
37 i
< BCH_COUNTER_NR
? bch2_counter_names
[i
] : "(unknown)",
38 le64_to_cpu(ctrs
->d
[i
]));
41 int bch2_sb_counters_to_cpu(struct bch_fs
*c
)
43 struct bch_sb_field_counters
*ctrs
= bch2_sb_field_get(c
->disk_sb
.sb
, counters
);
45 unsigned int nr
= bch2_sb_counter_nr_entries(ctrs
);
48 for (i
= 0; i
< BCH_COUNTER_NR
; i
++)
49 c
->counters_on_mount
[i
] = 0;
51 for (i
= 0; i
< min_t(unsigned int, nr
, BCH_COUNTER_NR
); i
++) {
52 val
= le64_to_cpu(ctrs
->d
[i
]);
53 percpu_u64_set(&c
->counters
[i
], val
);
54 c
->counters_on_mount
[i
] = val
;
59 int bch2_sb_counters_from_cpu(struct bch_fs
*c
)
61 struct bch_sb_field_counters
*ctrs
= bch2_sb_field_get(c
->disk_sb
.sb
, counters
);
62 struct bch_sb_field_counters
*ret
;
64 unsigned int nr
= bch2_sb_counter_nr_entries(ctrs
);
66 if (nr
< BCH_COUNTER_NR
) {
67 ret
= bch2_sb_field_resize(&c
->disk_sb
, counters
,
68 sizeof(*ctrs
) / sizeof(u64
) + BCH_COUNTER_NR
);
72 nr
= bch2_sb_counter_nr_entries(ctrs
);
77 for (i
= 0; i
< min_t(unsigned int, nr
, BCH_COUNTER_NR
); i
++)
78 ctrs
->d
[i
] = cpu_to_le64(percpu_u64_get(&c
->counters
[i
]));
82 void bch2_fs_counters_exit(struct bch_fs
*c
)
84 free_percpu(c
->counters
);
87 int bch2_fs_counters_init(struct bch_fs
*c
)
89 c
->counters
= __alloc_percpu(sizeof(u64
) * BCH_COUNTER_NR
, sizeof(u64
));
91 return -BCH_ERR_ENOMEM_fs_counters_init
;
93 return bch2_sb_counters_to_cpu(c
);
96 const struct bch_sb_field_ops bch_sb_field_ops_counters
= {
97 .validate
= bch2_sb_counters_validate
,
98 .to_text
= bch2_sb_counters_to_text
,