php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40893 PHP reports wrong total and free space for NFS-mounted filesystems on RedHat
Submitted: 2007-03-22 14:59 UTC Modified: 2007-04-03 01:00 UTC
Votes:2
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: andrew at digicol dot de Assigned:
Status: No Feedback Package: Filesystem function related
PHP Version: 4.4.5 OS: Redhat EL4
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: andrew at digicol dot de
New email:
PHP Version: OS:

 

 [2007-03-22 14:59 UTC] andrew at digicol dot de
Description:
------------
disk_total_space, disk_free_space reports wrong total and free space for NFS-mounted filesystems on RedHat Linux.

This bug seems to be the related to #39520, if not the same. #39520 has been rated as 'bogus' which I think is a mistake. Please re-consider.

The bug shows on RedHat Linux, but not SuSE Linux. This might ultimately be considered as a RedHat bug or of the libraries used there, but other commands (df) that use the statfs system call show the correct file system size / free space. 

It may be argued (like in #39520) that the wrong block size parameter is used to calculate total or free disk space. strace df -h shows RedHat and SuSE report different f_frsize, but same f_bsize on the same NFS share, but df reports the correct size on both.

Reproduce code:
---------------
Test: Mount a NFS share on a RedHat system and on a SuSE Linux system.

1) RedHat 2.6.9-34.EL, 32-bit
[root@dc5ora10gr2 /]# mount -t nfs 10.20.0.178:/dot/oracle_dump /mnt
[root@dc5ora10gr2 /]# df -h
Filesystem                   Size Used Avail Use% Mounted on
...
10.20.0.178:/dot/oracle_dump 280G 125G 156G 45% /mnt
[root@dc5ora10gr2 /]# /dot/dc/bin/php/bin/php -r 'echo_number_format(disk_total_space("/mnt")) . "\n";'
37,512,204,288    ==> Wrong size, seems to be real size / 8

2) SuSE Linux 9.3 32-bit
suse:/ # mount -t nfs 10.20.0.178:/dot/oracle_dump /mnt
suse:/ # df -h
Filesystem                   Size Used Avail Use% Mounted on
...
10.20.0.178:/dot/oracle_dump 280G 125G 156G 45% /mnt
suse:/ # php -r 'echo number_format(disk_total_space("/mnt")) . "\n";'
300,097,634,304    ==> Correct.


Expected result:
----------------
I would expect the result to be 300G on both systems.

Actual result:
--------------
Reports 300G on SuSE Linux, around 35G only on RedHat.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-03-22 15:06 UTC] andrew at digicol dot de
PHP version seems to be irrelevant, but I was forced to choose a version because of the bug category. I couldn't find the versions I tried it on (4.3.9, 5.2.0) in the version drop-down.
 [2007-03-22 15:17 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2007-03-22 15:21 UTC] tony2001@php.net
If you're still able to reproduce it - try to trace it and figure out which blocksize is reported by the system and which function is used - statvfs() or statfs().
 [2007-03-22 15:38 UTC] andrew at digicol dot de
RedHat Linux:

strace /dot/dc/bin/php/bin/php -r 'echo number_format(disk_total_space("/mnt")) . "\n";'
...
statfs("/mnt", {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=9158253, f_bfree=5093458, f_bavail=5093458, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
...

SuSE Linux:

strace  php -r 'echo number_format(disk_total_space("/mnt")) . "\n";'
...
statfs("/mnt", {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=9158253, f_bfree=5093458, f_bavail=5093458, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=32768}) = 0
...

Just in case this helps, "df -h" seems to invoke the a different system call (statfs64, both systems are 32-bit, I am not an expert regarding system calls). They result in the same f_bsize and fr_size values. Unlike php, df draws the correct conclusions regarding total / free space on both systems:

RedHat Linux:

strace df -h
...
statfs64("/mnt", 84, {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=9158253, f_bfree=5093460, f_bavail=5093460, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
...

SuSE Linux:

strace df -h
...
statfs64("/mnt", 84, {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=9158253, f_bfree=5093460, f_bavail=5093460, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=32768}) = 0
...
 [2007-03-22 17:19 UTC] tony2001@php.net
From what I can see in df sources, it uses exactly the same logics as PHP, so I don't really see how it's possible that you get correct values with df, especially taking into account that the f_frsize is broken in the same way there.

You might want to look at this RH bug: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=146427
It says that RHEL3 U4 fixes it.
 [2007-03-22 21:26 UTC] andrew at digicol dot de
We get the correct sizes with df (I would not have considered posting the bug report otherwise). We are using df (coreutils) 5.2.1 on RedHat.

The RedHat version is RHEL 4 btw, not 3.

Maybe it is an NFS-related bug that is handled gracefully in df.
 [2007-03-24 13:19 UTC] andrew at digicol dot de
I have no solution, but an explanation:

Looking at the code for PHP's filestat.c we see:
  When statfs is called, size is  bytestotal = f_blocks * f_bsize
  When statvfs is called, size is  bytestotal = f_blocks * f_frsize
  
Looking at the system trace, which shows statfs, indicates f_bsize is used, looking at what PHP actually shows for disk_total_space indicates f_frsize is used in the calculation.
 
The problem with RedHat Linux seems to be that is has statvfs, but this calls statfs internally. This is a problem, it confuses PHP about what block size parameter to use for space calculations.

I add the following lines to the function disk_total_space in ext/standard/filestat.c and re-compiled php:

#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
    syslog(LOG_INFO, "# include <sys/statvfs.h>\n");
#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS)
    syslog(LOG_INFO, "# include <sys/statfs.h>\n");
#elif defined(HAVE_SYS_MOUNT_H) && defined(HAVE_STATFS)
    syslog(LOG_INFO, "# include <sys/mount.h>\n");
#endif

The following command:
  strace /dot/dc/bin/php-5.2.0-logging/bin/php -r 'echo number_format(disk_total_space("/mnt")) . "\n";'

will show:
  ..
  statfs("/mnt", {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=9158253, f_bfree=5093336, f_bavail=5093336, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
  ..
  
and the this appears in /var/log/messages:
  Mar 24 14:02:20 dc5ora10gr2 php: # include <sys/statvfs.h>
  
I haven't looked at the source code for df but somehow it is able to cope with it.
 [2007-03-26 23:19 UTC] tony2001@php.net
I'm unable to reproduce it and unable to track it down.
An account on this RH machine would help.
 [2007-04-03 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 03:01:28 2024 UTC