Modify the crash-recovery test code in test6.c for 3.5. Also change some other code to use the new sqlite3_io_methods interface. Lots of things are broken now. (CVS 4228)

FossilOrigin-Name: af9503daf3f7703fcddad754bc1dc9e179830b6e
This commit is contained in:
danielk1977 2007-08-15 17:08:46 +00:00
parent 4c3645c601
commit 6207906027
10 changed files with 717 additions and 731 deletions

View File

@ -1,5 +1,5 @@
C Add\sa\sdebugging\smemory\sallocator.\s(CVS\s4227) C Modify\sthe\scrash-recovery\stest\scode\sin\stest6.c\sfor\s3.5.\sAlso\schange\ssome\sother\scode\sto\suse\sthe\snew\ssqlite3_io_methods\sinterface.\sLots\sof\sthings\sare\sbroken\snow.\s(CVS\s4228)
D 2007-08-15T17:07:57 D 2007-08-15T17:08:46
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -91,18 +91,18 @@ F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c ef73642a171d174cd556d0168f8edbceaf94933b F src/mem1.c ef73642a171d174cd556d0168f8edbceaf94933b
F src/mem2.c b8173ddcca23e99829617185154a35a6f046b214 F src/mem2.c b8173ddcca23e99829617185154a35a6f046b214
F src/mutex.c 667dae0de95f8fb92a3ffc8c3f20c0d26115a1a6 F src/mutex.c 667dae0de95f8fb92a3ffc8c3f20c0d26115a1a6
F src/os.c 1f10b47acc1177fb9225edb4f5f0d25ed716f9cb F src/os.c e2faefbe0f5a8ca5e3b1c49ee1b5c6cfa0f0e279
F src/os.h cea2e179bb33f4fc09dbb9fcd51b2246544bd2db F src/os.h 8eff07babf74e5bc3f895f8a6c7c294dad5ff997
F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446 F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3 F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
F src/os_unix.c 9d2a421acc607262e63ccf31e3fe86e5f2520af6 F src/os_unix.c 05ad65c32b4937fd47b17b472955aa5dfc438074
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c cdf561d3ae4009be902df714da4518dc3522e206 F src/pager.c 05ea9dcbc4de4e9d9ca332ca1f8a9ba65fe2cbf5
F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
F src/parse.y ad2ce25665be7f7303137f774a4e3e72e0d036ff F src/parse.y ad2ce25665be7f7303137f774a4e3e72e0d036ff
F src/pragma.c 7914a6b9ea05f158800116dfcae11e52ab8e39c4 F src/pragma.c 7914a6b9ea05f158800116dfcae11e52ab8e39c4
@ -112,18 +112,18 @@ F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
F src/select.c 3b167744fc375bddfddcef87feb18f5171737677 F src/select.c 3b167744fc375bddfddcef87feb18f5171737677
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
F src/sqlite.h.in 025e9fd6c519f2945296a9db46ca9da4571c22d7 F src/sqlite.h.in 165913eb3426fbaa8a2a51d87f84593bfe5bee15
F src/sqlite3ext.h a27bedc222df5e5f0f458ac99726d0483b953a91 F src/sqlite3ext.h a27bedc222df5e5f0f458ac99726d0483b953a91
F src/sqliteInt.h fc9f6e8d916e182c04983a089c4ce4057fac5003 F src/sqliteInt.h fc9f6e8d916e182c04983a089c4ce4057fac5003
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
F src/table.c a8de75bcedf84d4060d804264b067ab3b1a3561d F src/table.c a8de75bcedf84d4060d804264b067ab3b1a3561d
F src/tclsqlite.c 648e6f53041ce4974234d4963e71680926760925 F src/tclsqlite.c 648e6f53041ce4974234d4963e71680926760925
F src/test1.c 94bd41c24a4d8d782e39c1275421511587d8b293 F src/test1.c 94bd41c24a4d8d782e39c1275421511587d8b293
F src/test2.c 24458b17ab2f3c90cbc1c8446bd7ffe69be62f88 F src/test2.c 5c3edc610852a8f67990cd08c5d5dbb79e3f8db9
F src/test3.c a280931fb40222b7c90da45eea926459beee8904 F src/test3.c a280931fb40222b7c90da45eea926459beee8904
F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25 F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
F src/test5.c c40a4cf43266c1c6da7bcb737d294304a177e6cc F src/test5.c c40a4cf43266c1c6da7bcb737d294304a177e6cc
F src/test6.c 2c4ed21787944bd8896cba80d4a544d8bed5473e F src/test6.c 4d812a5ea1fe08693f4189bfc974b341102a3bea
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3 F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
F src/test8.c 27a61c60f736066646a9e9ca21acdfdf0f3ea11e F src/test8.c 27a61c60f736066646a9e9ca21acdfdf0f3ea11e
F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
@ -147,7 +147,7 @@ F src/vdbe.c cf973bd1af5fbda845b0f759bb06eb19ff42e215
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
F src/vdbeInt.h c3514903cad9e36d6b3242be20261351d09db56c F src/vdbeInt.h c3514903cad9e36d6b3242be20261351d09db56c
F src/vdbeapi.c 220b81132abaf0f620edb8da48799a77daef12a7 F src/vdbeapi.c 220b81132abaf0f620edb8da48799a77daef12a7
F src/vdbeaux.c d626e0f8cd78b4280bcb7af25d5c5566348ba87a F src/vdbeaux.c 8e6dbe3dac3bdd7d37c87ba553059b5251ba07e5
F src/vdbeblob.c bb30b3e387c35ba869949494b2736aff97159470 F src/vdbeblob.c bb30b3e387c35ba869949494b2736aff97159470
F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
F src/vdbemem.c ca4d3994507cb0a9504820293af69f5c778b4abd F src/vdbemem.c ca4d3994507cb0a9504820293af69f5c778b4abd
@ -528,7 +528,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P c0fa3769790af199a4c8715c80bb8ff900730520 P 8d2d1c4ff9dca61f75e3048107ee9712d346a28c
R afa459b840a3b96de70924b91a0e1dbb R 7d9819ae0c3408fa1555b7b8d9a48850
U drh U danielk1977
Z 9341f1481e29775e7a036e24546ed5fc Z 41f21c80ce49e631fe5dbf7930bb9145

View File

@ -1 +1 @@
8d2d1c4ff9dca61f75e3048107ee9712d346a28c af9503daf3f7703fcddad754bc1dc9e179830b6e

View File

