Skip to content

disk_*_space uses statvfs on macOS and it returns inaccurate results for some filesystems #8048

Closed

Description

@risner

Description

The following code:

<?php print disk_total_space("/nfs1") . "\n";?>

Resulted in this output:

198919206912

But I expected this output instead:

60518056220

The code works correctly for local filesystems, and fails on NFS.
If I remember correctly the posix standard is not required to provide correct information. Should php never be using the statvfs call?

Data points for NFS:
php total 198919206912
correct total 30985244784640
df total 30259028110
vfs total 194257038
fs f_bsize 512 vfs 1048576
fs f_iosize 1048576 vfs f_frsize 512
fs f_blocks 60518056220 vfs 388514076
fs f_bfree 20573829227 vfs 3393960043
fs f_bavail 20573829227 vfs 3393960043

Data points for local:
php total 245107195904 vfs 245107195904
correct total 245107195904
df total 3496966385312
vfs total 3496966385312
fs f_bsize 4096 vfs 1048576
fs f_iosize 1048576 vfs f_frsize 4096
fs f_blocks 59840624 vfs 59840624
fs f_bfree 5153807 vfs 5153807
fs f_bavail 5153807 vfs 5153807

PHP Version

PHP 7.4

Operating System

macOS 12.1

Activity

  1. risner commented on Feb 6, 2022

    @risner
    ContributorAuthor

    Additionally, on FreeBSD there is a standards note:
    STANDARDS
    The statvfs() and fstatvfs() functions conform to IEEE Std 1003.1-2001
    (“POSIX.1”). As standardized, portable applications cannot depend on
    these functions returning any valid information at all.
    This
    implementation attempts to provide as much useful information as is
    provided by the underlying file system, subject to the limitations of the
    specified data types.

  2. risner commented on Feb 7, 2022

    @risner
    ContributorAuthor

    Looking at macOS's Libc-1353.11.2, it does a conversion from statfs to statvfs in libc.
    It is an integer overflow issue.
    size x64 = 8; size x32 = 4
    x64 = 60518056220; x32 = 388514076

    For reliable results, on macOS the source should be statfs(2) instead of statvfs(3). I suspect this is a good practice to do whenever statfs is also available. Linux my be the exception, I found a number of statements regarding Linux doing statvfs correctly while researching this issue.

    Code snip of the function:
    /* Internal common conversion function */
    static void
    cvt_statfs_to_statvfs(struct statfs *from, struct statvfs *to)
    {
    to->f_bsize = from->f_iosize;
    to->f_frsize = from->f_bsize;
    to->f_blocks = (fsblkcnt_t)from->f_blocks;
    to->f_bfree = (fsblkcnt_t)from->f_bfree;

  3. devnexen commented on Feb 7, 2022

    @devnexen
    Member

    are you able to propose a PR eventually ?

  4. risner commented on Feb 7, 2022

    @risner
    ContributorAuthor
  5. changed the title [-]disk_*_space uses statvfs on macOS and it returns inaccruate results for some filesystems[/-] [+]disk_*_space uses statvfs on macOS and it returns inaccurate results for some filesystems[/+] on Feb 7, 2022
  6. linked a pull request that will close this issueFixed GH-8048: Force macOS to use statfs. #8056on Mar 4, 2022
  7. added 2 commits that reference this issue on Mar 4, 2022
    57ef16b
    81048b9
  8. added a commit that references this issue on Mar 4, 2022
    2384c23
  9. cmb69 commented on Mar 4, 2022

    @cmb69
    Member

    Thanks for the PR, and sorry it tooks so long to merge! The fix will only be available as of PHP 8.0.18 and 8.1.5, respectively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions