Subject: Problem with df(1)
To: 'port-i386@netbsd.org' <port-i386@NetBSD.ORG>
From: Gunnar Helliesen <gunnar@bitcon.no>
List: port-i386
Date: 11/04/1997 18:14:15
Some of you might remember that I reported a problem with df(1) a while
back. The problem is that the free space calculations are wrong on large
disks:
atlas:~# df /dev/sd2c
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/sd2c 21952751 20433937 -41430858 -97% /usr/local/ftp/.4
Perry E. Metzger suggested:
> Its obviously a type screw -- off_t's are probably not being used...
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)