Bug 163365 - Apache fails on directory listing of files from MS NFS
Summary: Apache fails on directory listing of files from MS NFS
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: apr
Version: 4.0
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
: ---
Assignee: Joe Orton
QA Contact:
URL:
Whiteboard: RHEL4U3NAK
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2005-07-15 14:25 UTC by Bastien Nocera
Modified: 2007-11-30 22:07 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2006-10-27 16:20:24 UTC
Target Upstream Version:
Embargoed:


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

Description Bastien Nocera 2005-07-15 14:25:58 UTC
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 14:25:58 UTC
Created attachment 116801 [details]
test-apr3.c

Comment 2 Bastien Nocera 2005-07-18 10:30:05 UTC
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;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    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! */
  };
#endif


Comment 3 Joe Orton 2005-07-18 12:52:10 UTC
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
field.

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 10:04:13 UTC
Summary: basically no, all inode numbers are within (signed) 32bit 

Comment 11 Jakub Jelinek 2005-07-21 09:03:03 UTC
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
off64_t.

Comment 22 RHEL Program Management 2006-08-18 17:33:20 UTC
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
release.


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