diff --git a/cmdline/bw.c b/cmdline/bw.c index 46f3bb5a..bb64c12e 100644 --- a/cmdline/bw.c +++ b/cmdline/bw.c @@ -17,7 +17,9 @@ void bw_limit(struct snapraid_bw* bw, uint64_t bytes) if (!bw || bw->limit == 0) return; - uint64_t elapsed = os_tick_ms() - bw->start; + uint64_t start = bw->start; + uint64_t now = os_tick_ms(); + uint64_t elapsed = now - start; uint64_t done; uint64_t eta; @@ -25,6 +27,18 @@ void bw_limit(struct snapraid_bw* bw, uint64_t bytes) eta = done * 1000 / bw->limit; + /* + * To prevent accumulating unlimited credit during long pauses + * (such as CPU-bound hashing or metadata scanning), we cap the + * maximum accumulated credit to 10 seconds. + * If the elapsed time is more than 10 seconds ahead of the target ETA, + * we advance the start time to align the credit to exactly 10 seconds. + */ + if (elapsed > eta + 10000) { + bw->start = now - eta - 10000; + elapsed = eta + 10000; + } + if (eta > elapsed) { eta -= elapsed; if (eta > 1000)