kernel - Fix vmtotal sysctl
[dragonfly.git] / usr.bin / systat / vmstat.c
index c18457f..87e1e5a 100644 (file)
  * Cursed vmstat -- from Robert Elz.
  */
 
-#define _KERNEL_STRUCTURES
+#include <sys/user.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/time.h>
-#include <sys/user.h>
 #include <sys/uio.h>
 #include <sys/namei.h>
 #include <sys/sysctl.h>
@@ -77,12 +76,13 @@ static struct Info {
        struct  vmstats Vms;
        struct  nchstats nchstats;
        long    nchcount;
+       long    nchpathcount;
        long    *intrcnt;
        int     bufspace;
        int     desiredvnodes;
-       long    numvnodes;
-       long    freevnodes;
-       long    dirtybufspace;
+       int     numvnodes;
+       int     freevnodes;
+       int     dirtybufspace;
 } s, s1, s2, z;
 
 struct kinfo_cputime cp_time, old_cp_time;
@@ -102,9 +102,10 @@ static void allocinfo(struct Info *);
 static void copyinfo(struct Info *, struct Info *);
 static void dinfo(int, int, struct statinfo *, struct statinfo *);
 static void getinfo(struct Info *);
-static void putint(int, int, int, int, int);
+static void putlong(long, int, int, int, int);
 static void putfloat(double, int, int, int, int, int);
 static void putlongdouble(long double, int, int, int, int, int);
+static void putlongdoublez(long double, int, int, int, int, int);
 static int ucount(void);
 
 static int ncpu;
