On 2024/9/6 0:59, Reed Riley wrote:
Bcachefs often uses this function to divide by nanosecond times - which
can easily cause problems when cast to u32.  For example, `cat
/sys/fs/bcachefs/*/internal/rebalance_status` would return invalid data
in the `duration waited` field because dividing by the number of
nanoseconds in a minute requires the divisor parameter to be u64.

Signed-off-by: Reed Riley <[email protected]>
---
  fs/bcachefs/super-io.c |  2 +-
  fs/bcachefs/sysfs.c    |  2 +-
  fs/bcachefs/util.c     | 12 ++++++------
  3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
index c8c2ccbdfbb5..6f71e8cef7ea 100644
--- a/fs/bcachefs/super-io.c
+++ b/fs/bcachefs/super-io.c
@@ -521,7 +521,7 @@ static void bch2_sb_update(struct bch_fs *c)
        c->sb.time_units_per_sec = NSEC_PER_SEC / c->sb.nsec_per_time_unit;
/* XXX this is wrong, we need a 96 or 128 bit integer type */
-       c->sb.time_base_lo   = div_u64(le64_to_cpu(src->time_base_lo),
+       c->sb.time_base_lo   = div64_u64(le64_to_cpu(src->time_base_lo),
                                          c->sb.nsec_per_time_unit);
may be div_u64 is enough, c->sb.nsec_per_time_unit is unsigned type.

Thanks,
Hongbo
        c->sb.time_base_hi   = le32_to_cpu(src->time_base_hi);
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
index f393023a3ae2..561998b2b5dc 100644
--- a/fs/bcachefs/sysfs.c
+++ b/fs/bcachefs/sysfs.c
@@ -288,7 +288,7 @@ static int bch2_compression_stats_to_text(struct printbuf 
*out, struct bch_fs *c
                prt_tab_rjust(out);
prt_human_readable_u64(out, nr_extents
-                                      ? div_u64(sectors_uncompressed << 9, 
nr_extents)
+                                      ? div64_u64(sectors_uncompressed << 9, 
nr_extents)
                                       : 0);
                prt_tab_rjust(out);
                prt_newline(out);
diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c
index 1b8554460af4..144d8df48b1e 100644
--- a/fs/bcachefs/util.c
+++ b/fs/bcachefs/util.c
@@ -64,7 +64,7 @@ static int bch2_pow(u64 n, u64 p, u64 *res)
        *res = 1;
while (p--) {
-               if (*res > div_u64(U64_MAX, n))
+               if (*res > div64_u64(U64_MAX, n))
                        return -ERANGE;
                *res *= n;
        }
@@ -140,14 +140,14 @@ static int __bch2_strtou64_h(const char *cp, u64 *res)
parse_or_ret(cp, parse_unit_suffix(cp, &b)); - if (v > div_u64(U64_MAX, b))
+       if (v > div64_u64(U64_MAX, b))
                return -ERANGE;
        v *= b;
- if (f_n > div_u64(U64_MAX, b))
+       if (f_n > div64_u64(U64_MAX, b))
                return -ERANGE;
- f_n = div_u64(f_n * b, f_d);
+       f_n = div64_u64(f_n * b, f_d);
        if (v + f_n < v)
                return -ERANGE;
        v += f_n;
@@ -360,7 +360,7 @@ void bch2_pr_time_units(struct printbuf *out, u64 ns)
  {
        const struct time_unit *u = bch2_pick_time_units(ns);
- prt_printf(out, "%llu %s", div_u64(ns, u->nsecs), u->name);
+       prt_printf(out, "%llu %s", div64_u64(ns, u->nsecs), u->name);
  }
static void bch2_pr_time_units_aligned(struct printbuf *out, u64 ns)
@@ -477,7 +477,7 @@ void bch2_time_stats_to_text(struct printbuf *out, struct 
bch2_time_stats *stats
                        bool is_last = eytzinger0_next(i, NR_QUANTILES) == -1;
u64 q = max(quantiles->entries[i].m, last_q);
-                       prt_printf(out, "%llu ", div_u64(q, u->nsecs));
+                       prt_printf(out, "%llu ", div64_u64(q, u->nsecs));
                        if (is_last)
                                prt_newline(out);
                        last_q = q;

Reply via email to