Mail Archives: djgpp-workers/2002/12/30/08:05:37
Hello.
I've just taken a look at why df (from fileutils 4.1) reports
the wrong sizes. This problem is with df built against DJGPP CVS.
The problem arises because we return inconsistent information
in 'struct statvfs' from statvfs() and fstatvfs(). The f_blocks member
is supposed to contain the number of free blocks of size f_frsize.
f_frsize is the fundamental block size in bytes. In our implementation
f_blocks contains the number of free clusters. f_frsize is a fixed value -
512 bytes - which represents most common sector sizes.
Sources: New POSIX standard, draft 7; Single Unix Specification, version 2
The amount of free disk space is f_frsize * f_blocks. There's a large
discrepancy between this and the actual free space on my FAT32 disk,
which has 16K clusters.
There are a few solutions that I can see:
(a) Set f_frsize to the same size as the cluster size. We pretend
that the fundamental block size is the cluster size.
This is the simplest solution. There's a patch below.
(b) Modify the code to find the real sector size. Then scale
the free block size numbers by (cluster size / sector size),
to give the correct figures for free sectors.
This method could be troublesome, unless we assume that
cluster sizes are always equal to the sector size multiplied
by a power of 2.
*statvfs() use statfs() to get their information. Looking at
the statfs code, it doesn't look like all the methods for finding
disk space (CD-ROM, Windows '9x, Windows '9x other method) return
the sector size. If not all the methods return the sector size,
then this method can't really be used (we can only really support
the "common lowest denominator").
(c) Assume a 512 byte sector size and then scale the free block size
numbers as in (b).
The only problem I can see with (a) is that we lie about the sector size.
Well, we were doing that before anyway. IMNSHO any programs that need
to know the sector size are probably low-level enough that they will
need rewriting to work with DJGPP.
OK to commit?
Bye, Rich =]
Index: src/libc/posix/sys/statvfs/statvfs.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/statvfs/statvfs.c,v
retrieving revision 1.2
diff -p -c -3 -r1.2 statvfs.c
*** src/libc/posix/sys/statvfs/statvfs.c 17 Oct 2002 23:00:25 -0000 1.2
--- src/libc/posix/sys/statvfs/statvfs.c 30 Dec 2002 12:42:56 -0000
*************** statvfs (const char *path, struct statvf
*** 34,43 ****
outbuf->f_ffree = sbuf.f_bfree;
outbuf->f_favail = sbuf.f_bavail;
! /* We pretend that the fundamental block size `f_frsize' for all devices
! * is 512 bytes. This seems reasonable since many (if not most) devices
! * have 512 byte sectors. */
! outbuf->f_frsize = 512;
/* Set the flags. */
outbuf->f_flag = ST_NOSUID;
--- 34,47 ----
outbuf->f_ffree = sbuf.f_bfree;
outbuf->f_favail = sbuf.f_bavail;
! /* We pretend that the fundamental block size `f_frsize' is the same
! * as the file system's block size ("clusters" for FAT file systems).
! *
! * We could reasonably report 512 bytes here, since many (if not most)
! * devices have 512 byte sectors. But then we would need to convert
! * from file system blocks to fundamental blocks,
! * which would be troublesome. */
! outbuf->f_frsize = outbuf->f_bsize;
/* Set the flags. */
outbuf->f_flag = ST_NOSUID;
Index: src/libc/posix/sys/statvfs/statvfs.txh
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/statvfs/statvfs.txh,v
retrieving revision 1.2
diff -p -c -3 -r1.2 statvfs.txh
*** src/libc/posix/sys/statvfs/statvfs.txh 14 Dec 2002 16:41:57 -0000 1.2
--- src/libc/posix/sys/statvfs/statvfs.txh 30 Dec 2002 12:42:57 -0000
*************** the structure below:
*** 18,27 ****
struct statvfs @{
unsigned long f_bsize; /* FS block size */
unsigned long f_frsize; /* fundamental block size */
! fsblkcnt_t f_blocks; /* # of blocks on filesystem */
! fsblkcnt_t f_bfree; /* # of free blocks on FS */
! fsblkcnt_t f_bavail; /* # of free blocks on FS for
! * unprivileged users */
fsfilcnt_t f_files; /* # of file serial numbers */
fsfilcnt_t f_ffree; /* # of free file serial numbers */
fsfilcnt_t f_favail; /* # of free file serial numbers
--- 18,27 ----
struct statvfs @{
unsigned long f_bsize; /* FS block size */
unsigned long f_frsize; /* fundamental block size */
! fsblkcnt_t f_blocks; /* # of blocks on FS of size f_frsize */
! fsblkcnt_t f_bfree; /* # of free blocks on FS of size f_frsize */
! fsblkcnt_t f_bavail; /* # of free blocks on FS of size f_frsize
! * for unprivileged users */
fsfilcnt_t f_files; /* # of file serial numbers */
fsfilcnt_t f_ffree; /* # of free file serial numbers */
fsfilcnt_t f_favail; /* # of free file serial numbers
- Raw text -