@@ -180,7 +181,7 @@ static struct nlist namelist[] = {
 #define GRAPHCOL        0
 #define NAMEIROW       14      /* uses 3 rows and 38 cols */
 #define NAMEICOL        0
-#define DISKROW                18      /* uses 5 rows and 50 cols (for 9 drives) */
+#define DISKROW                17      /* uses 6 rows and 50 cols (for 9 drives) */
 #define DISKCOL                 0
 
 #define        DRIVESPACE       7      /* max # for space */
@@ -224,22 +225,22 @@ initkre(void)
        if (nintr == 0) {
                if (sysctlbyname("hw.intrnames", NULL, &bytes, NULL, 0) == 0) {
                        intrnamebuf = malloc(bytes);
-                       sysctlbyname("hw.intrnames", intrnamebuf, &bytes, 
+                       sysctlbyname("hw.intrnames", intrnamebuf, &bytes,
                                        NULL, 0);
                        for (i = 0; i < bytes; ++i) {
-                           if (intrnamebuf[i] == 0)
-                               ++nintr;
+                               if (intrnamebuf[i] == 0)
+                                       ++nintr;
                        }
                        intrname = malloc(nintr * sizeof(char *));
                        intrloc = malloc(nintr * sizeof(*intrloc));
                        nintr = 0;
                        for (b = i = 0; i < bytes; ++i) {
-                           if (intrnamebuf[i] == 0) {
-                               intrname[nintr] = intrnamebuf + b;
-                               intrloc[nintr] = 0;
-                               b = i + 1;
-                               ++nintr;
-                           }
+                               if (intrnamebuf[i] == 0) {
+                                       intrname[nintr] = intrnamebuf + b;
+                                       intrloc[nintr] = 0;
+                                       b = i + 1;
+                                       ++nintr;
+                               }
                        }
                }
                nextintsrow = INTSROW + 2;
@@ -277,7 +278,7 @@ labelkre(void)
 
        clear();
        mvprintw(STATROW, STATCOL + 4, "users    Load");
-       mvprintw(MEMROW, MEMCOL, "Mem:KB    REAL            VIRTUAL");
+       mvprintw(MEMROW, MEMCOL, "Mem:MB    REAL            VIRTUAL");
        mvprintw(MEMROW + 1, MEMCOL, "        Tot   Share      Tot    Share");
        mvprintw(MEMROW + 2, MEMCOL, "Act");
        mvprintw(MEMROW + 3, MEMCOL, "All");
@@ -319,20 +320,19 @@ labelkre(void)
        mvprintw(GRAPHROW + 1, GRAPHCOL,
                "|    |    |    |    |    |    |    |    |    |    |");
 
-       mvprintw(NAMEIROW, NAMEICOL, "Namei         Name-cache    Dir-cache");
-       mvprintw(NAMEIROW + 1, NAMEICOL,
-               "    Calls     hits    %%     hits    %%");
+       mvprintw(NAMEIROW, NAMEICOL, "Path-lookups   hits   %%    Components");
        mvprintw(DISKROW, DISKCOL, "Disks");
        mvprintw(DISKROW + 1, DISKCOL, "KB/t");
-       mvprintw(DISKROW + 2, DISKCOL, "tps");
-       mvprintw(DISKROW + 3, DISKCOL, "MB/s");
-       mvprintw(DISKROW + 4, DISKCOL, "%% busy");
+       mvprintw(DISKROW + 2, DISKCOL, "tpr/s");
+       mvprintw(DISKROW + 3, DISKCOL, "MBr/s");
+       mvprintw(DISKROW + 4, DISKCOL, "tpw/s");
+       mvprintw(DISKROW + 5, DISKCOL, "MBw/s");
+       mvprintw(DISKROW + 6, DISKCOL, "%% busy");
        /*
         * For now, we don't support a fourth disk statistic.  So there's
         * no point in providing a label for it.  If someone can think of a
         * fourth useful disk statistic, there is room to add it.
         */
-       /* mvprintw(DISKROW + 4, DISKCOL, " msps"); */
        j = 0;
        for (i = 0; i < num_devices && j < MAXDRIVES; i++)
                if (dev_select[i].selected) {
@@ -349,7 +349,7 @@ labelkre(void)
                 * room for extended VM stats
                 */
                mvprintw(VMSTATROW + 11, VMSTATCOL - 6, "zfod");
-               mvprintw(VMSTATROW + 12, VMSTATCOL - 6, "ofod");
+               mvprintw(VMSTATROW + 12, VMSTATCOL - 6, "ozfod");
                mvprintw(VMSTATROW + 13, VMSTATCOL - 6, "%%slo-z");
                mvprintw(VMSTATROW + 14, VMSTATCOL - 6, "tfree");
                extended_vm_stats = 1;
@@ -383,7 +383,7 @@ labelkre(void)
        if(state == TIME) s1.nchstats.fld = t;}
 #define PUTRATE(fld, l, c, w) \
        Y(fld); \
-       putint((int)((float)s.fld/etime + 0.5), l, c, w, 'D')
+       putlong((long)((float)s.fld/etime + 0.5), l, c, w, 'D')
 #define MAXFAIL 5
 
 #define CPUSTATES 5
@@ -401,8 +401,10 @@ void
 showkre(void)
 {
        float f1, f2;
-       int psiz, inttotal;
-       int i, l, lc;
+       int psiz;
+       int i, lc;
+       long inttotal;
+       long l;
        static int failcnt = 0;
        double total_time;
 
@@ -447,17 +449,20 @@ showkre(void)
                                intrname[i]);
                }
                X(intrcnt);
-               l = (int)((float)s.intrcnt[i]/etime + 0.5);
+               l = (long)((float)s.intrcnt[i]/etime + 0.5);
                inttotal += l;
-               putint(l, intrloc[i], INTSCOL + 2, 6, 'D');
+               putlong(l, intrloc[i], INTSCOL + 2, 6, 'D');
        }
-       putint(inttotal, INTSROW + 1, INTSCOL + 2, 6, 'D');
+       putlong(inttotal, INTSROW + 1, INTSCOL + 2, 6, 'D');
        Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss);
-       Z(ncs_long); Z(ncs_pass2); Z(ncs_2passes); Z(ncs_neghits);
+       Z(ncs_longhits); Z(ncs_longmiss); Z(ncs_neghits);
        s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits +
-           nchtotal.ncs_miss + nchtotal.ncs_long + nchtotal.ncs_neghits;
-       if (state == TIME)
+           nchtotal.ncs_miss + nchtotal.ncs_neghits;
+       s.nchpathcount = nchtotal.ncs_longhits + nchtotal.ncs_longmiss;
+       if (state == TIME) {
                s1.nchcount = s.nchcount;
+               s1.nchpathcount = s.nchpathcount;
+       }
 
        psiz = 0;
        f2 = 0.0;
@@ -476,35 +481,36 @@ showkre(void)
                        addch(cpuchar[lc]);
        }
 
-       putint(ucount(), STATROW, STATCOL, 3, 'D');
-       putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0);
-       putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0);
-       putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0);
+       putlong(ucount(), STATROW, STATCOL, 3, 'D');
+       putfloat(avenrun[0], STATROW, STATCOL + 18, 6, 2, 0);
+       putfloat(avenrun[1], STATROW, STATCOL + 25, 6, 2, 0);
+       putfloat(avenrun[2], STATROW, STATCOL + 32, 6, 2, 0);
        mvaddstr(STATROW, STATCOL + 53, buf);
-#define pgtokb(pg)     ((pg) * vms.v_page_size / 1024)
-       putint(pgtokb(total.t_arm), MEMROW + 2, MEMCOL + 3, 8, 'K');
-       putint(pgtokb(total.t_armshr), MEMROW + 2, MEMCOL + 11, 8, 'K');
-       putint(pgtokb(total.t_avm), MEMROW + 2, MEMCOL + 19, 9, 'K');
-       putint(pgtokb(total.t_avmshr), MEMROW + 2, MEMCOL + 28, 9, 'K');
-       putint(pgtokb(total.t_rm), MEMROW + 3, MEMCOL + 3, 8, 'K');
-       putint(pgtokb(total.t_rmshr), MEMROW + 3, MEMCOL + 11, 8, 'K');
-       putint(pgtokb(total.t_vm), MEMROW + 3, MEMCOL + 19, 9, 'K');
-       putint(pgtokb(total.t_vmshr), MEMROW + 3, MEMCOL + 28, 9, 'K');
-       putint(pgtokb(total.t_free), MEMROW + 2, MEMCOL + 37, 8, 'K');
-       putint(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 0, 3, 'D');
-       putint(total.t_pw, PROCSROW + 1, PROCSCOL + 3, 3, 'D');
-       putint(total.t_dw, PROCSROW + 1, PROCSCOL + 6, 3, 'D');
-       putint(total.t_sl, PROCSROW + 1, PROCSCOL + 9, 3, 'D');
-       putint(total.t_sw, PROCSROW + 1, PROCSCOL + 12, 3, 'D');
+#define pgtokb(pg)     (long)((intmax_t)(pg) * vms.v_page_size / 1024)
+#define pgtomb(pg)     (long)((intmax_t)(pg) * vms.v_page_size / (1024 * 1024))
+       putlong(pgtomb(total.t_arm), MEMROW + 2, MEMCOL + 3, 8, 'M');
+       putlong(pgtomb(total.t_armshr), MEMROW + 2, MEMCOL + 11, 8, 'M');
+       putlong(pgtomb(total.t_avm), MEMROW + 2, MEMCOL + 19, 9, 'M');
+       putlong(pgtomb(total.t_avmshr), MEMROW + 2, MEMCOL + 28, 9, 'M');
+       putlong(pgtomb(total.t_rm), MEMROW + 3, MEMCOL + 3, 8, 'M');
+       putlong(pgtomb(total.t_rmshr), MEMROW + 3, MEMCOL + 11, 8, 'M');
+       putlong(pgtomb(total.t_vm), MEMROW + 3, MEMCOL + 19, 9, 'M');
+       putlong(pgtomb(total.t_vmshr), MEMROW + 3, MEMCOL + 28, 9, 'M');
+       putlong(pgtomb(total.t_free), MEMROW + 2, MEMCOL + 37, 8, 'M');
+       putlong(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 0, 3, 'D');
+       putlong(total.t_pw, PROCSROW + 1, PROCSCOL + 3, 3, 'D');
+       putlong(total.t_dw, PROCSROW + 1, PROCSCOL + 6, 3, 'D');
+       putlong(total.t_sl, PROCSROW + 1, PROCSCOL + 9, 3, 'D');
+       putlong(total.t_sw, PROCSROW + 1, PROCSCOL + 12, 3, 'D');
        if (extended_vm_stats == 0) {
                PUTRATE(Vmm.v_zfod, VMSTATROW + 0, VMSTATCOL + 4, 5);
        }
        PUTRATE(Vmm.v_cow_faults, VMSTATROW + 1, VMSTATCOL + 3, 6);
