This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: getdents64 problem
- To: Andreas Jaeger <aj at suse dot de>
- Subject: Re: getdents64 problem
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 19 Jan 2001 11:54:19 +0100
- Cc: libc-alpha Mailinglist <libc-alpha at sourceware dot cygnus dot com>, Mogens Kjaer <mk at crc dot dk>, Trond Myklebust <trond dot myklebust at fys dot uio dot no>
- References: <u8vgrbdejp.fsf@gromit.rhein-neckar.de>
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
On Fri, Jan 19, 2001 at 11:25:30AM +0100, Andreas Jaeger wrote:
>
> There was yesterday a thread on linux kernel with subject "nfs client
> problem in kernel 2.4.0" which noticed some problems with our getdents
> implementation.
>
> Is the following patch ok? Mogens, does it fix the problems you
> noticed?
At least my understanding was that the problem is the opposite of what
you're doing here:
last kernel_dirent64 entry given from kernel is
{ ?, 0xffffffffULL, ?, ?, ? }
and thus
(sizeof (dp->d_off) != sizeof (kdp->d_off) && dp->d_off != d_off)
check fails (it would succeed if kernel gave { ?, -1LL, ?, ?, ? } instead),
which means (as last_offset != -1 at that point) that we just seek before
this entry and return. On next getdents call, we read
{ ?, 0xffffffffULL, ?, ?, ? }
once again and as last_offset is now -1 (no matter what your patch does), we
return EOVERFLOW since we were not able to convert the last entry into
struct dirent (4GB-1 does not fit into <-2GB,2GB-1> range).
So, I think this is a kernel bug which glibc cannot do anything about
(silently accepting d_off which would not fit would be IMHO a bad thing).
>
> 2001-01-19 Andreas Jaeger <aj@suse.de>
>
> * sysdeps/unix/sysv/linux/getdents.c (__GETDENTS): Make 64 bit
> clean.
>
> ============================================================
> Index: sysdeps/unix/sysv/linux/getdents.c
> --- sysdeps/unix/sysv/linux/getdents.c 2000/11/30 17:41:56 1.15
> +++ sysdeps/unix/sysv/linux/getdents.c 2001/01/19 10:24:24
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
> +/* Copyright (C) 1993,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
> This file is part of the GNU C Library.
>
> The GNU C Library is free software; you can redistribute it and/or
> @@ -98,7 +98,7 @@
> __GETDENTS (int fd, char *buf, size_t nbytes)
> {
> DIRENT_TYPE *dp;
> - off_t last_offset = -1;
> + off64_t last_offset = -1;
> ssize_t retval;
>
> #ifdef __NR_getdents64
> @@ -164,7 +164,7 @@
> otherwise signal overflow. */
> if (last_offset != -1)
> {
> - __lseek (fd, last_offset, SEEK_SET);
> + __lseek64 (fd, last_offset, SEEK_SET);
> return (char *) dp - buf;
> }
> __set_errno (EOVERFLOW);
Jakub