From e40c96e8149713855ee3ea599b09ded22aaaf8d1 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 26 May 2011 03:51:55 +0000 Subject: *** empty log message *** --- Changes | 3 ++- eio.c | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Changes b/Changes index 3bc3388..2685024 100644 --- a/Changes +++ b/Changes @@ -36,4 +36,5 @@ TODO: openbsd requires stdint.h for intptr_t - why posix? - use _POSIX_MEMLOCK_RANGE for mlock. - do not (errornously) overwrite CFLAGS in configure.ac. - mknod used int3 for dev_t (ยง2 bit), not offs (64 bit). - + - fix memory corruption in eio_readdirx for the flags + combination EIO_READDIR_STAT_ORDER | EIO_READDIR_DIRS_FIRST. diff --git a/eio.c b/eio.c index b303299..2123996 100644 --- a/eio.c +++ b/eio.c @@ -1062,8 +1062,10 @@ eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) static signed char eio_dent_cmp (const eio_dirent *a, const eio_dirent *b) { - return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */ - : a->inode < b->inode ? -1 : a->inode > b->inode ? 1 : 0; + return a->score - b->score ? a->score - b->score /* works because our signed char is always 0..100 */ + : a->inode < b->inode ? -1 + : a->inode > b->inode ? 1 + : 0; } #define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0 @@ -1079,8 +1081,8 @@ eio_dent_radix_sort (eio_dirent *dents, int size, signed char score_bits, ino_t assert (CHAR_BIT == 8); assert (sizeof (eio_dirent) * 8 < 256); - assert (offsetof (eio_dirent, inode)); /* we use 0 as sentinel */ - assert (offsetof (eio_dirent, score)); /* we use 0 as sentinel */ + assert (offsetof (eio_dirent, inode)); /* we use bit #0 as sentinel */ + assert (offsetof (eio_dirent, score)); /* we use bit #0 as sentinel */ if (size <= EIO_SORT_FAST) return; @@ -1245,6 +1247,7 @@ eio__scandir (eio_req *req, etp_worker *self) X_LOCK (wrklock); /* the corresponding closedir is in ETP_WORKER_CLEAR */ self->dirp = dirp = opendir (req->ptr1); + req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE; req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0; req->ptr2 = names = malloc (namesalloc); @@ -1266,7 +1269,7 @@ eio__scandir (eio_req *req, etp_worker *self) req->result = dentoffs; if (flags & EIO_READDIR_STAT_ORDER) - eio_dent_sort (dents, dentoffs, 0, inode_bits); /* sort by inode exclusively */ + eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits); else if (flags & EIO_READDIR_DIRS_FIRST) if (flags & EIO_READDIR_FOUND_UNKNOWN) eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */ -- cgit v1.2.3