-       putint(pgtokb(vms.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_active_count), VMSTATROW + 3, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9, 'K');
-       putint(pgtokb(vms.v_free_count), VMSTATROW + 6, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_active_count), VMSTATROW + 3, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9, 'K');
+       putlong(pgtokb(vms.v_free_count), VMSTATROW + 6, VMSTATCOL, 9, 'K');
        PUTRATE(Vmm.v_dfree, VMSTATROW + 7, VMSTATCOL, 9);
        PUTRATE(Vmm.v_pfree, VMSTATROW + 8, VMSTATCOL, 9);
        PUTRATE(Vmm.v_reactivated, VMSTATROW + 9, VMSTATCOL, 9);
@@ -513,26 +519,20 @@ showkre(void)
        PUTRATE(Vmm.v_intrans, VMSTATROW + 12, VMSTATCOL, 9);
 
        if (extended_vm_stats) {
-           PUTRATE(Vmm.v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9);
-           PUTRATE(Vmm.v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9);
-           putint(
-               ((s.Vmm.v_ozfod < s.Vmm.v_zfod) ?
-                   s.Vmm.v_ozfod * 100 / s.Vmm.v_zfod : 
-                   0
-               ),
-               VMSTATROW + 13, 
-               VMSTATCOL - 16,
-               9,
-               'D'
-           );
-           PUTRATE(Vmm.v_tfree, VMSTATROW + 14, VMSTATCOL - 16, 9);
+               PUTRATE(Vmm.v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9);
+               PUTRATE(Vmm.v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9);
+#define nz(x)  ((x) ? (x) : 1)
+               putlong((s.Vmm.v_zfod - s.Vmm.v_ozfod) * 100 / nz(s.Vmm.v_zfod),
+                   VMSTATROW + 13, VMSTATCOL - 16, 9, 'D');
+#undef nz
+               PUTRATE(Vmm.v_tfree, VMSTATROW + 14, VMSTATCOL - 16, 9);
        }
 
-       putint(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9, 'K');
-       putint(s.dirtybufspace/1024, VMSTATROW + 14, VMSTATCOL, 9, 'K');
-       putint(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9, 'D');
-       putint(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9, 'D');
-       putint(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9, 'D');
+       putlong(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9, 'K');
+       putlong(s.dirtybufspace/1024, VMSTATROW + 14, VMSTATCOL, 9, 'K');
+       putlong(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9, 'D');
+       putlong(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9, 'D');
+       putlong(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9, 'D');
        PUTRATE(Vmm.v_vnodein, PAGEROW + 2, PAGECOL + 5, 5);
        PUTRATE(Vmm.v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5);
        PUTRATE(Vmm.v_swapin, PAGEROW + 2, PAGECOL + 17, 5);
@@ -567,16 +567,15 @@ showkre(void)
                                break;
                        }
                }
-       putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9, 'D');
-       putint((nchtotal.ncs_goodhits + nchtotal.ncs_neghits),
-          NAMEIROW + 2, NAMEICOL + 9, 9, 'D');
 #define nz(x)  ((x) ? (x) : 1)
-       putfloat((nchtotal.ncs_goodhits+nchtotal.ncs_neghits) *
-          100.0 / nz(s.nchcount),
-          NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1);
-       putint(nchtotal.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9, 'D');
-       putfloat(nchtotal.ncs_pass2 * 100.0 / nz(s.nchcount),
-          NAMEIROW + 2, NAMEICOL + 33, 4, 0, 1);
+       putlong(s.nchpathcount, NAMEIROW + 1, NAMEICOL + 3, 9, 'D');
+
+       putlong(nchtotal.ncs_longhits, NAMEIROW + 1, NAMEICOL + 12, 7, 'D');
+       putfloat(nchtotal.ncs_longhits * 100.0 / nz(s.nchpathcount),
+           NAMEIROW + 1, NAMEICOL + 19, 4, 0, 0);
+
+       putfloat((double)s.nchcount / nz(s.nchpathcount),
+           NAMEIROW + 1, NAMEICOL + 27, 5, 2, 1);
 #undef nz
 }
 
@@ -660,7 +659,7 @@ ucount(void)
 }
 
 static void
-putint(int n, int l, int lc, int w, int type)
+putlong(long n, int l, int lc, int w, int type)
 {
        char b[128];
        int xtype;
@@ -671,7 +670,7 @@ putint(int n, int l, int lc, int w, int type)
                        addch(' ');
                return;
        }
