This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 2/2] Squashing 64bit directory inode into 32bit inode field
- From: Denis Obrezkov <reprofy at etersoft dot ru>
- To: libc-alpha at sourceware dot org
- Cc: Denis Obrezkov <reprofy at etersoft dot ru>
- Date: Thu, 27 Feb 2014 21:22:56 +0400
- Subject: [PATCH 2/2] Squashing 64bit directory inode into 32bit inode field
- Authentication-results: sourceware.org; auth=none
- References: <1393521776-1102-1-git-send-email-reprofy at etersoft dot ru>
Replace returning EOVERFLOW by sqashing long inode.
ports/ChangeLog:
2014-02-15 Denis Obrezkov <reprofy@etersoft.ru>
* ports/sysdeps/unix/sysv/linux/generic/wordsize-32/getdents.c
(squash_dir_inode): Squashing long directory inodes.
(__getdents): Squashing inodes instead of EOVERFLOW returning.
---
.../unix/sysv/linux/generic/wordsize-32/getdents.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/ports/sysdeps/unix/sysv/linux/generic/wordsize-32/getdents.c b/ports/sysdeps/unix/sysv/linux/generic/wordsize-32/getdents.c
index bafde85..2b7877c 100644
--- a/ports/sysdeps/unix/sysv/linux/generic/wordsize-32/getdents.c
+++ b/ports/sysdeps/unix/sysv/linux/generic/wordsize-32/getdents.c
@@ -30,6 +30,13 @@
#include <sysdep.h>
#include <sys/syscall.h>
+static ino_t
+squash_dir_inode (ino_t d_ino32, uint64_t d_ino64)
+{
+ d_ino32 ^= d_ino64 >> (sizeof (uint64_t) - sizeof (ino_t)) * 8;
+ return d_ino32;
+}
+
/* Pack the dirent64 struct down into 32-bit offset/inode fields, and
ensure that no overflow occurs. */
ssize_t
@@ -87,10 +94,14 @@ __getdents (int fd, char *buf, size_t nbytes)
outp->u.d_ino = d_ino;
outp->u.d_off = d_off;
- if ((sizeof (outp->u.d_ino) != sizeof (inp->k.d_ino)
+ if (sizeof (outp->u.d_ino) != sizeof (inp->k.d_ino)
&& outp->u.d_ino != d_ino)
- || (sizeof (outp->u.d_off) != sizeof (inp->k.d_off)
- && outp->u.d_off != d_off))
+ {
+ /* Inode overflow. Squash it*/
+ outp->u.d_ino = squash_dir_inode (outp->u.d_ino, d_ino);
+ }
+ if (sizeof (outp->u.d_off) != sizeof (inp->k.d_off)
+ && outp->u.d_off != d_off)
{
/* Overflow. If there was at least one entry before this one,
return them without error, otherwise signal overflow. */
--
1.8.4.5