From 28be87c7c427f4f6dd4e3d2b9e53f5e1653489f0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 5 Nov 2002 23:03:02 +0000 Subject: [PATCH] Add support for databases larger than 2GB under Unix. Must be compiled with -D_FILE_OFFSET_BITS=64 and -D_LARGEFILE_SOURCE in order to work with larger databases. (CVS 778) FossilOrigin-Name: a3f67fe9121ca4655510094fe775b8603a87800e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os.c | 24 ++++++++++++++---------- src/os.h | 7 ++++--- src/pager.c | 21 +++++++++++---------- 5 files changed, 38 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 3421d6d466..55bfddb59a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite_version()\sSQL\sfunction\sas\sa\sbuilt-in.\s(CVS\s777) -D 2002-11-04T19:32:25 +C Add\ssupport\sfor\sdatabases\slarger\sthan\s2GB\sunder\sUnix.\s\sMust\sbe\scompiled\nwith\s-D_FILE_OFFSET_BITS=64\sand\s-D_LARGEFILE_SOURCE\sin\sorder\sto\swork\swith\nlarger\sdatabases.\s(CVS\s778) +D 2002-11-05T23:03:03 F Makefile.in d6c9a85c2a5e696843201d090dcf8bf2f8716f2a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -30,9 +30,9 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/insert.c 764300a0bd8074a2174946c0bf8a550bd833397a F src/main.c b95d7eeec90f86d05b6a064d07db34b7279e06d4 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 -F src/os.c ede7346dffdbab40c6de20d2f325981f3f1168fd -F src/os.h 3009379b06941e7796a9812d1b6cbc59b26248c8 -F src/pager.c 592e5931fdc65e952a6c3e152bc822580856532a +F src/os.c 355c66ca67623f9fd652e5c20820b1d9e2210c2a +F src/os.h c5e4fb5906b506d6e0ad99485a777928b27f6228 +F src/pager.c baf50d8308c61d079086f532c70155cd22c6d07a F src/pager.h 6991c9c2dc5e4c7f2df4d4ba47d1c6458f763a32 F src/parse.y 469c9636ff713e63c00234662209f11668671ae9 F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167 @@ -149,7 +149,7 @@ F www/speed.tcl a20a792738475b68756ea7a19321600f23d1d803 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 326e0983c34b584a3c4a2300399bff0a8281b9f8 -R 12c8410f7c6ea71ae42e48a4c6d31874 +P 7c8c0e7633dca00bde7bc7c22075f688c034c200 +R bb6cf2c43588a20871dc03d12670be4d U drh -Z f6c61d47bb938fe73872fd88f36201ed +Z 1af0198577d28fb69a5246d24434f76c diff --git a/manifest.uuid b/manifest.uuid index 4d607285c2..e5e8968a89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c8c0e7633dca00bde7bc7c22075f688c034c200 \ No newline at end of file +a3f67fe9121ca4655510094fe775b8603a87800e \ No newline at end of file diff --git a/src/os.c b/src/os.c index 42dc89dd6b..adafc35d2e 100644 --- a/src/os.c +++ b/src/os.c @@ -22,7 +22,14 @@ # include # include # include +# ifndef O_LARGEFILE +# define O_LARGEFILE 0 +# endif +# ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +# endif #endif + #if OS_WIN # include #endif @@ -232,9 +239,9 @@ int sqliteOsOpenReadWrite( int *pReadonly ){ #if OS_UNIX - id->fd = open(zFilename, O_RDWR|O_CREAT, 0644); + id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE, 0644); if( id->fd<0 ){ - id->fd = open(zFilename, O_RDONLY); + id->fd = open(zFilename, O_RDONLY|O_LARGEFILE); if( id->fd<0 ){ return SQLITE_CANTOPEN; } @@ -303,10 +310,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ if( access(zFilename, 0)==0 ){ return SQLITE_CANTOPEN; } -#ifndef O_NOFOLLOW -# define O_NOFOLLOW 0 -#endif - id->fd = open(zFilename, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600); + id->fd = open(zFilename, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE, 0600); if( id->fd<0 ){ return SQLITE_CANTOPEN; } @@ -359,7 +363,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ */ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){ #if OS_UNIX - id->fd = open(zFilename, O_RDONLY); + id->fd = open(zFilename, O_RDONLY|O_LARGEFILE); if( id->fd<0 ){ return SQLITE_CANTOPEN; } @@ -536,7 +540,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){ /* ** Move the read/write pointer in a file. */ -int sqliteOsSeek(OsFile *id, int offset){ +int sqliteOsSeek(OsFile *id, off_t offset){ SEEK(offset/1024 + 1); #if OS_UNIX lseek(id->fd, offset, SEEK_SET); @@ -573,7 +577,7 @@ int sqliteOsSync(OsFile *id){ /* ** Truncate an open file to a specified size */ -int sqliteOsTruncate(OsFile *id, int nByte){ +int sqliteOsTruncate(OsFile *id, off_t nByte){ SimulateIOError(SQLITE_IOERR); #if OS_UNIX return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; @@ -588,7 +592,7 @@ int sqliteOsTruncate(OsFile *id, int nByte){ /* ** Determine the current size of a file in bytes */ -int sqliteOsFileSize(OsFile *id, int *pSize){ +int sqliteOsFileSize(OsFile *id, off_t *pSize){ #if OS_UNIX struct stat buf; SimulateIOError(SQLITE_IOERR); diff --git a/src/os.h b/src/os.h index 2b9f53cf99..25dde98e7a 100644 --- a/src/os.h +++ b/src/os.h @@ -60,6 +60,7 @@ HANDLE h; /* Handle for accessing the file */ int locked; /* 0: unlocked, <0: write lock, >0: read lock */ }; + typedef int off_t; # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) # define SQLITE_MIN_SLEEP_MS 1 #endif @@ -73,10 +74,10 @@ int sqliteOsTempFileName(char*); int sqliteOsClose(OsFile*); int sqliteOsRead(OsFile*, void*, int amt); int sqliteOsWrite(OsFile*, const void*, int amt); -int sqliteOsSeek(OsFile*, int offset); +int sqliteOsSeek(OsFile*, off_t offset); int sqliteOsSync(OsFile*); -int sqliteOsTruncate(OsFile*, int size); -int sqliteOsFileSize(OsFile*, int *pSize); +int sqliteOsTruncate(OsFile*, off_t size); +int sqliteOsFileSize(OsFile*, off_t *pSize); int sqliteOsReadLock(OsFile*); int sqliteOsWriteLock(OsFile*); int sqliteOsUnlock(OsFile*); diff --git a/src/pager.c b/src/pager.c index 73b0673569..f68d817727 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.53 2002/09/05 19:10:33 drh Exp $ +** @(#) $Id: pager.c,v 1.54 2002/11/05 23:03:03 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" @@ -106,7 +106,8 @@ struct Pager { OsFile cpfd; /* File descriptor for the checkpoint journal */ int dbSize; /* Number of pages in the file */ int origDbSize; /* dbSize before the current change */ - int ckptSize, ckptJSize; /* Size of database and journal at ckpt_begin() */ + int ckptSize; /* Size of database (in pages) at ckpt_begin() */ + off_t ckptJSize; /* Size of journal at ckpt_begin() */ int nExtra; /* Add this many bytes to each in-memory page */ void (*xDestructor)(void*); /* Call this routine when freeing pages */ int nPage; /* Total number of in-memory pages */ @@ -381,7 +382,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd){ ** works, then this routine returns SQLITE_OK. */ static int pager_playback(Pager *pPager){ - int nRec; /* Number of Records */ + off_t nRec; /* Number of Records */ int i; /* Loop counter */ Pgno mxPg = 0; /* Size of the original file in pages */ unsigned char aMagic[sizeof(aJournalMagic)]; @@ -396,10 +397,10 @@ static int pager_playback(Pager *pPager){ if( rc!=SQLITE_OK ){ goto end_playback; } - nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord); - if( nRec<=0 ){ + if( nRec <= sizeof(aMagic)+sizeof(Pgno) ){ goto end_playback; } + nRec = (nRec - (sizeof(aMagic)+sizeof(Pgno))) / sizeof(PageRecord); /* Read the beginning of the journal and truncate the ** database file back to its original size. @@ -421,7 +422,7 @@ static int pager_playback(Pager *pPager){ if( rc!=SQLITE_OK ){ goto end_playback; } - rc = sqliteOsTruncate(&pPager->fd, mxPg*SQLITE_PAGE_SIZE); + rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)mxPg); if( rc!=SQLITE_OK ){ goto end_playback; } @@ -460,13 +461,13 @@ end_playback: ** at offset pPager->ckptJSize. */ static int pager_ckpt_playback(Pager *pPager){ - int nRec; /* Number of Records */ + off_t nRec; /* Number of Records */ int i; /* Loop counter */ int rc; /* Truncate the database back to its original size. */ - rc = sqliteOsTruncate(&pPager->fd, pPager->ckptSize*SQLITE_PAGE_SIZE); + rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)pPager->ckptSize); pPager->dbSize = pPager->ckptSize; /* Figure out how many records are in the checkpoint journal. @@ -651,7 +652,7 @@ void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){ ** pPager. */ int sqlitepager_pagecount(Pager *pPager){ - int n; + off_t n; assert( pPager!=0 ); if( pPager->dbSize>=0 ){ return pPager->dbSize; @@ -1003,7 +1004,7 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){ sqliteOsSeek(&pPager->fd, (pgno-1)*SQLITE_PAGE_SIZE); rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE); if( rc!=SQLITE_OK ){ - int fileSize; + off_t fileSize; if( sqliteOsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK || fileSize>=pgno*SQLITE_PAGE_SIZE ){ return rc;