@ -20,63 +20,65 @@
/* /*
** The following routines are convenience wrappers around methods ** The following routines are convenience wrappers around methods
** of the OsFile object. This is mostly just syntactic sugar. All ** of the sqlite3_file object. This is mostly just syntactic sugar. All
** of this would be completely automatic if SQLite were coded using ** of this would be completely automatic if SQLite were coded using
** C++ instead of plain old C. ** C++ instead of plain old C.
*/ */
int sqlite3OsClose(OsFile **pId){ int sqlite3OsClose(sqlite3_file **pId){
OsFile *id; int rc = SQLITE_OK;
sqlite3_file *id;
if( pId!=0 && (id = *pId)!=0 ){ if( pId!=0 && (id = *pId)!=0 ){
return id->pMethod->xClose(pId); rc = id->pMethods->xClose(id);
}else{ if( rc==SQLITE_OK ){
return SQLITE_OK; *pId = 0;
}
} }
return rc;
} }
int sqlite3OsOpenDirectory(OsFile *id, const char *zName){ int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
return id->pMethod->xOpenDirectory(id, zName); return id->pMethods->xRead(id, pBuf, amt, offset);
} }
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
return id->pMethod->xRead(id, pBuf, amt); return id->pMethods->xWrite(id, pBuf, amt, offset);
} }
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ int sqlite3OsTruncate(sqlite3_file *id, i64 size){
return id->pMethod->xWrite(id, pBuf, amt); return id->pMethods->xTruncate(id, size);
} }
int sqlite3OsSeek(OsFile *id, i64 offset){ int sqlite3OsSync(sqlite3_file *id, int fullsync){
return id->pMethod->xSeek(id, offset); return id->pMethods->xSync(id, fullsync);
} }
int sqlite3OsTruncate(OsFile *id, i64 size){ int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
return id->pMethod->xTruncate(id, size); return id->pMethods->xFileSize(id, pSize);
} }
int sqlite3OsSync(OsFile *id, int fullsync){ int sqlite3OsLock(sqlite3_file *id, int lockType){
return id->pMethod->xSync(id, fullsync); return id->pMethods->xLock(id, lockType);
} }
void sqlite3OsSetFullSync(OsFile *id, int value){ int sqlite3OsUnlock(sqlite3_file *id, int lockType){
id->pMethod->xSetFullSync(id, value); return id->pMethods->xUnlock(id, lockType);
} }
int sqlite3OsFileSize(OsFile *id, i64 *pSize){ int sqlite3OsBreakLock(sqlite3_file *id){
return id->pMethod->xFileSize(id, pSize); return id->pMethods->xBreakLock(id);
} }
int sqlite3OsLock(OsFile *id, int lockType){ int sqlite3OsCheckReservedLock(sqlite3_file *id){
return id->pMethod->xLock(id, lockType); return id->pMethods->xCheckReservedLock(id);
} }
int sqlite3OsUnlock(OsFile *id, int lockType){ int sqlite3OsSectorSize(sqlite3_file *id){
return id->pMethod->xUnlock(id, lockType); int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
}
int sqlite3OsCheckReservedLock(OsFile *id){
return id->pMethod->xCheckReservedLock(id);
}
int sqlite3OsSectorSize(OsFile *id){
int (*xSectorSize)(OsFile*) = id->pMethod->xSectorSize;
return xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE; return xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE;
} }
int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
return id->pMethods->xDeviceCharacteristics(id);
}
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/* These methods are currently only used for testing and debugging. */ /* These methods are currently only used for testing and debugging. */
int sqlite3OsFileHandle(OsFile *id){ int sqlite3OsFileHandle(sqlite3_file *id){
return id->pMethod->xFileHandle(id); /* return id->pMethods->xFileHandle(id); */
return 0;
} }
int sqlite3OsLockState(OsFile *id){ int sqlite3OsLockState(sqlite3_file *id){
return id->pMethod->xLockState(id); /* return id->pMethods->xLockState(id); */
return 0;
} }
#endif #endif

View File

@ -348,27 +348,28 @@ extern unsigned int sqlite3_pending_byte;
/* /*
** Prototypes for operating system interface routines. ** Prototypes for operating system interface routines.
*/ */
int sqlite3OsClose(OsFile**); int sqlite3OsClose(sqlite3_file**);
int sqlite3OsOpenDirectory(OsFile*, const char*); int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
int sqlite3OsWrite(OsFile*, const void*, int amt); int sqlite3OsTruncate(sqlite3_file*, i64 size);
int sqlite3OsSeek(OsFile*, i64 offset); int sqlite3OsSync(sqlite3_file*, int);
int sqlite3OsTruncate(OsFile*, i64 size); int sqlite3OsFileSize(sqlite3_file*, i64 *pSize);
int sqlite3OsSync(OsFile*, int); int sqlite3OsLock(sqlite3_file*, int);
void sqlite3OsSetFullSync(OsFile *id, int setting); int sqlite3OsUnlock(sqlite3_file*, int);
int sqlite3OsFileSize(OsFile*, i64 *pSize); int sqlite3OsBreakLock(sqlite3_file*);
int sqlite3OsLock(OsFile*, int); int sqlite3OsCheckReservedLock(sqlite3_file *id);
int sqlite3OsUnlock(OsFile*, int); int sqlite3OsSectorSize(sqlite3_file *id);
int sqlite3OsCheckReservedLock(OsFile *id); int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
int sqlite3OsOpenReadWrite(const char*, OsFile**, int*);
int sqlite3OsOpenExclusive(const char*, OsFile**, int); int sqlite3OsOpenReadWrite(const char*, sqlite3_file**, int*);
int sqlite3OsOpenReadOnly(const char*, OsFile**); int sqlite3OsOpenExclusive(const char*, sqlite3_file**, int);
int sqlite3OsOpenReadOnly(const char*, sqlite3_file**);
int sqlite3OsDelete(const char*); int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*); int sqlite3OsFileExists(const char*);
char *sqlite3OsFullPathname(const char*); char *sqlite3OsFullPathname(const char*);
int sqlite3OsIsDirWritable(char*); int sqlite3OsIsDirWritable(char*);
int sqlite3OsSyncDirectory(const char*); int sqlite3OsSyncDirectory(const char*);
int sqlite3OsSectorSize(OsFile *id);
int sqlite3OsTempFileName(char*); int sqlite3OsTempFileName(char*);
int sqlite3OsRandomSeed(char*); int sqlite3OsRandomSeed(char*);
int sqlite3OsSleep(int ms); int sqlite3OsSleep(int ms);
@ -386,8 +387,8 @@ void *sqlite3OsDlsym(void*, const char*);
int sqlite3OsDlclose(void*); int sqlite3OsDlclose(void*);
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
int sqlite3OsFileHandle(OsFile *id); int sqlite3OsFileHandle(sqlite3_file *id);
int sqlite3OsLockState(OsFile *id); int sqlite3OsLockState(sqlite3_file *id);
#endif #endif
/* /*
@ -409,9 +410,9 @@ int sqlite3OsDlclose(void*);
** operating system interfaces or behaviors. ** operating system interfaces or behaviors.
*/ */
struct sqlite3OsVtbl { struct sqlite3OsVtbl {
int (*xOpenReadWrite)(const char*, OsFile**, int*); int (*xOpenReadWrite)(const char*, sqlite3_file**, int*);
int (*xOpenExclusive)(const char*, OsFile**, int); int (*xOpenExclusive)(const char*, sqlite3_file**, int);
int (*xOpenReadOnly)(const char*, OsFile**); int (*xOpenReadOnly)(const char*, sqlite3_file**);
int (*xDelete)(const char*); int (*xDelete)(const char*);
int (*xFileExists)(const char*); int (*xFileExists)(const char*);

View File

@ -82,7 +82,7 @@
*/ */
typedef struct unixFile unixFile; typedef struct unixFile unixFile;
struct unixFile { struct unixFile {
IoMethod const *pMethod; /* Always the first entry */ sqlite3_io_methods const *pMethod; /* Always the first entry */
struct openCnt *pOpen; /* Info about all open fd's on this inode */ struct openCnt *pOpen; /* Info about all open fd's on this inode */
struct lockInfo *pLock; /* Info about locks on this inode */ struct lockInfo *pLock; /* Info about locks on this inode */
#ifdef SQLITE_ENABLE_LOCKING_STYLE #ifdef SQLITE_ENABLE_LOCKING_STYLE
@ -99,6 +99,7 @@ struct unixFile {
#endif #endif
}; };
/* /*
** Provide the ability to override some OS-layer functions during ** Provide the ability to override some OS-layer functions during
** testing. This is used to simulate OS crashes to verify that ** testing. This is used to simulate OS crashes to verify that
@ -106,13 +107,15 @@ struct unixFile {
*/ */
#ifdef SQLITE_CRASH_TEST #ifdef SQLITE_CRASH_TEST
extern int sqlite3CrashTestEnable; extern int sqlite3CrashTestEnable;
extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*); int sqlite3CrashFileWrap(sqlite3_file *, const char *, sqlite3_file **);
extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int); static int CRASH_TEST_OVERRIDE(const char *zFile, sqlite3_file **pId, int rc){
extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int); if( rc==SQLITE_OK && sqlite3CrashTestEnable ){
# define CRASH_TEST_OVERRIDE(X,A,B,C) \ rc = sqlite3CrashFileWrap(*pId, zFile, pId);
if(sqlite3CrashTestEnable){ return X(A,B,C); } }
return rc;
}
#else #else
# define CRASH_TEST_OVERRIDE(X,A,B,C) /* no-op */ # define CRASH_TEST_OVERRIDE(A,B,C) C
#endif #endif
@ -801,7 +804,7 @@ int sqlite3UnixFileExists(const char *zFilename){
/* Forward declaration */ /* Forward declaration */
static int allocateUnixFile( static int allocateUnixFile(
int h, /* File descriptor of the open file */ int h, /* File descriptor of the open file */
OsFile **pId, /* Write the real file descriptor here */ sqlite3_file **pId, /* Write the real file descriptor here */
const char *zFilename, /* Name of the file being opened */ const char *zFilename, /* Name of the file being opened */
int delFlag /* If true, make sure the file deletes on close */ int delFlag /* If true, make sure the file deletes on close */
); );
@ -821,12 +824,11 @@ static int allocateUnixFile(
*/ */
int sqlite3UnixOpenReadWrite( int sqlite3UnixOpenReadWrite(
const char *zFilename, const char *zFilename,
OsFile **pId, sqlite3_file **pId,
int *pReadonly int *pReadonly
){ ){
int h; int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
assert( 0==*pId ); assert( 0==*pId );
h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
SQLITE_DEFAULT_FILE_PERMISSIONS); SQLITE_DEFAULT_FILE_PERMISSIONS);
@ -844,7 +846,10 @@ int sqlite3UnixOpenReadWrite(
}else{ }else{
*pReadonly = 0; *pReadonly = 0;
} }
return allocateUnixFile(h, pId, zFilename, 0);
return CRASH_TEST_OVERRIDE(
zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
);
} }
@ -862,10 +867,13 @@ int sqlite3UnixOpenReadWrite(
** **
** On failure, return SQLITE_CANTOPEN. ** On failure, return SQLITE_CANTOPEN.
*/ */
int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ int sqlite3UnixOpenExclusive(
const char *zFilename,
sqlite3_file **pId,
int delFlag
){
int h; int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
assert( 0==*pId ); assert( 0==*pId );
h = open(zFilename, h = open(zFilename,
O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
@ -873,7 +881,9 @@ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
if( h<0 ){ if( h<0 ){
return SQLITE_CANTOPEN; return SQLITE_CANTOPEN;
} }
return allocateUnixFile(h, pId, zFilename, delFlag); return CRASH_TEST_OVERRIDE(
zFilename, pId, allocateUnixFile(h, pId, zFilename, delFlag)
);
} }
/* /*
@ -883,16 +893,17 @@ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
** **
** On failure, return SQLITE_CANTOPEN. ** On failure, return SQLITE_CANTOPEN.
*/ */
int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){ int sqlite3UnixOpenReadOnly(const char *zFilename, sqlite3_file **pId){
int h; int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
assert( 0==*pId ); assert( 0==*pId );
h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
if( h<0 ){ if( h<0 ){
return SQLITE_CANTOPEN; return SQLITE_CANTOPEN;
} }
return allocateUnixFile(h, pId, zFilename, 0); return CRASH_TEST_OVERRIDE(
zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
);
} }
/* /*
@ -994,29 +1005,26 @@ int sqlite3UnixIsDirWritable(char *zBuf){
** Seek to the offset in id->offset then read cnt bytes into pBuf. ** Seek to the offset in id->offset then read cnt bytes into pBuf.
** Return the number of bytes actually read. Update the offset. ** Return the number of bytes actually read. Update the offset.
*/ */
static int seekAndRead(unixFile *id, void *pBuf, int cnt){ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
int got; int got;
i64 newOffset; i64 newOffset;
TIMER_START; TIMER_START;
#if defined(USE_PREAD) #if defined(USE_PREAD)
got = pread(id->h, pBuf, cnt, id->offset); got = pread(id->h, pBuf, cnt, offset);
SimulateIOError( got = -1 ); SimulateIOError( got = -1 );
#elif defined(USE_PREAD64) #elif defined(USE_PREAD64)
got = pread64(id->h, pBuf, cnt, id->offset); got = pread64(id->h, pBuf, cnt, offset);
SimulateIOError( got = -1 ); SimulateIOError( got = -1 );
#else #else
newOffset = lseek(id->h, id->offset, SEEK_SET); newOffset = lseek(id->h, offset, SEEK_SET);
SimulateIOError( newOffset-- ); SimulateIOError( newOffset-- );
if( newOffset!=id->offset ){ if( newOffset!=offset ){
return -1; return -1;
} }
got = read(id->h, pBuf, cnt); got = read(id->h, pBuf, cnt);
#endif #endif
TIMER_END; TIMER_END;
OSTRACE5("READ %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED); OSTRACE5("READ %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED);
if( got>0 ){
id->offset += got;
}
return got; return got;
} }
@ -1025,10 +1033,15 @@ static int seekAndRead(unixFile *id, void *pBuf, int cnt){
** bytes were read successfully and SQLITE_IOERR if anything goes ** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong. ** wrong.
*/ */
static int unixRead(OsFile *id, void *pBuf, int amt){ static int unixRead(
sqlite3_file *id,
void *pBuf,
int amt,
sqlite3_int64 offset
){
int got; int got;
assert( id ); assert( id );
got = seekAndRead((unixFile*)id, pBuf, amt); got = seekAndRead((unixFile*)id, offset, pBuf, amt);
if( got==amt ){ if( got==amt ){
return SQLITE_OK; return SQLITE_OK;
}else if( got<0 ){ }else if( got<0 ){
@ -1043,26 +1056,23 @@ static int unixRead(OsFile *id, void *pBuf, int amt){
** Seek to the offset in id->offset then read cnt bytes into pBuf. ** Seek to the offset in id->offset then read cnt bytes into pBuf.
** Return the number of bytes actually read. Update the offset. ** Return the number of bytes actually read. Update the offset.
*/ */
static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
int got; int got;
i64 newOffset; i64 newOffset;
TIMER_START; TIMER_START;
#if defined(USE_PREAD) #if defined(USE_PREAD)
got = pwrite(id->h, pBuf, cnt, id->offset); got = pwrite(id->h, pBuf, cnt, offset);
#elif defined(USE_PREAD64) #elif defined(USE_PREAD64)
got = pwrite64(id->h, pBuf, cnt, id->offset); got = pwrite64(id->h, pBuf, cnt, offset);
#else #else
newOffset = lseek(id->h, id->offset, SEEK_SET); newOffset = lseek(id->h, offset, SEEK_SET);
if( newOffset!=id->offset ){ if( newOffset!=offset ){
return -1; return -1;
} }
got = write(id->h, pBuf, cnt); got = write(id->h, pBuf, cnt);
#endif #endif
TIMER_END; TIMER_END;
OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED); OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
if( got>0 ){
id->offset += got;
}
return got; return got;
} }
@ -1071,12 +1081,18 @@ static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){
** Write data from a buffer into a file. Return SQLITE_OK on success ** Write data from a buffer into a file. Return SQLITE_OK on success
** or some other error code on failure. ** or some other error code on failure.
*/ */
static int unixWrite(OsFile *id, const void *pBuf, int amt){ static int unixWrite(
sqlite3_file *id,
const void *pBuf,
int amt,
sqlite3_int64 offset
){
int wrote = 0; int wrote = 0;
assert( id ); assert( id );
assert( amt>0 ); assert( amt>0 );
while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){ while( amt>0 && (wrote = seekAndWrite((unixFile*)id, offset, pBuf, amt))>0 ){
amt -= wrote; amt -= wrote;
offset += wrote;
pBuf = &((char*)pBuf)[wrote]; pBuf = &((char*)pBuf)[wrote];
} }
SimulateIOError(( wrote=(-1), amt=1 )); SimulateIOError(( wrote=(-1), amt=1 ));
@ -1205,7 +1221,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
** the directory entry for the journal was never created) and the transaction ** the directory entry for the journal was never created) and the transaction
** will not roll back - possibly leading to database corruption. ** will not roll back - possibly leading to database corruption.
*/ */
static int unixSync(OsFile *id, int dataOnly){ static int unixSync(sqlite3_file *id, int dataOnly){
int rc; int rc;
unixFile *pFile = (unixFile*)id; unixFile *pFile = (unixFile*)id;
assert( pFile ); assert( pFile );
@ -1272,7 +1288,7 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
/* /*
** Truncate an open file to a specified size ** Truncate an open file to a specified size
*/ */
static int unixTruncate(OsFile *id, i64 nByte){ static int unixTruncate(sqlite3_file *id, i64 nByte){
int rc; int rc;
assert( id ); assert( id );
rc = ftruncate(((unixFile*)id)->h, (off_t)nByte); rc = ftruncate(((unixFile*)id)->h, (off_t)nByte);
@ -1287,7 +1303,7 @@ static int unixTruncate(OsFile *id, i64 nByte){
/* /*
** Determine the current size of a file in bytes ** Determine the current size of a file in bytes
*/ */
static int unixFileSize(OsFile *id, i64 *pSize){ static int unixFileSize(sqlite3_file *id, i64 *pSize){
int rc; int rc;
struct stat buf; struct stat buf;
assert( id ); assert( id );
@ -1306,7 +1322,7 @@ static int unixFileSize(OsFile *id, i64 *pSize){
** non-zero. If the file is unlocked or holds only SHARED locks, then ** non-zero. If the file is unlocked or holds only SHARED locks, then
** return zero. ** return zero.
*/ */
static int unixCheckReservedLock(OsFile *id){ static int unixCheckReservedLock(sqlite3_file *id){
int r = 0; int r = 0;
unixFile *pFile = (unixFile*)id; unixFile *pFile = (unixFile*)id;
@ -1362,7 +1378,7 @@ static int unixCheckReservedLock(OsFile *id){
** This routine will only increase a lock. Use the sqlite3OsUnlock() ** This routine will only increase a lock. Use the sqlite3OsUnlock()
** routine to lower a locking level. ** routine to lower a locking level.
*/ */
static int unixLock(OsFile *id, int locktype){ static int unixLock(sqlite3_file *id, int locktype){
/* The following describes the implementation of the various locks and /* The following describes the implementation of the various locks and
** lock transitions in terms of the POSIX advisory shared and exclusive ** lock transitions in terms of the POSIX advisory shared and exclusive
** lock primitives (called read-locks and write-locks below, to avoid ** lock primitives (called read-locks and write-locks below, to avoid
@ -1564,7 +1580,7 @@ end_lock:
** If the locking level of the file descriptor is already at or below ** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op. ** the requested locking level, this routine is a no-op.
*/ */
static int unixUnlock(OsFile *id, int locktype){ static int unixUnlock(sqlite3_file *id, int locktype){
struct lockInfo *pLock; struct lockInfo *pLock;
struct flock lock; struct flock lock;
int rc = SQLITE_OK; int rc = SQLITE_OK;
@ -1650,44 +1666,42 @@ static int unixUnlock(OsFile *id, int locktype){
/* /*
** Close a file. ** Close a file.
*/ */
static int unixClose(OsFile **pId){ static int unixClose(sqlite3_file *id){
unixFile *id = (unixFile*)*pId; unixFile *pFile = (unixFile *)id;
if( !pFile ) return SQLITE_OK;
if( !id ) return SQLITE_OK; unixUnlock(id, NO_LOCK);
unixUnlock(*pId, NO_LOCK); if( pFile->dirfd>=0 ) close(pFile->dirfd);
if( id->dirfd>=0 ) close(id->dirfd); pFile->dirfd = -1;
id->dirfd = -1;
sqlite3OsEnterMutex(); sqlite3OsEnterMutex();
if( id->pOpen->nLock ){ if( pFile->pOpen->nLock ){
/* If there are outstanding locks, do not actually close the file just /* If there are outstanding locks, do not actually close the file just
** yet because that would clear those locks. Instead, add the file ** yet because that would clear those locks. Instead, add the file
** descriptor to pOpen->aPending. It will be automatically closed when ** descriptor to pOpen->aPending. It will be automatically closed when
** the last lock is cleared. ** the last lock is cleared.
*/ */
int *aNew; int *aNew;
struct openCnt *pOpen = id->pOpen; struct openCnt *pOpen = pFile->pOpen;
aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) ); aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
if( aNew==0 ){ if( aNew==0 ){
/* If a malloc fails, just leak the file descriptor */ /* If a malloc fails, just leak the file descriptor */
}else{ }else{
pOpen->aPending = aNew; pOpen->aPending = aNew;
pOpen->aPending[pOpen->nPending] = id->h; pOpen->aPending[pOpen->nPending] = pFile->h;
pOpen->nPending++; pOpen->nPending++;
} }
}else{ }else{
/* There are no outstanding locks so we can close the file immediately */ /* There are no outstanding locks so we can close the file immediately */
close(id->h); close(pFile->h);
} }
releaseLockInfo(id->pLock); releaseLockInfo(pFile->pLock);
releaseOpenCnt(id->pOpen); releaseOpenCnt(pFile->pOpen);
sqlite3OsLeaveMutex(); sqlite3OsLeaveMutex();
id->isOpen = 0; pFile->isOpen = 0;
OSTRACE2("CLOSE %-3d\n", id->h); OSTRACE2("CLOSE %-3d\n", pFile->h);
OpenCounter(-1); OpenCounter(-1);
sqlite3ThreadSafeFree(id); sqlite3ThreadSafeFree(id);
*pId = 0;
return SQLITE_OK; return SQLITE_OK;
} }
@ -2348,30 +2362,37 @@ static int unixLockState(OsFile *id){
** a database and it's journal file) that the sector size will be the ** a database and it's journal file) that the sector size will be the
** same for both. ** same for both.
*/ */
static int unixSectorSize(OsFile *id){ static int unixSectorSize(sqlite3_file *id){
return SQLITE_DEFAULT_SECTOR_SIZE; return SQLITE_DEFAULT_SECTOR_SIZE;
} }
static int unixDeviceCharacteristics(sqlite3_file *id){
return 0;
}
static int unixBreakLock(sqlite3_file *id){
assert(!"TODO: unixBreakLock()");
return 0;
}
/* /*
** This vector defines all the methods that can operate on an OsFile ** This vector defines all the methods that can operate on an OsFile
** for unix. ** for unix.
*/ */
static const IoMethod sqlite3UnixIoMethod = { static const sqlite3_io_methods sqlite3UnixIoMethod = {
1, /* iVersion */
unixClose, unixClose,
unixOpenDirectory,
unixRead, unixRead,
unixWrite, unixWrite,
unixSeek,
unixTruncate, unixTruncate,
unixSync, unixSync,
unixSetFullSync,
unixFileHandle,
unixFileSize, unixFileSize,
unixLock, unixLock,
unixUnlock, unixUnlock,
unixLockState,
unixCheckReservedLock, unixCheckReservedLock,
unixBreakLock,
unixSectorSize, unixSectorSize,
unixDeviceCharacteristics
}; };
#ifdef SQLITE_ENABLE_LOCKING_STYLE #ifdef SQLITE_ENABLE_LOCKING_STYLE
@ -2573,7 +2594,7 @@ static int allocateUnixFile(
#else /* SQLITE_ENABLE_LOCKING_STYLE */ #else /* SQLITE_ENABLE_LOCKING_STYLE */
static int allocateUnixFile( static int allocateUnixFile(
int h, /* Open file descriptor on file being opened */ int h, /* Open file descriptor on file being opened */
OsFile **pId, /* Write the resul unixFile structure here */ sqlite3_file **pId, /* Write the resul unixFile structure here */
const char *zFilename, /* Name of the file being opened */ const char *zFilename, /* Name of the file being opened */
int delFlag /* If true, delete the file on or before closing */ int delFlag /* If true, delete the file on or before closing */
){ ){
@ -2611,7 +2632,7 @@ static int allocateUnixFile(
}else{ }else{
*pNew = f; *pNew = f;
pNew->pMethod = &sqlite3UnixIoMethod; pNew->pMethod = &sqlite3UnixIoMethod;
*pId = (OsFile*)pNew; *pId = (sqlite3_file*)pNew;
OpenCounter(+1); OpenCounter(+1);
return SQLITE_OK; return SQLITE_OK;
} }

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** another is writing.
** **
** @(#) $Id: pager.c,v 1.355 2007/08/11 00:26:21 drh Exp $ ** @(#) $Id: pager.c,v 1.356 2007/08/15 17:08:46 danielk1977 Exp $
*/ */
#ifndef SQLITE_OMIT_DISKIO #ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h" #include "sqliteInt.h"
@ -50,7 +50,7 @@
** to print out file-descriptors. ** to print out file-descriptors.
** **
** PAGERID() takes a pointer to a Pager struct as it's argument. The ** PAGERID() takes a pointer to a Pager struct as it's argument. The
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
** struct as it's argument. ** struct as it's argument.
*/ */
#define PAGERID(p) ((int)(p->fd)) #define PAGERID(p) ((int)(p->fd))
@ -336,8 +336,8 @@ struct Pager {
char *zFilename; /* Name of the database file */ char *zFilename; /* Name of the database file */
char *zJournal; /* Name of the journal file */ char *zJournal; /* Name of the journal file */
char *zDirectory; /* Directory hold database and journal files */ char *zDirectory; /* Directory hold database and journal files */
OsFile *fd, *jfd; /* File descriptors for database and journal */ sqlite3_file *fd, *jfd; /* File descriptors for database and journal */
OsFile *stfd; /* File descriptor for the statement subjournal*/ sqlite3_file *stfd; /* File descriptor for the statement subjournal*/
BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */ BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */
PgHdr *pFirst, *pLast; /* List of free pages */ PgHdr *pFirst, *pLast; /* List of free pages */
PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */ PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
@ -526,9 +526,9 @@ static void pager_resize_hash_table(Pager *pPager, int N){
** **
** All values are stored on disk as big-endian. ** All values are stored on disk as big-endian.
*/ */
static int read32bits(OsFile *fd, u32 *pRes){ static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
unsigned char ac[4]; unsigned char ac[4];
int rc = sqlite3OsRead(fd, ac, sizeof(ac)); int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
*pRes = sqlite3Get4byte(ac); *pRes = sqlite3Get4byte(ac);
} }
@ -544,10 +544,10 @@ static int read32bits(OsFile *fd, u32 *pRes){
** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK ** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK
** on success or an error code is something goes wrong. ** on success or an error code is something goes wrong.
*/ */
static int write32bits(OsFile *fd, u32 val){ static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
char ac[4]; char ac[4];
put32bits(ac, val); put32bits(ac, val);
return sqlite3OsWrite(fd, ac, 4); return sqlite3OsWrite(fd, ac, 4, offset);
} }
/* /*
@ -627,7 +627,7 @@ static void checkPage(PgHdr *pPg){
** If no master journal file name is present *pzMaster is set to 0 and ** If no master journal file name is present *pzMaster is set to 0 and
** SQLITE_OK returned. ** SQLITE_OK returned.
*/ */
static int readMasterJournal(OsFile *pJrnl, char **pzMaster){ static int readMasterJournal(sqlite3_file *pJrnl, char **pzMaster){
int rc; int rc;
u32 len; u32 len;
i64 szJ; i64 szJ;
@ -640,26 +640,20 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
rc = sqlite3OsFileSize(pJrnl, &szJ); rc = sqlite3OsFileSize(pJrnl, &szJ);
if( rc!=SQLITE_OK || szJ<16 ) return rc; if( rc!=SQLITE_OK || szJ<16 ) return rc;
rc = sqlite3OsSeek(pJrnl, szJ-16); rc = read32bits(pJrnl, szJ-16, &len);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
rc = read32bits(pJrnl, &len); rc = read32bits(pJrnl, szJ-12, &cksum);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
rc = read32bits(pJrnl, &cksum); rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8);
if( rc!=SQLITE_OK ) return rc;
rc = sqlite3OsRead(pJrnl, aMagic, 8);
if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc; if( rc!=SQLITE_OK || memcmp(aMagic, aJournalMagic, 8) ) return rc;
rc = sqlite3OsSeek(pJrnl, szJ-16-len);
if( rc!=SQLITE_OK ) return rc;
*pzMaster = (char *)sqliteMalloc(len+1); *pzMaster = (char *)sqliteMalloc(len+1);
if( !*pzMaster ){ if( !*pzMaster ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
rc = sqlite3OsRead(pJrnl, *pzMaster, len); rc = sqlite3OsRead(pJrnl, *pzMaster, len, szJ-16-len);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
sqliteFree(*pzMaster); sqliteFree(*pzMaster);
*pzMaster = 0; *pzMaster = 0;
@ -700,7 +694,7 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
** 2000 2048 ** 2000 2048
** **
*/ */
static int seekJournalHdr(Pager *pPager){ static void seekJournalHdr(Pager *pPager){
i64 offset = 0; i64 offset = 0;
i64 c = pPager->journalOff; i64 c = pPager->journalOff;
if( c ){ if( c ){
@ -710,7 +704,6 @@ static int seekJournalHdr(Pager *pPager){
assert( offset>=c ); assert( offset>=c );
assert( (offset-c)<JOURNAL_HDR_SZ(pPager) ); assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
pPager->journalOff = offset; pPager->journalOff = offset;
return sqlite3OsSeek(pPager->jfd, pPager->journalOff);
} }
/* /*
@ -735,11 +728,8 @@ static int writeJournalHdr(Pager *pPager){
pPager->stmtHdrOff = pPager->journalOff; pPager->stmtHdrOff = pPager->journalOff;
} }
rc = seekJournalHdr(pPager); seekJournalHdr(pPager);
if( rc ) return rc;
pPager->journalHdr = pPager->journalOff; pPager->journalHdr = pPager->journalOff;
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
/* FIX ME: /* FIX ME:
** **
@ -760,17 +750,15 @@ static int writeJournalHdr(Pager *pPager){
/* The assumed sector size for this process */ /* The assumed sector size for this process */
put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader))) IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, sizeof(zHeader)))
rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader)); rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader),pPager->journalOff);
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
/* The journal header has been written successfully. Seek the journal /* The journal header has been written successfully. Seek the journal
** file descriptor to the end of the journal header sector. ** file descriptor to the end of the journal header sector.
*/ */
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1)) IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1))
rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1); rc = sqlite3OsWrite(pPager->jfd, "\000", 1, pPager->journalOff-1);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->jfd, "\000", 1);
}
} }
return rc; return rc;
} }
@ -799,28 +787,29 @@ static int readJournalHdr(
){ ){
int rc; int rc;
unsigned char aMagic[8]; /* A buffer to hold the magic header */ unsigned char aMagic[8]; /* A buffer to hold the magic header */
i64 jrnlOff;
rc = seekJournalHdr(pPager); seekJournalHdr(pPager);
if( rc ) return rc;
if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
return SQLITE_DONE; return SQLITE_DONE;
} }
jrnlOff = pPager->journalOff;
rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic)); rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), jrnlOff);
if( rc ) return rc; if( rc ) return rc;
jrnlOff += sizeof(aMagic);
if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
return SQLITE_DONE; return SQLITE_DONE;
} }
rc = read32bits(pPager->jfd, pNRec); rc = read32bits(pPager->jfd, jrnlOff, pNRec);
if( rc ) return rc; if( rc ) return rc;
rc = read32bits(pPager->jfd, &pPager->cksumInit); rc = read32bits(pPager->jfd, jrnlOff+4, &pPager->cksumInit);
if( rc ) return rc; if( rc ) return rc;
rc = read32bits(pPager->jfd, pDbSize); rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
if( rc ) return rc; if( rc ) return rc;
/* Update the assumed sector-size to match the value used by /* Update the assumed sector-size to match the value used by
@ -829,12 +818,11 @@ static int readJournalHdr(
** is being called from within pager_playback(). The local value ** is being called from within pager_playback(). The local value
** of Pager.sectorSize is restored at the end of that routine. ** of Pager.sectorSize is restored at the end of that routine.
*/ */
rc = read32bits(pPager->jfd, (u32 *)&pPager->sectorSize); rc = read32bits(pPager->jfd, jrnlOff+12, (u32 *)&pPager->sectorSize);
if( rc ) return rc; if( rc ) return rc;
pPager->journalOff += JOURNAL_HDR_SZ(pPager); pPager->journalOff += JOURNAL_HDR_SZ(pPager);
rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff); return SQLITE_OK;
return rc;
} }
@ -861,6 +849,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
int rc; int rc;
int len; int len;
int i; int i;
i64 jrnlOff;
u32 cksum = 0; u32 cksum = 0;
char zBuf[sizeof(aJournalMagic)+2*4]; char zBuf[sizeof(aJournalMagic)+2*4];
@ -877,21 +866,23 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
** the journal has already been synced. ** the journal has already been synced.
*/ */
if( pPager->fullSync ){ if( pPager->fullSync ){
rc = seekJournalHdr(pPager); seekJournalHdr(pPager);
if( rc!=SQLITE_OK ) return rc;
} }
jrnlOff = pPager->journalOff;
pPager->journalOff += (len+20); pPager->journalOff += (len+20);
rc = write32bits(pPager->jfd, PAGER_MJ_PGNO(pPager)); rc = write32bits(pPager->jfd, jrnlOff, PAGER_MJ_PGNO(pPager));
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
jrnlOff += 4;
rc = sqlite3OsWrite(pPager->jfd, zMaster, len); rc = sqlite3OsWrite(pPager->jfd, zMaster, len, jrnlOff);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
jrnlOff += len;
put32bits(zBuf, len); put32bits(zBuf, len);
put32bits(&zBuf[4], cksum); put32bits(&zBuf[4], cksum);
memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic)); memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic));
rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic)); rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic), jrnlOff);
pPager->needSync = !pPager->noSync; pPager->needSync = !pPager->noSync;
return rc; return rc;
} }
@ -1026,7 +1017,6 @@ static int pager_end_transaction(Pager *pPager){
if( pPager->journalOpen ){ if( pPager->journalOpen ){
if( pPager->exclusiveMode if( pPager->exclusiveMode
&& (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){; && (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){;
sqlite3OsSeek(pPager->jfd, 0);
pPager->journalOff = 0; pPager->journalOff = 0;
pPager->journalStarted = 0; pPager->journalStarted = 0;
}else{ }else{
@ -1111,7 +1101,12 @@ static void makeClean(PgHdr*);
** are not used in statement journals because statement journals do not ** are not used in statement journals because statement journals do not
** need to survive power failures. ** need to survive power failures.
*/ */
static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ static int pager_playback_one_page(
Pager *pPager,
sqlite3_file *jfd,
i64 offset,
int useCksum
){
int rc; int rc;
PgHdr *pPg; /* An existing page in the cache */ PgHdr *pPg; /* An existing page in the cache */
Pgno pgno; /* The page number of a page in journal */ Pgno pgno; /* The page number of a page in journal */
@ -1124,9 +1119,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) ); assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) );
assert( aData ); assert( aData );
rc = read32bits(jfd, &pgno); rc = read32bits(jfd, offset, &pgno);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
rc = sqlite3OsRead(jfd, aData, pPager->pageSize); rc = sqlite3OsRead(jfd, aData, pPager->pageSize, offset+4);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
pPager->journalOff += pPager->pageSize + 4; pPager->journalOff += pPager->pageSize + 4;
@ -1142,7 +1137,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
return SQLITE_OK; return SQLITE_OK;
} }
if( useCksum ){ if( useCksum ){
rc = read32bits(jfd, &cksum); rc = read32bits(jfd, offset+pPager->pageSize+4, &cksum);
if( rc ) return rc; if( rc ) return rc;
pPager->journalOff += 4; pPager->journalOff += 4;
if( pager_cksum(pPager, aData)!=cksum ){ if( pager_cksum(pPager, aData)!=cksum ){
@ -1184,10 +1179,8 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n", PAGERTRACE4("PLAYBACK %d page %d hash(%08x)\n",
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData)); PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData));
if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize); i64 offset = (pgno-1)*(i64)pPager->pageSize;
if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, offset);
rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize);
}
if( pPg ){ if( pPg ){
makeClean(pPg); makeClean(pPg);
} }
@ -1235,7 +1228,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
static int pager_delmaster(const char *zMaster){ static int pager_delmaster(const char *zMaster){
int rc; int rc;
int master_open = 0; int master_open = 0;
OsFile *master = 0; sqlite3_file *master = 0;
char *zMasterJournal = 0; /* Contents of master journal file */ char *zMasterJournal = 0; /* Contents of master journal file */
i64 nMasterJournal; /* Size of master journal file */ i64 nMasterJournal; /* Size of master journal file */
@ -1261,7 +1254,7 @@ static int pager_delmaster(const char *zMaster){
rc = SQLITE_NOMEM; rc = SQLITE_NOMEM;
goto delmaster_out; goto delmaster_out;
} }
rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal); rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal, 0);
if( rc!=SQLITE_OK ) goto delmaster_out; if( rc!=SQLITE_OK ) goto delmaster_out;
zJournal = zMasterJournal; zJournal = zMasterJournal;
@ -1271,7 +1264,7 @@ static int pager_delmaster(const char *zMaster){
** Open it and check if it points at the master journal. If ** Open it and check if it points at the master journal. If
** so, return without deleting the master journal file. ** so, return without deleting the master journal file.
*/ */
OsFile *journal = 0; sqlite3_file *journal = 0;
int c; int c;
rc = sqlite3OsOpenReadOnly(zJournal, &journal); rc = sqlite3OsOpenReadOnly(zJournal, &journal);
@ -1424,7 +1417,6 @@ static int pager_playback(Pager *pPager, int isHot){
if( rc==SQLITE_DONE ) rc = SQLITE_OK; if( rc==SQLITE_DONE ) rc = SQLITE_OK;
goto end_playback; goto end_playback;
} }
sqlite3OsSeek(pPager->jfd, 0);
pPager->journalOff = 0; pPager->journalOff = 0;
/* This loop terminates either when the readJournalHdr() call returns /* This loop terminates either when the readJournalHdr() call returns
@ -1480,7 +1472,7 @@ static int pager_playback(Pager *pPager, int isHot){
/* Copy original pages out of the journal and back into the database file. /* Copy original pages out of the journal and back into the database file.
*/ */
for(i=0; i<nRec; i++){ for(i=0; i<nRec; i++){
rc = pager_playback_one_page(pPager, pPager->jfd, 1); rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
if( rc==SQLITE_DONE ){ if( rc==SQLITE_DONE ){
rc = SQLITE_OK; rc = SQLITE_OK;
@ -1567,7 +1559,6 @@ static int pager_stmt_playback(Pager *pPager){
/* Figure out how many records are in the statement journal. /* Figure out how many records are in the statement journal.
*/ */
assert( pPager->stmtInUse && pPager->journalOpen ); assert( pPager->stmtInUse && pPager->journalOpen );
sqlite3OsSeek(pPager->stfd, 0);
nRec = pPager->stmtNRec; nRec = pPager->stmtNRec;
/* Copy original pages out of the statement journal and back into the /* Copy original pages out of the statement journal and back into the
@ -1575,8 +1566,9 @@ static int pager_stmt_playback(Pager *pPager){
** each record since power-failure recovery is not important to statement ** each record since power-failure recovery is not important to statement
** journals. ** journals.
*/ */
for(i=nRec-1; i>=0; i--){ for(i=0; i<nRec; i++){
rc = pager_playback_one_page(pPager, pPager->stfd, 0); i64 offset = i*(4+pPager->pageSize);
rc = pager_playback_one_page(pPager, pPager->stfd, offset, 0);
assert( rc!=SQLITE_DONE ); assert( rc!=SQLITE_DONE );
if( rc!=SQLITE_OK ) goto end_stmt_playback; if( rc!=SQLITE_OK ) goto end_stmt_playback;
} }
@ -1589,14 +1581,10 @@ static int pager_stmt_playback(Pager *pPager){
** If it is not zero, then Pager.stmtHdrOff is the offset to the start ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
** of the first journal header written during this statement transaction. ** of the first journal header written during this statement transaction.
*/ */
rc = sqlite3OsSeek(pPager->jfd, pPager->stmtJSize);
if( rc!=SQLITE_OK ){
goto end_stmt_playback;
}
pPager->journalOff = pPager->stmtJSize; pPager->journalOff = pPager->stmtJSize;
pPager->cksumInit = pPager->stmtCksum; pPager->cksumInit = pPager->stmtCksum;
while( pPager->journalOff < hdrOff ){ while( pPager->journalOff < hdrOff ){
rc = pager_playback_one_page(pPager, pPager->jfd, 1); rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
assert( rc!=SQLITE_DONE ); assert( rc!=SQLITE_DONE );
if( rc!=SQLITE_OK ) goto end_stmt_playback; if( rc!=SQLITE_OK ) goto end_stmt_playback;
} }
@ -1613,7 +1601,7 @@ static int pager_stmt_playback(Pager *pPager){
nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8); nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
} }
for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){ for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){
rc = pager_playback_one_page(pPager, pPager->jfd, 1); rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
assert( rc!=SQLITE_DONE ); assert( rc!=SQLITE_DONE );
if( rc!=SQLITE_OK ) goto end_stmt_playback; if( rc!=SQLITE_OK ) goto end_stmt_playback;
} }
@ -1693,7 +1681,7 @@ int sqlite3_opentemp_count = 0;
** The OS will automatically delete the temporary file when it is ** The OS will automatically delete the temporary file when it is
** closed. ** closed.
*/ */
static int sqlite3PagerOpentemp(OsFile **pFd){ static int sqlite3PagerOpentemp(sqlite3_file **pFd){
int cnt = 8; int cnt = 8;
int rc; int rc;
char zFile[SQLITE_TEMPNAME_SIZE]; char zFile[SQLITE_TEMPNAME_SIZE];
@ -1733,7 +1721,7 @@ int sqlite3PagerOpen(
Pager *pPager = 0; Pager *pPager = 0;
char *zFullPathname = 0; char *zFullPathname = 0;
int nameLen; /* Compiler is wrong. This is always initialized before use */ int nameLen; /* Compiler is wrong. This is always initialized before use */
OsFile *fd = 0; sqlite3_file *fd = 0;
int rc = SQLITE_OK; int rc = SQLITE_OK;
int i; int i;
int tempFile = 0; int tempFile = 0;
@ -1970,11 +1958,8 @@ int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
int rc = SQLITE_OK; int rc = SQLITE_OK;
memset(pDest, 0, N); memset(pDest, 0, N);
if( MEMDB==0 ){ if( MEMDB==0 ){
disable_simulated_io_errors();
sqlite3OsSeek(pPager->fd, 0);
enable_simulated_io_errors();
IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
rc = sqlite3OsRead(pPager->fd, pDest, N); rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
if( rc==SQLITE_IOERR_SHORT_READ ){ if( rc==SQLITE_IOERR_SHORT_READ ){
rc = SQLITE_OK; rc = SQLITE_OK;
} }
@ -2381,6 +2366,8 @@ static int syncJournal(Pager *pPager){
} }
#endif #endif
{ {
i64 jrnlOff;
/* Write the nRec value into the journal file header. If in /* Write the nRec value into the journal file header. If in
** full-synchronous mode, sync the journal first. This ensures that ** full-synchronous mode, sync the journal first. This ensures that
** all data has really hit the disk before nRec is updated to mark ** all data has really hit the disk before nRec is updated to mark
@ -2392,15 +2379,10 @@ static int syncJournal(Pager *pPager){
rc = sqlite3OsSync(pPager->jfd, 0); rc = sqlite3OsSync(pPager->jfd, 0);
if( rc!=0 ) return rc; if( rc!=0 ) return rc;
} }
rc = sqlite3OsSeek(pPager->jfd,
pPager->journalHdr + sizeof(aJournalMagic));
if( rc ) return rc;
IOTRACE(("JHDR %p %lld %d\n", pPager,
pPager->journalHdr + sizeof(aJournalMagic), 4))
rc = write32bits(pPager->jfd, pPager->nRec);
if( rc ) return rc;
rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff); jrnlOff = pPager->journalHdr + sizeof(aJournalMagic);
IOTRACE(("JHDR %p %lld %d\n", pPager, jrnlOff, 4));
rc = write32bits(pPager->jfd, jrnlOff, pPager->nRec);
if( rc ) return rc; if( rc ) return rc;
} }
PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager)); PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
@ -2545,19 +2527,18 @@ static int pager_write_pagelist(PgHdr *pList){
pList = sort_pagelist(pList); pList = sort_pagelist(pList);
while( pList ){ while( pList ){
assert( pList->dirty ); assert( pList->dirty );
rc = sqlite3OsSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);
if( rc ) return rc;
/* If there are dirty pages in the page cache with page numbers greater /* If there are dirty pages in the page cache with page numbers greater
** than Pager.dbSize, this means sqlite3PagerTruncate() was called to ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
** make the file smaller (presumably by auto-vacuum code). Do not write ** make the file smaller (presumably by auto-vacuum code). Do not write
** any such pages to the file. ** any such pages to the file.
*/ */
if( pList->pgno<=pPager->dbSize ){ if( pList->pgno<=pPager->dbSize ){
i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
PAGERTRACE4("STORE %d page %d hash(%08x)\n", PAGERTRACE4("STORE %d page %d hash(%08x)\n",
PAGERID(pPager), pList->pgno, pager_pagehash(pList)); PAGERID(pPager), pList->pgno, pager_pagehash(pList));
IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno)); IOTRACE(("PGOUT %p %d\n", pPager, pList->pgno));
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize); rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
PAGER_INCR(sqlite3_pager_writedb_count); PAGER_INCR(sqlite3_pager_writedb_count);
PAGER_INCR(pPager->nWrite); PAGER_INCR(pPager->nWrite);
if( pList->pgno==1 ){ if( pList->pgno==1 ){
@ -2796,12 +2777,10 @@ int sqlite3PagerReleaseMemory(int nReq){
*/ */
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){ static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
int rc; int rc;
i64 offset;
assert( MEMDB==0 ); assert( MEMDB==0 );
rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize); offset = (pgno-1)*(i64)pPager->pageSize;
if( rc==SQLITE_OK ){ rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize, offset);
rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg),
pPager->pageSize);
}
PAGER_INCR(sqlite3_pager_readdb_count); PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead); PAGER_INCR(pPager->nRead);
IOTRACE(("PGIN %p %d\n", pPager, pgno)); IOTRACE(("PGIN %p %d\n", pPager, pgno));
@ -2934,11 +2913,7 @@ static int pagerSharedLock(Pager *pPager){
if( pPager->dbSize>0 ){ if( pPager->dbSize>0 ){
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
rc = sqlite3OsSeek(pPager->fd, 24); rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
if( rc!=SQLITE_OK ){
return rc;
}
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers));
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
return rc; return rc;
} }
@ -3332,9 +3307,11 @@ static int pager_open_journal(Pager *pPager){
} }
goto failed_to_open_journal; goto failed_to_open_journal;
} }
#if 0
sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync); sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync); sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync);
sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory); sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
#endif
pPager->journalOpen = 1; pPager->journalOpen = 1;
pPager->journalStarted = 0; pPager->journalStarted = 0;
pPager->needSync = 0; pPager->needSync = 0;
@ -3583,7 +3560,7 @@ static int pager_write(PgHdr *pPg){
put32bits(pEnd, cksum); put32bits(pEnd, cksum);
szPg = pPager->pageSize+8; szPg = pPager->pageSize+8;
put32bits(pData2, pPg->pgno); put32bits(pData2, pPg->pgno);
rc = sqlite3OsWrite(pPager->jfd, pData2, szPg); rc = sqlite3OsWrite(pPager->jfd, pData2, szPg, pPager->journalOff);
IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno,
pPager->journalOff, szPg)); pPager->journalOff, szPg));
PAGER_INCR(sqlite3_pager_writej_count); PAGER_INCR(sqlite3_pager_writej_count);
@ -3638,9 +3615,10 @@ static int pager_write(PgHdr *pPg){
PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
page_add_to_stmt_list(pPg); page_add_to_stmt_list(pPg);
}else{ }else{
i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7)-4; char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7)-4;
put32bits(pData2, pPg->pgno); put32bits(pData2, pPg->pgno);
rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize+4); rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize+4, offset);
PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
return rc; return rc;
@ -4215,7 +4193,6 @@ int sqlite3PagerStmtCommit(Pager *pPager){
PgHdr *pPg, *pNext; PgHdr *pPg, *pNext;
PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
if( !MEMDB ){ if( !MEMDB ){
sqlite3OsSeek(pPager->stfd, 0);
/* sqlite3OsTruncate(pPager->stfd, 0); */ /* sqlite3OsTruncate(pPager->stfd, 0); */
sqliteFree( pPager->aInStmt ); sqliteFree( pPager->aInStmt );
pPager->aInStmt = 0; pPager->aInStmt = 0;

View File

@ -30,7 +30,7 @@
** the version number) and changes its name to "sqlite3.h" as ** the version number) and changes its name to "sqlite3.h" as
** part of the build process. ** part of the build process.
** **
** @(#) $Id: sqlite.h.in,v 1.223 2007/08/15 13:04:54 drh Exp $ ** @(#) $Id: sqlite.h.in,v 1.224 2007/08/15 17:08:46 danielk1977 Exp $
*/ */
#ifndef _SQLITE3_H_ #ifndef _SQLITE3_H_
#define _SQLITE3_H_ #define _SQLITE3_H_
@ -488,7 +488,7 @@ struct sqlite3_io_methods {
int iVersion; int iVersion;
int (*xClose)(sqlite3_file*); int (*xClose)(sqlite3_file*);
int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite_int64 iOfst); int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite_int64 iOfst);
int (*xWrite)(sqlite3_file*, void*, int iAmt, sqlite_int64 iOfst); int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite_int64 iOfst);
int (*xTruncate)(sqlite3_file*, sqlite_int64 size); int (*xTruncate)(sqlite3_file*, sqlite_int64 size);
int (*xSync)(sqlite3_file*, int flags); int (*xSync)(sqlite3_file*, int flags);
int (*xFileSize)(sqlite3_file*, sqlite_int64 *pSize); int (*xFileSize)(sqlite3_file*, sqlite_int64 *pSize);

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test2.c,v 1.43 2007/04/02 05:07:47 danielk1977 Exp $ ** $Id: test2.c,v 1.44 2007/08/15 17:08:46 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@ -546,12 +546,7 @@ static int fake_big_file(
} }
offset = n; offset = n;
offset *= 1024*1024; offset *= 1024*1024;
rc = sqlite3OsSeek(fd, offset); rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
if( rc ){
Tcl_AppendResult(interp, "seek failed: ", errorName(rc), 0);
return TCL_ERROR;
}
rc = sqlite3OsWrite(fd, "Hello, World!", 14);
sqlite3OsClose(&fd); sqlite3OsClose(&fd);
if( rc ){ if( rc ){
Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0); Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);

File diff suppressed because it is too large Load Diff

View File

@ -1129,7 +1129,8 @@ static int vdbeCommit(sqlite3 *db){
int needSync = 0; int needSync = 0;
char *zMaster = 0; /* File-name for the master journal */ char *zMaster = 0; /* File-name for the master journal */
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
OsFile *master = 0; sqlite3_file *master = 0;
i64 offset = 0;
/* Select a master journal file name */ /* Select a master journal file name */
do { do {
@ -1164,7 +1165,8 @@ static int vdbeCommit(sqlite3 *db){
if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
needSync = 1; needSync = 1;
} }
rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1); rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1, offset);
offset += strlen(zFile)+1;
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
sqlite3OsClose(&master); sqlite3OsClose(&master);
sqlite3OsDelete(zMaster); sqlite3OsDelete(zMaster);
@ -1179,6 +1181,7 @@ static int vdbeCommit(sqlite3 *db){
** the master journal file is store in so that it gets synced too. ** the master journal file is store in so that it gets synced too.
*/ */
zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
#if 0
rc = sqlite3OsOpenDirectory(master, zMainFile); rc = sqlite3OsOpenDirectory(master, zMainFile);
if( rc!=SQLITE_OK || if( rc!=SQLITE_OK ||
(needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){ (needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){
@ -1187,6 +1190,7 @@ static int vdbeCommit(sqlite3 *db){
sqliteFree(zMaster); sqliteFree(zMaster);
return rc; return rc;
} }
#endif
/* Sync all the db files involved in the transaction. The same call /* Sync all the db files involved in the transaction. The same call
** sets the master journal pointer in each individual journal. If ** sets the master journal pointer in each individual journal. If