From: Martin Mares Date: Wed, 2 Aug 2000 09:00:56 +0000 (+0000) Subject: Rewrote large file support. Instead of mucking with SHERLOCK_O_LARGEFILE X-Git-Tag: holmes-import~1628 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=253574f355eb91472ec45ffb4609193c5d59b07e;p=libucw.git Rewrote large file support. Instead of mucking with SHERLOCK_O_LARGEFILE all the way around, just use sh_{open,pread,pwrite} instead of the ordinary calls. --- diff --git a/lib/config.h b/lib/config.h index e827ec5f..37b19867 100644 --- a/lib/config.h +++ b/lib/config.h @@ -1,7 +1,7 @@ /* * Sherlock Library -- Configuration-Dependent Definitions * - * (c) 1997--1999 Martin Mares, + * (c) 1997--2000 Martin Mares, */ #ifndef _SHERLOCK_CONFIG_H @@ -13,9 +13,10 @@ /* Features */ -#define SHERLOCK_CONFIG_REF_WEIGHTS -#define SHERLOCK_CONFIG_LARGE_DB -#define SHERLOCK_CONFIG_LFS +#define SHERLOCK_CONFIG_REF_WEIGHTS /* Weighed references */ +#define SHERLOCK_CONFIG_LARGE_DB /* Support for DB files >4GB */ +#define SHERLOCK_CONFIG_LFS /* Large files on 32-bit systems */ +#undef SHERLOCK_CONFIG_LFS_LIBC /* LFS supported directly by libc */ /* Types */ diff --git a/lib/fastbuf.c b/lib/fastbuf.c index 6bbadb40..c3b8b80d 100644 --- a/lib/fastbuf.c +++ b/lib/fastbuf.c @@ -31,11 +31,7 @@ struct fastbuf *__bfdopen(int fd, uns buffer, byte *name) struct fastbuf * bopen(byte *name, uns mode, uns buffer) { - int fd; - - mode |= SHERLOCK_O_LARGEFILE; - fd = open(name, mode, 0666); - + int fd = sh_open(name, mode, 0666); if (fd < 0) die("Unable to %s file %s: %m", (mode & O_CREAT) ? "create" : "open", name); diff --git a/lib/lfs.h b/lib/lfs.h index 089fad35..ceb9e307 100644 --- a/lib/lfs.h +++ b/lib/lfs.h @@ -1,7 +1,7 @@ /* * Sherlock Library -- Large File Support * - * (c) 1999 Martin Mares, + * (c) 1999--2000 Martin Mares, */ #ifndef _SHERLOCK_LFS_H @@ -9,6 +9,28 @@ #ifdef SHERLOCK_CONFIG_LFS +#ifdef SHERLOCK_CONFIG_LFS_LIBC + +/* + * Unfortunately, we need to configure this manually since + * out-of-the-box glibc 2.1 offers the 64-bit calls, but + * converts them to 32-bit syscalls. Damn it! + */ + +#define sh_open open64 +#define sh_seek lseek64 +#define sh_pread pread64 +#define sh_pwrite pwrite64 +#define SHERLOCK_HAVE_PREAD + +#else + +/* + * Talk directly with the kernel. The LFS implementations of LFS in Linux 2.2 + * and 2.4 differ, but fortunately for us only in things like stat64 which + * we don't need to use. + */ + #ifndef O_LARGEFILE #if defined(__linux__) && defined(__i386__) #define O_LARGEFILE 0100000 @@ -17,7 +39,11 @@ #endif #endif -#define SHERLOCK_O_LARGEFILE O_LARGEFILE +extern inline int +sh_open(char *name, int flags, int mode) +{ + return open(name, flags | O_LARGEFILE, mode); +} #if 0 @@ -38,16 +64,23 @@ extern inline loff_t sh_seek(int fd, sh_off_t pos, int whence) } #else +#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0 +/* glibc 2.1 or newer -> has lseek64 */ +#define sh_seek(f,o,w) lseek64(f,o,w) +#else /* Touching hidden places in glibc */ extern loff_t llseek(int fd, loff_t pos, int whence); #define sh_seek(f,o,w) llseek(f,o,w) +#endif #endif +#endif /* !SHERLOCK_CONFIG_LFS_LIBC */ + #else /* !SHERLOCK_CONFIG_LFS */ +#define sh_open open #define sh_seek(f,o,w) lseek(f,o,w) -#define SHERLOCK_O_LARGEFILE 0 #endif /* !SHERLOCK_CONFIG_LFS */ @@ -56,10 +89,20 @@ extern loff_t llseek(int fd, loff_t pos, int whence); * isn't simple at all since all libc's until glibc 2.1 don't define it. */ +#ifndef SHERLOCK_HAVE_PREAD + #ifdef __linux__ +#define SHERLOCK_HAVE_PREAD #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0 /* glibc 2.1 or newer -> pread/pwrite supported automatically */ -#define SHERLOCK_HAVE_PREAD +#ifdef SHERLOCK_CONFIG_LFS +/* but have to use the 64-bit versions explicitly */ +#define sh_pread pread64 +#define sh_pwrite pwrite64 +#else +#define sh_pread pread +#define sh_pwrite pwrite +#endif #elif defined(i386) && defined(__GLIBC__) /* glibc 2.0 on i386 -> call syscalls directly */ #include @@ -69,21 +112,29 @@ extern loff_t llseek(int fd, loff_t pos, int whence); #ifndef SYS_pread #define SYS_pread 180 #endif -static int pread(unsigned int fd, void *buf, size_t size, loff_t where) +static int sh_pread(unsigned int fd, void *buf, size_t size, loff_t where) { return syscall(SYS_pread, fd, buf, size, where); } #ifndef SYS_pwrite #define SYS_pwrite 181 #endif -static int pwrite(unsigned int fd, void *buf, size_t size, loff_t where) +static int sh_pwrite(unsigned int fd, void *buf, size_t size, loff_t where) { return syscall(SYS_pwrite, fd, buf, size, where); } -#define SHERLOCK_HAVE_PREAD #elif defined(i386) /* old libc on i386 -> call syscalls directly the old way */ #include static _syscall4(int, pread, unsigned int, fd, void *, buf, size_t, size, loff_t, where); static _syscall4(int, pwrite, unsigned int, fd, void *, buf, size_t, size, loff_t, where); -#define SHERLOCK_HAVE_PREAD +#define sh_pread pread +#define sh_pwrite pwrite +#else +#undef SHERLOCK_HAVE_PREAD #endif #endif /* __linux__ */ +#endif /* !SHERLOCK_HAVE_PREAD */ + +#ifndef SHERLOCK_HAVE_PREAD +#error pread/pwrite not available, need to work around +#endif + #endif /* !_SHERLOCK_LFS_H */ diff --git a/lib/pagecache.c b/lib/pagecache.c index 149986d9..f194fc5c 100644 --- a/lib/pagecache.c +++ b/lib/pagecache.c @@ -4,8 +4,6 @@ * (c) 1999--2000 Martin Mares */ -#define _GNU_SOURCE - #include #include #include @@ -105,7 +103,7 @@ flush_page(struct page_cache *c, struct page *p) ASSERT(p->flags & PG_FLAG_DIRTY); #ifdef SHERLOCK_HAVE_PREAD - s = pwrite(p->fd, p->data, c->page_size, p->pos); + s = sh_pwrite(p->fd, p->data, c->page_size, p->pos); #else if (c->pos != p->pos || c->pos_fd != p->fd) sh_seek(p->fd, p->pos, SEEK_SET); @@ -282,7 +280,7 @@ pgc_read(struct page_cache *c, int fd, sh_off_t pos) { c->stat_miss++; #ifdef SHERLOCK_HAVE_PREAD - s = pread(fd, p->data, c->page_size, pos); + s = sh_pread(fd, p->data, c->page_size, pos); #else if (c->pos != pos || c->pos_fd != fd) sh_seek(fd, pos, SEEK_SET);