Bug 163365 - Apache fails on directory listing of files from MS NFS
Apache fails on directory listing of files from MS NFS
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: apr (Show other bugs)
All Linux
medium Severity medium
: ---
: ---
Assigned To: Joe Orton
Depends On:
  Show dependency treegraph
Reported: 2005-07-15 10:25 EDT by Bastien Nocera
Modified: 2007-11-30 17:07 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2006-10-27 12:20:24 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
test-apr3.c (3.91 KB, text/plain)
2005-07-15 10:25 EDT, Bastien Nocera
no flags Details

  None (edit)
Description Bastien Nocera 2005-07-15 10:25:58 EDT
Directory listing the root directory of an NFS mount from an MS server in Apache
shows up as empty, as if with no (not even '..') directories.

ls on the same directory works.

The attached test case, which uses APR's API to read the directory listing, as
well as readdir and readdir_r shows the problem:
- APR fails, with an EOVERFLOW error
- readdir works
- readdir_r (using code similar to what APR uses) works

If the #defines for LFS support are removed in the test case, readdir and
readdir_r will fail.

So APR needs to be recompiled with LFS support (so that the testcase above uses
readdir64 instead of readdir) for the listing to work on this NFS mount.
Comment 1 Bastien Nocera 2005-07-15 10:25:58 EDT
Created attachment 116801 [details]
Comment 2 Bastien Nocera 2005-07-18 06:30:05 EDT
I've tried recompiling apr with large readdir support, and it would basically
break ABI. From /usr/include/bits/dirent.h:

struct dirent
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
    __ino64_t d_ino;
    __off64_t d_off;
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];           /* We must not include limits.h! */

#ifdef __USE_LARGEFILE64
struct dirent64
    __ino64_t d_ino;
    __off64_t d_off;
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];           /* We must not include limits.h! */
Comment 3 Joe Orton 2005-07-18 08:52:10 EDT
To follow up some off-line discussion: I'm not clear about exactly why this
happens.  It appears the case being hit here may be glibc returning EOVERFLOW
because the inode number cannot be stored in a struct dirent with a 32-bit d_ino

Can you confirm whether there are files with inode numbers > 2^31 in this
directory? (e.g. using "ls -lia")

Comment 5 Thomas Uebermeier 2005-07-20 06:04:13 EDT
Summary: basically no, all inode numbers are within (signed) 32bit 
Comment 11 Jakub Jelinek 2005-07-21 05:03:03 EDT
4294967039 certainly doesn't fit into (signed 32-bit) d_off, so glibc behaviour
is correct.  Now, the bug is either on the MS side or in the kernel,
depending on whether the actual values are going over the wire as 32-bit
or 64-bit values.  If as 32-bit values, then kernel must sign extend them
when getdents64 is called, because it is storing a 32-bit value into signed
Comment 22 RHEL Product and Program Management 2006-08-18 13:33:20 EDT
This request was evaluated by Red Hat Product Management for inclusion in a Red
Hat Enterprise Linux maintenance release.  Product Management has requested
further review of this request by Red Hat Engineering, for potential
inclusion in a Red Hat Enterprise Linux Update release for currently deployed
products.  This request is not yet committed for inclusion in an Update

Note You need to log in before you can comment on or make changes to this bug.