nfsstat: fix a bug in diff_stats()
[nfs-utils.git] / utils / nfsstat / nfsstat.c
index eb6e45d..1c44050 100644 (file)
@@ -671,16 +671,37 @@ copy_stats(struct statinfo *dest, struct statinfo *src)
 static void
 diff_stats(struct statinfo *new, struct statinfo *old)
 {
-       int i, j, is_srv, should_diff;
-
+       int i, j, is_srv, nodiff_first_index, should_diff;
+
+       /*
+        * Different stat types have different formats in the /proc
+        * files: for the proc2/3/4-type stats, the first entry has
+        * the total number of subsequent entries; one does not want
+        * to diff that first entry.  The other stat types aren't like
+        * this.  So, we diff a given entry if it's not of one of the
+        * procX types ("i" < 2 for clt, < 4 for srv), or if it's not
+        * the first entry ("j" > 0).
+        */
        is_srv = (new == srvinfo);
+       nodiff_first_index = 2 + (2 * is_srv);
+
        for (i = 0; old[i].tag; i++) {
                for (j = 0; j < new[i].nrvals; j++) {
-                       /* skip items in valptr that shouldn't be changed */
-                       should_diff = (i < (3 + is_srv) || j > 0);
+                       should_diff = (i < nodiff_first_index || j > 0);
                        if (should_diff)
                                new[i].valptr[j] -= old[i].valptr[j];
                }
+
+               /*
+                * Make sure that the "totals" entry (last value in
+                * each stat array) for the procX-type stats has the
+                * "numentries" entry's (first value in procX-type
+                * stat arrays) constant value added-back after the
+                * diff -- i.e., it should always be included in the
+                * total.
+                */
+               if (!strncmp("proc", new[i].tag, 4))
+                       new[i].valptr[new[i].nrvals - 1] += new[i].valptr[0];
        }
 }