delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/12/30/08:05:37

Date: Mon, 30 Dec 2002 13:05:32 +0000
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Sender: rich AT phekda DOT freeserve DOT co DOT uk
To: djgpp-workers AT delorie DOT com
X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: Problem with df reporting the wrong sizes [PATCH]
Message-Id: <E18Szay-0000eR-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019