-       snprintf(b, sizeof(b), "%*d", w, n);
+       snprintf(b, sizeof(b), "%*ld", w, n);
        if (strlen(b) > (size_t)w) {
                if (type == 'D') {
                        n /= 1000;
@@ -680,7 +679,7 @@ putint(int n, int l, int lc, int w, int type)
                        n /= 1024;
                        xtype = 'M';
                }
-               snprintf(b, sizeof(b), "%*d%c", w - 1, n, xtype);
+               snprintf(b, sizeof(b), "%*ld%c", w - 1, n, xtype);
                if (strlen(b) > (size_t)w) {
                        if (type == 'D') {
                                n /= 1000;
@@ -689,7 +688,7 @@ putint(int n, int l, int lc, int w, int type)
                                n /= 1024;
                                xtype = 'G';
                        }
-                       snprintf(b, sizeof(b), "%*d%c", w - 1, n, xtype);
+                       snprintf(b, sizeof(b), "%*ld%c", w - 1, n, xtype);
                        if (strlen(b) > (size_t)w) {
                                while (w-- > 0)
                                        addch('*');
@@ -744,6 +743,20 @@ putlongdouble(long double f, int l, int lc, int w, int d, int nz)
        addstr(b);
 }
 
+static void
+putlongdoublez(long double f, int l, int lc, int w, int d, int nz)
+{
+       char b[128];
+
+       if (f == 0.0) {
+               move(l, lc);
+               sprintf(b, "%*.*s", w, w, "");
+               addstr(b);
+       } else {
+               putlongdouble(f, l, lc, w, d, nz);
+       }
+}
+
 static void
 getinfo(struct Info *ls)
 {
@@ -769,8 +782,8 @@ getinfo(struct Info *ls)
                err(1, "kinfo_get_sched_cputime");
        NREAD(X_BUFFERSPACE, &ls->bufspace, sizeof(ls->bufspace));
        NREAD(X_DESIREDVNODES, &ls->desiredvnodes, sizeof(ls->desiredvnodes));
-       NREAD(X_NUMVNODES, &ls->numvnodes, LONG);
-       NREAD(X_FREEVNODES, &ls->freevnodes, LONG);
+       NREAD(X_NUMVNODES, &ls->numvnodes, sizeof(ls->numvnodes));
+       NREAD(X_FREEVNODES, &ls->freevnodes, sizeof(ls->freevnodes));
        NREAD(X_NUMDIRTYBUFFERS, &ls->dirtybufspace, sizeof(ls->dirtybufspace));
 
        if (nintr) {
@@ -782,7 +795,7 @@ getinfo(struct Info *ls)
                error("Can't get kernel info: %s\n", strerror(errno));
                bzero(&ls->Total, sizeof(ls->Total));
        }
-       
+
        if ((nch_tmp = malloc(nch_size)) == NULL) {
                perror("malloc");
                exit(1);
@@ -850,8 +863,11 @@ copyinfo(struct Info *from, struct Info *to)
 static void
 dinfo(int dn, int lc, struct statinfo *now, struct statinfo *then)
 {
-       long double transfers_per_second;
-       long double kb_per_transfer, mb_per_second;
+       long double kb_per_transfer;
+       long double transfers_per_secondr;
+       long double transfers_per_secondw;
+       long double mb_per_secondr;
+       long double mb_per_secondw;
        long double elapsed_time, device_busy;
        int di;
 
@@ -865,26 +881,58 @@ dinfo(int dn, int lc, struct statinfo *now, struct statinfo *then)
                                     then->dinfo->devices[di].busy_time :
                                     now->dinfo->devices[di].dev_creation_time);
 
-       if (compute_stats(&now->dinfo->devices[di], then ?
-                         &then->dinfo->devices[di] : NULL, elapsed_time,
+       if (compute_stats(
+                         &now->dinfo->devices[di],
+                         (then ? &then->dinfo->devices[di] : NULL),
+                         elapsed_time,
+                         NULL, NULL, NULL,
+                         &kb_per_transfer,
+                         NULL,
+                         NULL,
+                         NULL, NULL) != 0)
+               errx(1, "%s", devstat_errbuf);
+
+       if (compute_stats_read(
+                         &now->dinfo->devices[di],
+                         (then ? &then->dinfo->devices[di] : NULL),
+                         elapsed_time,
+                         NULL, NULL, NULL,
+                         NULL,
+                         &transfers_per_secondr,
+                         &mb_per_secondr,
+                         NULL, NULL) != 0)
+               errx(1, "%s", devstat_errbuf);
+
+       if (compute_stats_write(
+                         &now->dinfo->devices[di],
+                         (then ? &then->dinfo->devices[di] : NULL),
+                         elapsed_time,
                          NULL, NULL, NULL,
-                         &kb_per_transfer, &transfers_per_second,
-                         &mb_per_second, NULL, NULL) != 0)
+                         NULL,
+                         &transfers_per_secondw,
+                         &mb_per_secondw,
+                         NULL, NULL) != 0)
                errx(1, "%s", devstat_errbuf);
 
-       if ((device_busy == 0) && (transfers_per_second > 5))
+       if ((device_busy == 0) &&
+           (transfers_per_secondr > 5 || transfers_per_secondw > 5)) {
                /* the device has been 100% busy, fake it because
                 * as long as the device is 100% busy the busy_time
                 * field in the devstat struct is not updated */
                device_busy = elapsed_time;
-       if (device_busy > elapsed_time)
+       }
+       if (device_busy > elapsed_time) {
                /* this normally happens after one or more periods
                 * where the device has been 100% busy, correct it */
                device_busy = elapsed_time;
+       }
 
        lc = DISKCOL + lc * 6;
-       putlongdouble(kb_per_transfer, DISKROW + 1, lc, 5, 2, 0);
-       putlongdouble(transfers_per_second, DISKROW + 2, lc, 5, 0, 0);
-       putlongdouble(mb_per_second, DISKROW + 3, lc, 5, 2, 0);
-       putlongdouble(device_busy * 100 / elapsed_time, DISKROW + 4, lc, 5, 0, 0);
+       putlongdoublez(kb_per_transfer, DISKROW + 1, lc, 5, 2, 0);
+       putlongdoublez(transfers_per_secondr, DISKROW + 2, lc, 5, 0, 0);
+       putlongdoublez(mb_per_secondr, DISKROW + 3, lc, 5, 2, 0);
+       putlongdoublez(transfers_per_secondw, DISKROW + 4, lc, 5, 0, 0);
+       putlongdoublez(mb_per_secondw, DISKROW + 5, lc, 5, 2, 0);
+       putlongdouble(device_busy * 100 / elapsed_time,
+                                     DISKROW + 6, lc, 5, 0, 0);
 }