NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/42350: frag size in "df -G" output has never been the right value, etc.



>Number:         42350
>Category:       bin
>Synopsis:       frag size in "df -G" output has never been the right value, 
>etc.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 20 05:45:00 +0000 2009
>Originator:     Greg A. Woods
>Release:        -current (2009/11/19)
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Environment:
System: NetBSD current
>Description:

        running "df -G" to find out file system block and frag sizes
        revealed it wasn't reporting the correct numbers

        that leads me to another round of fixes to df(1)....

>How-To-Repeat:

        notice that "df -G" wasn't reporting correct frag size (due the
        fact my initial changes in PR# 36541 were against a revision
        prior to the conversion to statvfs(2), i.e. they work with
        statfs(), but not statvfs(), and when I suggested more changes
        against 1.77 in a later reply I did not catch this bug)

        notice that column headers were wrongly spaced

        notice a comment about nflag vs. old statfs() that can be fixed
        now with statvfs1()

        read the code again and notice serveral other problems, notably
        that most struct statvfs fields are unsigned, and thus the
        available blocks field can never go negative now either

>Fix:

Index: bin/df/df.c
===================================================================
RCS file: /cvs/master/m-NetBSD/main/src/bin/df/df.c,v
retrieving revision 1.86
diff -u -r1.86 df.c
--- bin/df/df.c 6 Jun 2009 09:30:45 -0000       1.86
+++ bin/df/df.c 20 Nov 2009 03:53:27 -0000
@@ -74,8 +74,8 @@
 void    maketypelist(char *);
 long    regetmntinfo(struct statvfs **, long);
 void    usage(void);
-void    prthumanval(int64_t, const char *);
-void    prthuman(struct statvfs *, int64_t, int64_t);
+void    prthumanval(uint64_t, const char *);
+void    prthuman(struct statvfs *, uint64_t, uint64_t);
 const char *
        strpct64(uint64_t, uint64_t, u_int);
 
@@ -181,11 +181,7 @@
                                        mntpt = *argv;
                        } else
                                mntpt = *argv;
-                       /*
-                        * Statfs does not take a `wait' flag, so we cannot
-                        * implement nflag here.
-                        */
-                       if (!statvfs(mntpt, &mntbuf[mntsize]))
+                       if (!statvfs1(mntpt, &mntbuf[mntsize], nflag ? 
ST_NOWAIT : 0))
                                if (lflag &&
                                    (mntbuf[mntsize].f_flag & MNT_LOCAL) == 0)
                                        warnx("Warning: %s is not a local %s",
@@ -327,11 +323,16 @@
 }
 
 void
-prthumanval(int64_t bytes, const char *pad)
+prthumanval(uint64_t bytes, const char *pad) /* XXX passing pad as strings full
+                                             * of spaces is unbelievably
+                                             * bogus, but I'm not going to fix
+                                             * it because the whole idea of
+                                             * using/needing variable space
+                                             * padding here is stupid */
 {
        char buf[6];
 
-       (void)humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1),
+       (void)humanize_number(buf, sizeof(buf) - 1,
            bytes, "", HN_AUTOSCALE,
            HN_B | HN_NOSPACE | HN_DECIMAL);
 
@@ -339,22 +340,22 @@
 }
 
 void
-prthuman(struct statvfs *sfsp, int64_t used, int64_t bavail)
+prthuman(struct statvfs *sfsp, uint64_t used, uint64_t bavail)
 {
 
-       prthumanval((int64_t)(sfsp->f_blocks * sfsp->f_frsize), "  ");
-       prthumanval((int64_t)(used * sfsp->f_frsize), "    ");
-       prthumanval((int64_t)(bavail * sfsp->f_frsize), "    ");
+       prthumanval((uint64_t)(sfsp->f_blocks * sfsp->f_frsize), "   ");
+       prthumanval((uint64_t)(used * sfsp->f_frsize), "    ");
+       prthumanval((uint64_t)(bavail * sfsp->f_frsize), "    ");
 }
 
 /*
  * Convert statvfs returned filesystem size into BLOCKSIZE units.
  * Attempts to avoid overflow for large filesystems.
  */
-#define fsbtoblk(num, fsbs, bs)                                        \
-       (((fsbs) != 0 && (uint64_t)(fsbs) < (uint64_t)(bs)) ?   \
-           (int64_t)(num) / (int64_t)((bs) / (fsbs)) :         \
-           (int64_t)(num) * (int64_t)((fsbs) / (bs)))
+#define fsbtoblk(num, fsbs, bs)                                                
\
+       (((fsbs) != 0 && (fsbs) < (bs)) ?                               \
+        (uint64_t)(num) / (uint64_t)((bs) / (uint64_t)(fsbs)) :        \
+        (uint64_t)(num) * (uint64_t)((fsbs) / (uint64_t)(bs)))
 
 /*
  * Print out status about a filesystem.
@@ -367,16 +368,17 @@
        static const char *header;
        static const char full[] = "100%";
        static const char empty[] = "  0%";
-       int64_t used, availblks, inodes;
-       int64_t bavail;
+       uint64_t used, availblks, inodes; /* xxx fsblkcnt_t & fsfilcnt_t ??? */
+       uint64_t bavail;
 
        if (gflag) {
                /*
-                * From SunOS-5.6:
+                * From SunOS-5.6 (Note the actual output does include spaces
+                * at the ends of the lines! Don't remove them here!):
                 *
-                * /var               (/dev/dsk/c0t0d0s3 ):         8192 block 
size          1024 frag size
+                * /var               (/dev/dsk/c0t0d0s3 ):         8192 block 
size          1024 frag size  
                 *   984242 total blocks     860692 free blocks   859708 
available         249984 total files
-                *   248691 free files      8388611 filesys id
+                *   248691 free files      8388611 filesys id  
                 *      ufs fstype       0x00000004 flag             255 
filename length
                 *
                 */
@@ -388,25 +390,25 @@
                                         * is of course the file
                                         * system's block size too.
                                         */
-                   sfsp->f_bsize);     /* not so surprisingly the
+                   sfsp->f_frsize);    /* not so surprisingly the
                                         * "fundamental file system
                                         * block size" is the frag
                                         * size.
                                         */
-               (void)printf("%10" PRId64 " total blocks %10" PRId64
-                   " free blocks  %10" PRId64 " available\n",
+               (void)printf("%10" PRIu64 " total blocks %10" PRIu64
+                   " free blocks  %10" PRIu64 " available\n",
                    (uint64_t)sfsp->f_blocks, (uint64_t)sfsp->f_bfree,
                    (uint64_t)sfsp->f_bavail);
-               (void)printf("%10" PRId64 " total files  %10" PRId64
+               (void)printf("%10" PRIu64 " total files  %10" PRIu64
                    " free files %12lx filesys id\n",
                    (uint64_t)sfsp->f_ffree, (uint64_t)sfsp->f_files,
                    sfsp->f_fsid);
                (void)printf("%10s fstype  %#15lx flag  %17ld filename "
                    "length\n", sfsp->f_fstypename, sfsp->f_flag,
                    sfsp->f_namemax);
-               (void)printf("%10lu owner %17" PRId64 " syncwrites %12" PRId64
+               (void)printf("%10lu owner %17" PRIu64 " syncwrites %12" PRIu64
                    " asyncwrites\n\n", (unsigned long)sfsp->f_owner,
-                   sfsp->f_syncwrites, sfsp->f_asyncwrites);
+                   (uint64_t)sfsp->f_syncwrites, 
(uint64_t)sfsp->f_asyncwrites);
 
                /*
                 * a concession by the structured programming police to the
@@ -452,11 +454,11 @@
                            "Mounted on\n", header);
                } else {
                        (void)printf("%-*.*s %s       Used      Avail %%Cap",
-                           maxwidth - (headerlen - 9),
-                           maxwidth - (headerlen - 9),
+                           maxwidth - (headerlen - 10),
+                           maxwidth - (headerlen - 10),
                            "Filesystem", header);
                        if (iflag)
-                               (void)printf("    iUsed   iAvail %%iCap");
+                               (void)printf("    iUsed  iAvail %%iCap");
                        (void)printf(" Mounted on\n");
                }
        }
@@ -471,7 +473,7 @@
                 * <space used>, <space free>, <percentage used>,
                 * <file system root>
                 */
-               (void)printf("%s %" PRId64 " %" PRId64 " %" PRId64 " %s %s\n",
+               (void)printf("%s %" PRIu64 " %" PRIu64 " %" PRIu64 " %s %s\n",
                    sfsp->f_mntfromname,
                    fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize),
                    fsbtoblk(used, sfsp->f_frsize, blocksize),
@@ -492,7 +494,7 @@
        if (hflag)
                prthuman(sfsp, used, bavail);
        else
-               (void)printf("%10" PRId64 " %10" PRId64 " %10" PRId64,
+               (void)printf("%10" PRIu64 " %10" PRIu64 " %10" PRIu64,
                    fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize),
                    fsbtoblk(used, sfsp->f_frsize, blocksize),
                    fsbtoblk(bavail, sfsp->f_frsize, blocksize));
@@ -503,8 +505,8 @@
        if (iflag) {
                inodes = sfsp->f_files;
                used = inodes - sfsp->f_ffree;
-               (void)printf(" %8jd %8jd %4s",
-                   (intmax_t)used, (intmax_t)sfsp->f_ffree,
+               (void)printf(" %8" PRIu64 " %8" PRIu64 " %4s",
+                   (uint64_t)used, (uint64_t)sfsp->f_ffree,
                    inodes == 0 ? (used == 0 ? empty : full) :
                    strpct64((uint64_t)used, (uint64_t)inodes, 0));
        }



Home | Main Index | Thread Index | Old Index