Thread (1 message) 1 message, 1 author, 2001-08-10
  • (off-list ancestor, not in this archive)
  • Re: XFS installer · Steve Lord <hidden> · 2001-08-10

Re: XFS installer

From: Steve Lord <hidden>
Date: 2001-08-10 14:58:29

On Fri, Aug 10, 2001 at 08:46:26AM -0500, Steve Lord wrote:
quoted
The page size == block size will get fixed, we need to do that, but it
may take a while. Block size less than pagesize will come first, blocksize
greater than pagesize needs PAGE_CACHE_SIZE to be bumped, which appears to
be on the cards for 2.5.

V1 directories mostly work in Linux, but there are glibc getdents issues
with them. The glibc code which lseeks backwards in a directory is the issu
e,
quoted
if you have control over your glibc it can be fixed by using the 64 bit
version of lseek in this code. This is all because the directory offset in
V1 is a 64 bit hash value, not a 32 bit signed number.
So in other words that means using kernel 2.4 / glibc 2.2 and for 32-bit
systems building applications with the large file API.
No, it all depends on which version of the glibc getdents code you have,
there have been several, I cannot remember what it looks like now.
here is an old patch:
--- glibc-2.1.3/sysdeps/unix/sysv/linux/getdents.c.orig	Fri May  7 09:41:08 1999
+++ glibc-2.1.3/sysdeps/unix/sysv/linux/getdents.c	Thu Mar 23 11:49:11 2000
@@ -53,6 +53,9 @@
 #ifdef GETDENTS64
 # define __getdents __getdents64
 # define dirent dirent64
+# undef off_t
+# define off_t off64_t
+# define __lseek __lseek64
 #endif
 
 /* The problem here is that we cannot simply read the next NBYTES
@@ -107,6 +110,33 @@
 	}
 
       last_offset = kdp->d_off;
+
+#ifdef GETDENTS64
+	if (sizeof(__kernel_off_t) < sizeof(off64_t)) {
+	    /*
+	     * The kernel returns d_off as a 'cookie' that can be used
+	     * in an lseek() to re-position the directory stream.
+	     * "d_off" is signed by current definition of "__kernel_off_t",
+	     * which is consistent with lseek() "off_t" semantics.
+	     * Some file systems, most commonly NFS, may return "d_off"
+	     * 'cookies' that use all 32 bits, or more specifically the
+	     * sign bit.
+	     * This means we need to be careful how we save "last_offset"
+	     * in the case where "last_offset" is defined to be a larger
+	     * container than "__kernel_off_t", we want to prevent the sign
+	     * extension; it's only the lower 32 bits that we want to be
+	     * able to pass back in via lseek64().
+	     */
+	    switch(sizeof(__kernel_off_t)) {
+	    case 4:
+		{
+		    last_offset = (u_int32_t)kdp->d_off;
+
+		    break;
+		}
+	    }
+	}
+#endif
       dp->d_ino = kdp->d_ino;
       dp->d_off = kdp->d_off;
       dp->d_reclen = new_reclen;

I am pretty sure this patch is useless with a 2.2 glibc.

The issue is not so much the application interface as the fact that glibc has
the nasty habit of lseeking back in the directory because its dirent and
the kernels are not the same size. 

Steve
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help