Note: "permalinks" may not be as permanent as we would like,
direct links of old sources may well be a few messages off.
/ 2004-07-23 13:16:35 +0200
\ Lars Ellenberg:
> / 2004-07-23 09:04:15 +0200
> \ Martin Bene:
> > test-neu1 user # cat /proc/drbd
> > version: 0.7.0 svn $Rev: 1438 $ (api:74/proto:74)
> >
> > 0: cs:SyncTarget st:Secondary/Primary ld:Inconsistent
> > ns:0 nr:27311780 dw:27311780 dr:0 al:0 bm:3447 lo:134 pe:493 ua:134
> > ap:0
> > [==================>.] sync'ed: 93.7% (1818/28487)M
> > finish: 0:01:07 speed: 27,482 (25,008) K/sec
> > Another effect: The progress bar for resync diplayed on node1 seems to
> > be inconsistent
> >
> > test-neu2 drbd # cat /proc/drbd
> > version: 0.7.0 svn $Rev: 1438 $ (api:74/proto:74)
> >
> > 0: cs:SyncSource st:Primary/Secondary ld:Consistent
> > ns:8745864 nr:0 dw:87300 dr:9494623 al:109 bm:1412 lo:700 pe:1350
> > ua:700 ap:0
> > [=================>..] sync'ed: 88.9% (19952/28487)M
> > finish: 0:13:34 speed: 25,076 (25,187) K/sec
> >
> > test-neu2 drbd # cat /proc/drbd
> > version: 0.7.0 svn $Rev: 1438 $ (api:74/proto:74)
> >
> > 0: cs:SyncSource st:Primary/Secondary ld:Consistent
> > ns:12940824 nr:0 dw:87492 dr:13690591 al:109 bm:1668 lo:1000 pe:1876
> > ua:1000 ap:0
> > [========>...........] sync'ed: 44.4% (15858/28487)M
> > finish: 0:09:20 speed: 28,933 (25,160) K/sec
> >
> > Time to finish and synced/size info seem to be OK; but the progress bar
> > definitely isn't.. started out at ~50%, went to 100% and then jumped
> > back ~40.
>
> we patched the code there with some 64bit long compatibility things.
> seems like there sneaked in some integer overflow issue...
please try if this solves it:
Index: drbd_proc.c
===================================================================
--- drbd_proc.c (revision 1448)
+++ drbd_proc.c (working copy)
@@ -53,12 +53,25 @@
{
int sz = 0;
unsigned long res , db, dt, dbdt, rt, rs_left;
- sector_t n;
+ /* the whole sector_div thingy was wrong (did overflow,
+ * did not use correctly typed parameters), and is not even
+ * neccessary as long as rs_total and drbd_bm_total_weight
+ * are both unsigned long.
+ *
+ * this is to break it at compile time when we change that
+ * (we may feel 4TB maximum storage per drbd is not enough)
+ */
+ typecheck(unsigned long, mdev->rs_total);
+
+ /* note: both rs_total and rs_left are in bits, i.e. in
+ * units of BM_BLOCK_SIZE.
+ * for the percentage, we don't care. */
rs_left = drbd_bm_total_weight(mdev);
- n = rs_left*1000;
- sector_div(n,mdev->rs_total + 1);
- res = n;
+ D_ASSERT(rs_left < mdev->rs_total);
+ /* >> 10 to prevent overflow,
+ * +1 to prevent division by zero */
+ res = (rs_left >> 10)*1000/((mdev->rs_total >> 10) + 1);
{
int i, y = res/50, x = 20-y;
sz += sprintf(buf + sz, "\t[");
@@ -93,27 +106,28 @@
*/
dt = (jiffies - mdev->rs_mark_time) / HZ;
if (!dt) dt++;
- db = Bit2KB(mdev->rs_mark_left - rs_left);
- n = Bit2KB(rs_left);
- sector_div(n,(db/100+1));
- rt = ( dt * (unsigned long) n ) / 100; /* seconds */
+ db = mdev->rs_mark_left - rs_left;
+ rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
sz += sprintf(buf + sz, "finish: %lu:%02lu:%02lu",
rt / 3600, (rt % 3600) / 60, rt % 60);
-
/* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */
- if ((dbdt=db/dt) > 1000)
+ dbdt = Bit2KB(db/dt);
+ if (dbdt > 1000)
sz += sprintf(buf + sz, " speed: %ld,%03ld",
dbdt/1000,dbdt % 1000);
else
sz += sprintf(buf + sz, " speed: %ld", dbdt);
- /* mean speed since syncer started */
+ /* mean speed since syncer started
+ * FIXME introduce some additional "paused jiffies",
+ * so we can account for PausedSync periods */
dt = (jiffies - mdev->rs_start) / HZ;
if (!dt) dt++;
- db = Bit2KB(mdev->rs_total - rs_left);
- if ((dbdt=db/dt) > 1000)
+ db = mdev->rs_total - rs_left;
+ dbdt = Bit2KB(db/dt);
+ if (dbdt > 1000)
sz += sprintf(buf + sz, " (%ld,%03ld)",
dbdt/1000,dbdt % 1000);
else