php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68209 php does not work with files that have 64bit inodes (on a 32bit kernels)
Submitted: 2014-10-10 18:53 UTC Modified: 2014-10-11 20:56 UTC
From: arekm at maven dot pl Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.6.1 OS:
Private report: No CVE-ID: None
 [2014-10-10 18:53 UTC] arekm at maven dot pl
Description:
------------
It's perfectly valid to have files with 64bit inodes on a system with 32bit Linux kernel. Unfortunately php is not capable of handling these files. Example:

[arekm@farm 100]$ ls -li 100.txt 
425201762433 -rw-r--r-- 1 root root 0 10-08 23:09 100.txt
[arekm@farm 100]$ php --version
PHP 5.6.0 (cli) (built: Aug 28 2014 20:53:25) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
[arekm@farm 100]$ php -r "var_dump(stat('100.txt'));"
PHP Warning:  stat(): stat failed for 100.txt in Command line code on line 1
bool(false)
[arekm@farm 100]$ file /usr/bin/php
/usr/bin/php: symbolic link to `php56'
[arekm@farm 100]$ file /usr/bin/php56
/usr/bin/php56: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, BuildID[sha1]=9b3d30e4bb089221042dfbe36ca43c8b69a8021f, stripped


The whole problem comes from PHP not being compiled with
// this makes LFS (large file support) functions to be used
// (so glibc stat64() will be called instead of stat())
#define _LARGEFILE_SOURCE
// this makes resulting binary ready for 64bit off_t type (off64_t) this stat()
// won't die with EOVERFLOW errno (see stat(2) for more details)
#define _FILE_OFFSET_BITS=64

The solution is simple. Add
AC_SYS_LARGEFILE
macro to configure.ac. configure will then figure out what defines are needed to get LFS support.

Two reasons to get LFS enabled with php:
- files over 2GB will be correctly handled on 32bit kernels
- small files that have 64bit inodes will be correctly handled on 32bit kernels

ps. there are some bugs that will be uncovered in PHP with LFS enabled (some nesting detection error). That bug would need to be fixed too.


Test script:
---------------
php -r "var_dump(stat('test_file.txt'));"

is enough but test_file.txt needs to have 64bit inode number. To get test file with 64bit inode number do:

# create sparse 10T image

[arekm@farm test]$ truncate -s 10T testimage 

# create fs on it (it will take about 2GB on filesystem), note agcount got set to 10

[arekm@farm test]$ mkfs.xfs testimage       
meta-data=testimage              isize=256    agcount=10, agsize=268435455 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=2684354550, imaxpct=5
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=521728, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[arekm@farm test]$ mkdir mntpoint
[arekm@farm test]$ sudo bash

# mount with inode64 option. This option is default in recent kernels.

[root@farm test]# mount testimage mntpoint -o inode64
[root@farm test]# for i in `seq 1 100`; do mkdir mntpoint/$i && touch mntpoint/$i/$i.txt; done
[root@farm test]# ls -l mntpoint/100/100.txt 
-rw-r--r-- 1 root root 0 Oct 10 20:42 mntpoint/100/100.txt

# make sure one of txt files created has 64bit inode

[root@farm test]# ls -li mntpoint/100/100.txt 
38654705811 -rw-r--r-- 1 root root 0 Oct 10 20:42 mntpoint/100/100.txt

# so test php now on it

[root@farm test]# php -r 'stat("mntpoint/100/100.txt");';
PHP Warning:  stat(): stat failed for mntpoint/100/100.txt in Command line code on line 1
[root@farm test]# 



Expected result:
----------------
Working stat().

Actual result:
--------------
PHP Warning:  stat(): stat failed for mntpoint/100/100.txt in Command line code on line 1
failure.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-10-10 18:53 UTC] arekm at maven dot pl
-Summary: php does not work with files that have 64bit inodes on a 32bit filesystem +Summary: php does not work with files that have 64bit inodes (on a 32bit kernels)
 [2014-10-10 18:53 UTC] arekm at maven dot pl
Fixed summary.
 [2014-10-10 19:21 UTC] glen at delfi dot ee
AFAIK it is not that safe to enable LFS, as then libraries linked with PHP need to be LFS compatible too.

see http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/023935.html

or top of that  thread:
http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/thread.html#23916
 [2014-10-10 20:07 UTC] arekm at maven dot pl
Doesn't seem to be true since currently php is not LFS enabled while most of system libraries are LFS enabled on recent distros and I saw no bugreports related to that.

Probably php doesn't interchange 'struct stat' data between itself and libs thus is safe to mix non LFS php and LFS libraries.
 [2014-10-11 20:40 UTC] johannes@php.net
-Status: Open +Status: Not a bug
 [2014-10-11 20:40 UTC] johannes@php.net
There are such places - notably the SAPI interface has a function to pass the stat structure from a web server to PHP in order to save stat calls if the server already does. http://lxr.php.net/xref/PHP_5_6/main/SAPI.h#232

There are also different extensions where file pointers are passed around.

We already have open bugs for this, i.e. https://bugs.php.net/bug.php?id=27792closing this issue as duplicate.
 [2014-10-11 20:56 UTC] arekm at maven dot pl
This bug is not about large files.

It is about small files (example has 0 bytes size) and these files have 64bit inodes.

Of course (one) solution for both cases is to use LFS but these are different things.

The other solution would be cooking stat() wrapper. Wrapper that would use stat64 with _FILE_OFFSET_BITS=64 and just truncate s_ino as php mostly doesn't care about this.
 [2014-10-12 13:40 UTC] glen at delfi dot ee
Totally agree with arek, large file SIZE is totally different issue than file opened on 64bit filesystem. with bug 68209 even small file like 0 byte file is not accessible with php.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 27 16:01:29 2024 UTC