Subject: Re: Problem with df(1)
To: Gunnar Helliesen <gunnar@bitcon.no>
From: Perry E. Metzger <perry@piermont.com>
List: port-i386
Date: 11/04/1997 22:59:16
Gunnar Helliesen writes:
> Perry E. Metzger suggested:
> 
> > Its obviously a type screw -- off_t's are probably not being used...

And looking at the code in question, it appears that I'm
right. off_t's are 64 bit entities on most of our machines these
days. You need to switch everything used in the calculation to
quadwords, instead of longs. Otherwise you'll overflow.

.pm

> 
> Being of the optimistic kind I set out to fix it myself. I found that df
> uses the struct statfs(2) to get filesystem info, but that's how far I
> got. Changing the definitions to unsigned in df.c and <sys/mount.h> and
> building a new kernel and df didn't help much, so now I'm stuck.
> 
> As far as I can tell, this is where df.c calculates and prints the
> filesystem info:
> 
> void    
> prtstat(sfsp, maxwidth)
>         struct statfs *sfsp; 
>         int maxwidth;
> { 
>         static long blocksize;
>         static int headerlen, timesthrough;
>         static char *header;
>         long used, availblks, inodes; 
>  
>         if (maxwidth < 11) 
>                 maxwidth = 11;
>         if (++timesthrough == 1) {
>                 if (kflag) {
>                         blocksize = 1024;
>                         header = "1K-blocks";
>                         headerlen = strlen(header);
>                 } else
>                         header = getbsize(&headerlen, &blocksize);
>                 (void)printf("%-*.*s %s     Used    Avail Capacity",
>                     maxwidth, maxwidth, "Filesystem", header);
>                 if (iflag)
>                         (void)printf(" iused   ifree  %%iused"); 
>                 (void)printf("  Mounted on\n");
>         }
>         (void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
>         used = sfsp->f_blocks - sfsp->f_bfree;
>         availblks = sfsp->f_bavail + used;
>         (void)printf(" %*ld %8ld %8ld", headerlen,
>             fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
>             fsbtoblk(used, sfsp->f_bsize, blocksize),
>             fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
>         (void)printf(" %5.0f%%",
>             availblks == 0 ? 100.0 : (double)used / (double)availblks *
> 100.0);
>         if (iflag) {
>                 inodes = sfsp->f_files;
>                 used = inodes - sfsp->f_ffree;
>                 (void)printf(" %7ld %7ld %5.0f%% ", used, sfsp->f_ffree,
>                    inodes == 0 ? 100.0 : (double)used / (double)inodes *
> 100.0);
>         } else
>                 (void)printf("  ");
>         (void)printf("  %s\n", sfsp->f_mntonname);
> }
> 
> 
> My question is: Where are the elements of statfs calculated in the first
> place? How many places are the numbers passed as signed? Am I even on
> the right track? ;-)
> 
> Help anyone?
> 
> Gunnar
> 
> --
> Gunnar Helliesen   | Bergen IT Consult AS  | NetBSD/VAX on a uVAX II
> Systems Consultant | Bergen, Norway        | '86 Jaguar Sovereign 4.2
> gunnar@bitcon.no   | http://www.bitcon.no/ | '73 Mercedes 280 (240D)
> 
>