2.2.19 NFSv3 client breaks fdopen(3)

From: Matthias Andree (ma@dt.e-technik.uni-dortmund.de)
Date: Thu Apr 26 2001 - 12:26:32 EST


Hi,

SHORT:

the current 2.2.19 fs/nfs/dir.c ll. 455ff. nfs_dir_lseek breaks
fdopen(3) which (at least with glibc 2.1.3) cals __llseek with offset==0
and whence==1 (SEEK_CUR), probably to poll the current file position.
Application software affected comprises cvs (tried 1.10.7) and Perl5
(sysopen, see below).

I suggest that SEEK_CUR be allowed for offset == 0 in nfs_dir_llseek,
but I'm asking for help since I'm not into this and cannot do this on my
own. Thanks in advance.

LONG, with hints and logs:

Symptom: software calls __llseek with SEEK_CUR, offset=0; possibly to
obtain file pointer position on fdopen, and gets EINVAL. This seems to
be a deliberate decision from what I see in fs/nfs/dir.c. I traced what
happens to a simply Perl5 script in gdb, see below.

Regretfully, I cannot try either 2.4.3 (fails to detect sda attached to
aic7xxx) nor 2.4.4-pre6 (does not compile for __builtin_expect) nor
2.4.3-ac14 (pcnet32.c:327: pcnet32_pci_tbl causes a section type
conflict) to see. Using gcc 2.95.2 here.

Solaris 7 clients doing the same user-space operations on the same NFS
server (Linux 2.2.19 knfsd) are fine.

Perl script to test:

sysopen(O, "/net/server/usr/net", O_RDONLY) or die "sysopen failed: $!";
/net/server/usr/net is an automounted NFSv2 or NFSv3 directory

C source to trigger problem, with strace:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

main() {
        int fd = open("/net/server/usr/net", O_RDONLY);
        /* again, that's a NFS-imported directory, no matter if NFSv2 or
           v3 */
        if(fd) {
                FILE *f = fdopen(fd, "r");
        }
}

strace, omitting brk:
open("/net/server/usr/net", O_RDONLY) = 3
fcntl(3, F_GETFL) = 0 (flags O_RDONLY)
...
fstat64(3, 0xbffff45c) = -1 ENOSYS (Function not implemented)
fstat(3, {st_mode=S_IFDIR|S_ISGID|0755, st_size=2048, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x124000
_llseek(3, 0, 0xbffff4a4, SEEK_CUR) = -1 EINVAL (Invalid argument)
_exit(0) = ?

Stack trace, caught when entering _llseek:

#0 0x1cf665 in __llseek (fd=5, offset=0, whence=1)
    at ../sysdeps/unix/sysv/linux/llseek.c:32
#1 0x17d49b in _IO_file_seek () at fileops.c:671
#2 0x17d3a9 in _IO_new_file_seekoff (fp=0x8049618, offset=0, dir=1, mode=3)
    at fileops.c:652
#3 0x17cbc3 in _IO_new_file_attach (fp=0x8049618, fd=5) at fileops.c:268
#4 0x178f7c in _IO_new_fdopen (fd=5, mode=0x80484dc "r") at iofdopen.c:126
#5 0x804845e in main () at test.c:10

-- 
Matthias Andree
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Apr 30 2001 - 21:00:16 EST