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)
D 2007-08-15T17:07:57
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:08:46
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -91,18 +91,18 @@ F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c ef73642a171d174cd556d0168f8edbceaf94933b
F src/mem2.c b8173ddcca23e99829617185154a35a6f046b214
F src/mutex.c 667dae0de95f8fb92a3ffc8c3f20c0d26115a1a6
F src/os.c 1f10b47acc1177fb9225edb4f5f0d25ed716f9cb
F src/os.h cea2e179bb33f4fc09dbb9fcd51b2246544bd2db
F src/os.c e2faefbe0f5a8ca5e3b1c49ee1b5c6cfa0f0e279
F src/os.h 8eff07babf74e5bc3f895f8a6c7c294dad5ff997
F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
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_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c cdf561d3ae4009be902df714da4518dc3522e206
F src/pager.c 05ea9dcbc4de4e9d9ca332ca1f8a9ba65fe2cbf5
F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
F src/parse.y ad2ce25665be7f7303137f774a4e3e72e0d036ff
F src/pragma.c 7914a6b9ea05f158800116dfcae11e52ab8e39c4
@ -112,18 +112,18 @@ F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
F src/select.c 3b167744fc375bddfddcef87feb18f5171737677
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
F src/sqlite.h.in 025e9fd6c519f2945296a9db46ca9da4571c22d7
F src/sqlite.h.in 165913eb3426fbaa8a2a51d87f84593bfe5bee15
F src/sqlite3ext.h a27bedc222df5e5f0f458ac99726d0483b953a91
F src/sqliteInt.h fc9f6e8d916e182c04983a089c4ce4057fac5003
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
F src/table.c a8de75bcedf84d4060d804264b067ab3b1a3561d
F src/tclsqlite.c 648e6f53041ce4974234d4963e71680926760925
F src/test1.c 94bd41c24a4d8d782e39c1275421511587d8b293
F src/test2.c 24458b17ab2f3c90cbc1c8446bd7ffe69be62f88
F src/test2.c 5c3edc610852a8f67990cd08c5d5dbb79e3f8db9
F src/test3.c a280931fb40222b7c90da45eea926459beee8904
F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
F src/test5.c c40a4cf43266c1c6da7bcb737d294304a177e6cc
F src/test6.c 2c4ed21787944bd8896cba80d4a544d8bed5473e
F src/test6.c 4d812a5ea1fe08693f4189bfc974b341102a3bea
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
F src/test8.c 27a61c60f736066646a9e9ca21acdfdf0f3ea11e
F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
@ -147,7 +147,7 @@ F src/vdbe.c cf973bd1af5fbda845b0f759bb06eb19ff42e215
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
F src/vdbeInt.h c3514903cad9e36d6b3242be20261351d09db56c
F src/vdbeapi.c 220b81132abaf0f620edb8da48799a77daef12a7
F src/vdbeaux.c d626e0f8cd78b4280bcb7af25d5c5566348ba87a
F src/vdbeaux.c 8e6dbe3dac3bdd7d37c87ba553059b5251ba07e5
F src/vdbeblob.c bb30b3e387c35ba869949494b2736aff97159470
F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
F src/vdbemem.c ca4d3994507cb0a9504820293af69f5c778b4abd
@ -528,7 +528,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P c0fa3769790af199a4c8715c80bb8ff900730520
R afa459b840a3b96de70924b91a0e1dbb
U drh
Z 9341f1481e29775e7a036e24546ed5fc
P 8d2d1c4ff9dca61f75e3048107ee9712d346a28c
R 7d9819ae0c3408fa1555b7b8d9a48850
U danielk1977
Z 41f21c80ce49e631fe5dbf7930bb9145

View File

@ -1 +1 @@
8d2d1c4ff9dca61f75e3048107ee9712d346a28c
af9503daf3f7703fcddad754bc1dc9e179830b6e

View File

@ -20,63 +20,65 @@
/*
** 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
** C++ instead of plain old C.
*/
int sqlite3OsClose(OsFile **pId){
OsFile *id;
int sqlite3OsClose(sqlite3_file **pId){
int rc = SQLITE_OK;
sqlite3_file *id;
if( pId!=0 && (id = *pId)!=0 ){
return id->pMethod->xClose(pId);
}else{
return SQLITE_OK;
rc = id->pMethods->xClose(id);
if( rc==SQLITE_OK ){
*pId = 0;
}
}
return rc;
}
int sqlite3OsOpenDirectory(OsFile *id, const char *zName){
return id->pMethod->xOpenDirectory(id, zName);
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
return id->pMethods->xRead(id, pBuf, amt, offset);
}
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
return id->pMethod->xRead(id, pBuf, amt);
int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
return id->pMethods->xWrite(id, pBuf, amt, offset);
}
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
return id->pMethod->xWrite(id, pBuf, amt);
int sqlite3OsTruncate(sqlite3_file *id, i64 size){
return id->pMethods->xTruncate(id, size);
}
int sqlite3OsSeek(OsFile *id, i64 offset){
return id->pMethod->xSeek(id, offset);
int sqlite3OsSync(sqlite3_file *id, int fullsync){
return id->pMethods->xSync(id, fullsync);
}
int sqlite3OsTruncate(OsFile *id, i64 size){
return id->pMethod->xTruncate(id, size);
int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
return id->pMethods->xFileSize(id, pSize);
}
int sqlite3OsSync(OsFile *id, int fullsync){
return id->pMethod->xSync(id, fullsync);
int sqlite3OsLock(sqlite3_file *id, int lockType){
return id->pMethods->xLock(id, lockType);
}
void sqlite3OsSetFullSync(OsFile *id, int value){
id->pMethod->xSetFullSync(id, value);
int sqlite3OsUnlock(sqlite3_file *id, int lockType){
return id->pMethods->xUnlock(id, lockType);
}
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
return id->pMethod->xFileSize(id, pSize);
int sqlite3OsBreakLock(sqlite3_file *id){
return id->pMethods->xBreakLock(id);
}
int sqlite3OsLock(OsFile *id, int lockType){
return id->pMethod->xLock(id, lockType);
int sqlite3OsCheckReservedLock(sqlite3_file *id){
return id->pMethods->xCheckReservedLock(id);
}
int sqlite3OsUnlock(OsFile *id, int lockType){
return id->pMethod->xUnlock(id, lockType);
}
int sqlite3OsCheckReservedLock(OsFile *id){
return id->pMethod->xCheckReservedLock(id);
}
int sqlite3OsSectorSize(OsFile *id){
int (*xSectorSize)(OsFile*) = id->pMethod->xSectorSize;
int sqlite3OsSectorSize(sqlite3_file *id){
int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
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)
/* These methods are currently only used for testing and debugging. */
int sqlite3OsFileHandle(OsFile *id){
return id->pMethod->xFileHandle(id);
int sqlite3OsFileHandle(sqlite3_file *id){
/* return id->pMethods->xFileHandle(id); */
return 0;
}
int sqlite3OsLockState(OsFile *id){
return id->pMethod->xLockState(id);
int sqlite3OsLockState(sqlite3_file *id){
/* return id->pMethods->xLockState(id); */
return 0;
}
#endif

View File

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

View File

@ -82,7 +82,7 @@
*/
typedef struct unixFile 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 lockInfo *pLock; /* Info about locks on this inode */
#ifdef SQLITE_ENABLE_LOCKING_STYLE
@ -99,6 +99,7 @@ struct unixFile {
#endif
};
/*
** Provide the ability to override some OS-layer functions during
** testing. This is used to simulate OS crashes to verify that
@ -106,13 +107,15 @@ struct unixFile {
*/
#ifdef SQLITE_CRASH_TEST
extern int sqlite3CrashTestEnable;
extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*);
extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int);
extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int);
# define CRASH_TEST_OVERRIDE(X,A,B,C) \
if(sqlite3CrashTestEnable){ return X(A,B,C); }
int sqlite3CrashFileWrap(sqlite3_file *, const char *, sqlite3_file **);
static int CRASH_TEST_OVERRIDE(const char *zFile, sqlite3_file **pId, int rc){
if( rc==SQLITE_OK && sqlite3CrashTestEnable ){
rc = sqlite3CrashFileWrap(*pId, zFile, pId);
}
return rc;
}
#else
# define CRASH_TEST_OVERRIDE(X,A,B,C) /* no-op */
# define CRASH_TEST_OVERRIDE(A,B,C) C
#endif
@ -801,7 +804,7 @@ int sqlite3UnixFileExists(const char *zFilename){
/* Forward declaration */
static int allocateUnixFile(
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 */
int delFlag /* If true, make sure the file deletes on close */
);
@ -821,12 +824,11 @@ static int allocateUnixFile(
*/
int sqlite3UnixOpenReadWrite(
const char *zFilename,
OsFile **pId,
sqlite3_file **pId,
int *pReadonly
){
int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
assert( 0==*pId );
h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
SQLITE_DEFAULT_FILE_PERMISSIONS);
@ -844,7 +846,10 @@ int sqlite3UnixOpenReadWrite(
}else{
*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.
*/
int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
int sqlite3UnixOpenExclusive(
const char *zFilename,
sqlite3_file **pId,
int delFlag
){
int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
assert( 0==*pId );
h = open(zFilename,
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 ){
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.
*/
int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
int sqlite3UnixOpenReadOnly(const char *zFilename, sqlite3_file **pId){
int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
assert( 0==*pId );
h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
if( h<0 ){
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.
** 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;
i64 newOffset;
TIMER_START;
#if defined(USE_PREAD)
got = pread(id->h, pBuf, cnt, id->offset);
got = pread(id->h, pBuf, cnt, offset);
SimulateIOError( got = -1 );
#elif defined(USE_PREAD64)
got = pread64(id->h, pBuf, cnt, id->offset);
got = pread64(id->h, pBuf, cnt, offset);
SimulateIOError( got = -1 );
#else
newOffset = lseek(id->h, id->offset, SEEK_SET);
newOffset = lseek(id->h, offset, SEEK_SET);
SimulateIOError( newOffset-- );
if( newOffset!=id->offset ){
if( newOffset!=offset ){
return -1;
}
got = read(id->h, pBuf, cnt);
#endif
TIMER_END;
OSTRACE5("READ %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED);
if( got>0 ){
id->offset += 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
** 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;
assert( id );
got = seekAndRead((unixFile*)id, pBuf, amt);
got = seekAndRead((unixFile*)id, offset, pBuf, amt);
if( got==amt ){
return SQLITE_OK;
}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.
** 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;
i64 newOffset;
TIMER_START;
#if defined(USE_PREAD)
got = pwrite(id->h, pBuf, cnt, id->offset);
got = pwrite(id->h, pBuf, cnt, offset);
#elif defined(USE_PREAD64)
got = pwrite64(id->h, pBuf, cnt, id->offset);
got = pwrite64(id->h, pBuf, cnt, offset);
#else
newOffset = lseek(id->h, id->offset, SEEK_SET);
if( newOffset!=id->offset ){
newOffset = lseek(id->h, offset, SEEK_SET);
if( newOffset!=offset ){
return -1;
}
got = write(id->h, pBuf, cnt);
#endif
TIMER_END;
OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED);
if( got>0 ){
id->offset += got;
}
OSTRACE5("WRITE %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
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
** 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;
assert( id );
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;
offset += wrote;
pBuf = &((char*)pBuf)[wrote];
}
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
** 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;
unixFile *pFile = (unixFile*)id;
assert( pFile );
@ -1272,7 +1288,7 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
/*
** 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;
assert( id );
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
*/
static int unixFileSize(OsFile *id, i64 *pSize){
static int unixFileSize(sqlite3_file *id, i64 *pSize){
int rc;
struct stat buf;
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
** return zero.
*/
static int unixCheckReservedLock(OsFile *id){
static int unixCheckReservedLock(sqlite3_file *id){
int r = 0;
unixFile *pFile = (unixFile*)id;
@ -1362,7 +1378,7 @@ static int unixCheckReservedLock(OsFile *id){
** This routine will only increase a lock. Use the sqlite3OsUnlock()
** 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
** lock transitions in terms of the POSIX advisory shared and exclusive
** 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
** 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 flock lock;
int rc = SQLITE_OK;
@ -1650,44 +1666,42 @@ static int unixUnlock(OsFile *id, int locktype){
/*
** Close a file.
*/
static int unixClose(OsFile **pId){
unixFile *id = (unixFile*)*pId;
if( !id ) return SQLITE_OK;
unixUnlock(*pId, NO_LOCK);
if( id->dirfd>=0 ) close(id->dirfd);
id->dirfd = -1;
static int unixClose(sqlite3_file *id){
unixFile *pFile = (unixFile *)id;
if( !pFile ) return SQLITE_OK;
unixUnlock(id, NO_LOCK);
if( pFile->dirfd>=0 ) close(pFile->dirfd);
pFile->dirfd = -1;
sqlite3OsEnterMutex();
if( id->pOpen->nLock ){
if( pFile->pOpen->nLock ){
/* If there are outstanding locks, do not actually close the file just
** yet because that would clear those locks. Instead, add the file
** descriptor to pOpen->aPending. It will be automatically closed when
** the last lock is cleared.
*/
int *aNew;
struct openCnt *pOpen = id->pOpen;
struct openCnt *pOpen = pFile->pOpen;
aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
if( aNew==0 ){
/* If a malloc fails, just leak the file descriptor */
}else{
pOpen->aPending = aNew;
pOpen->aPending[pOpen->nPending] = id->h;
pOpen->aPending[pOpen->nPending] = pFile->h;
pOpen->nPending++;
}
}else{
/* There are no outstanding locks so we can close the file immediately */
close(id->h);
close(pFile->h);
}
releaseLockInfo(id->pLock);
releaseOpenCnt(id->pOpen);
releaseLockInfo(pFile->pLock);
releaseOpenCnt(pFile->pOpen);
sqlite3OsLeaveMutex();
id->isOpen = 0;
OSTRACE2("CLOSE %-3d\n", id->h);
pFile->isOpen = 0;
OSTRACE2("CLOSE %-3d\n", pFile->h);
OpenCounter(-1);
sqlite3ThreadSafeFree(id);
*pId = 0;
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
** same for both.
*/
static int unixSectorSize(OsFile *id){
static int unixSectorSize(sqlite3_file *id){
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
** for unix.
*/
static const IoMethod sqlite3UnixIoMethod = {
static const sqlite3_io_methods sqlite3UnixIoMethod = {
1, /* iVersion */
unixClose,
unixOpenDirectory,
unixRead,
unixWrite,
unixSeek,
unixTruncate,
unixSync,
unixSetFullSync,
unixFileHandle,
unixFileSize,
unixLock,
unixUnlock,
unixLockState,
unixCheckReservedLock,
unixBreakLock,
unixSectorSize,
unixDeviceCharacteristics
};
#ifdef SQLITE_ENABLE_LOCKING_STYLE
@ -2573,7 +2594,7 @@ static int allocateUnixFile(
#else /* SQLITE_ENABLE_LOCKING_STYLE */
static int allocateUnixFile(
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 */
int delFlag /* If true, delete the file on or before closing */
){
@ -2611,7 +2632,7 @@ static int allocateUnixFile(
}else{
*pNew = f;
pNew->pMethod = &sqlite3UnixIoMethod;
*pId = (OsFile*)pNew;
*pId = (sqlite3_file*)pNew;
OpenCounter(+1);
return SQLITE_OK;
}

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** 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
#include "sqliteInt.h"
@ -50,7 +50,7 @@
** to print out file-descriptors.
**
** 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.
*/
#define PAGERID(p) ((int)(p->fd))
@ -336,8 +336,8 @@ struct Pager {
char *zFilename; /* Name of the database file */
char *zJournal; /* Name of the journal file */
char *zDirectory; /* Directory hold database and journal files */
OsFile *fd, *jfd; /* File descriptors for database and journal */
OsFile *stfd; /* File descriptor for the statement subjournal*/
sqlite3_file *fd, *jfd; /* File descriptors for database and journal */
sqlite3_file *stfd; /* File descriptor for the statement subjournal*/
BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */
PgHdr *pFirst, *pLast; /* List of free pages */
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.
*/
static int read32bits(OsFile *fd, u32 *pRes){
static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
unsigned char ac[4];
int rc = sqlite3OsRead(fd, ac, sizeof(ac));
int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
if( rc==SQLITE_OK ){
*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
** 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];
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
** SQLITE_OK returned.
*/
static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
static int readMasterJournal(sqlite3_file *pJrnl, char **pzMaster){
int rc;
u32 len;
i64 szJ;
@ -640,26 +640,20 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
rc = sqlite3OsFileSize(pJrnl, &szJ);
if( rc!=SQLITE_OK || szJ<16 ) return rc;
rc = sqlite3OsSeek(pJrnl, szJ-16);
if( rc!=SQLITE_OK ) return rc;
rc = read32bits(pJrnl, &len);
rc = read32bits(pJrnl, szJ-16, &len);
if( rc!=SQLITE_OK ) return rc;
rc = read32bits(pJrnl, &cksum);
rc = read32bits(pJrnl, szJ-12, &cksum);
if( rc!=SQLITE_OK ) return rc;
rc = sqlite3OsRead(pJrnl, aMagic, 8);
rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8);
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);
if( !*pzMaster ){
return SQLITE_NOMEM;
}
rc = sqlite3OsRead(pJrnl, *pzMaster, len);
rc = sqlite3OsRead(pJrnl, *pzMaster, len, szJ-16-len);
if( rc!=SQLITE_OK ){
sqliteFree(*pzMaster);
*pzMaster = 0;
@ -700,7 +694,7 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){
** 2000 2048
**
*/
static int seekJournalHdr(Pager *pPager){
static void seekJournalHdr(Pager *pPager){
i64 offset = 0;
i64 c = pPager->journalOff;
if( c ){
@ -710,7 +704,6 @@ static int seekJournalHdr(Pager *pPager){
assert( offset>=c );
assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
pPager->journalOff = offset;
return sqlite3OsSeek(pPager->jfd, pPager->journalOff);
}
/*
@ -735,11 +728,8 @@ static int writeJournalHdr(Pager *pPager){
pPager->stmtHdrOff = pPager->journalOff;
}
rc = seekJournalHdr(pPager);
if( rc ) return rc;
seekJournalHdr(pPager);
pPager->journalHdr = pPager->journalOff;
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
/* FIX ME:
**
@ -760,17 +750,15 @@ static int writeJournalHdr(Pager *pPager){
/* The assumed sector size for this process */
put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
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
** file descriptor to the end of the journal header sector.
*/
if( rc==SQLITE_OK ){
IOTRACE(("JTAIL %p %lld\n", pPager, pPager->journalOff-1))
rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->jfd, "\000", 1);
}
rc = sqlite3OsWrite(pPager->jfd, "\000", 1, pPager->journalOff-1);
}
return rc;
}
@ -799,28 +787,29 @@ static int readJournalHdr(
){
int rc;
unsigned char aMagic[8]; /* A buffer to hold the magic header */
i64 jrnlOff;
rc = seekJournalHdr(pPager);
if( rc ) return rc;
seekJournalHdr(pPager);
if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
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;
jrnlOff += sizeof(aMagic);
if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
return SQLITE_DONE;
}
rc = read32bits(pPager->jfd, pNRec);
rc = read32bits(pPager->jfd, jrnlOff, pNRec);
if( rc ) return rc;
rc = read32bits(pPager->jfd, &pPager->cksumInit);
rc = read32bits(pPager->jfd, jrnlOff+4, &pPager->cksumInit);
if( rc ) return rc;
rc = read32bits(pPager->jfd, pDbSize);
rc = read32bits(pPager->jfd, jrnlOff+8, pDbSize);
if( rc ) return rc;
/* 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
** 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;
pPager->journalOff += JOURNAL_HDR_SZ(pPager);
rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff);
return rc;
return SQLITE_OK;
}
@ -861,6 +849,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
int rc;
int len;
int i;
i64 jrnlOff;
u32 cksum = 0;
char zBuf[sizeof(aJournalMagic)+2*4];
@ -877,21 +866,23 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
** the journal has already been synced.
*/
if( pPager->fullSync ){
rc = seekJournalHdr(pPager);
if( rc!=SQLITE_OK ) return rc;
seekJournalHdr(pPager);
}
jrnlOff = pPager->journalOff;
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;
jrnlOff += 4;
rc = sqlite3OsWrite(pPager->jfd, zMaster, len);
rc = sqlite3OsWrite(pPager->jfd, zMaster, len, jrnlOff);
if( rc!=SQLITE_OK ) return rc;
jrnlOff += len;
put32bits(zBuf, len);
put32bits(&zBuf[4], cksum);
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;
return rc;
}
@ -1026,7 +1017,6 @@ static int pager_end_transaction(Pager *pPager){
if( pPager->journalOpen ){
if( pPager->exclusiveMode
&& (rc = sqlite3OsTruncate(pPager->jfd, 0))==SQLITE_OK ){;
sqlite3OsSeek(pPager->jfd, 0);
pPager->journalOff = 0;
pPager->journalStarted = 0;
}else{
@ -1111,7 +1101,12 @@ static void makeClean(PgHdr*);
** are not used in statement journals because statement journals do not
** 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;
PgHdr *pPg; /* An existing page in the cache */
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( aData );
rc = read32bits(jfd, &pgno);
rc = read32bits(jfd, offset, &pgno);
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;
pPager->journalOff += pPager->pageSize + 4;
@ -1142,7 +1137,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
return SQLITE_OK;
}
if( useCksum ){
rc = read32bits(jfd, &cksum);
rc = read32bits(jfd, offset+pPager->pageSize+4, &cksum);
if( rc ) return rc;
pPager->journalOff += 4;
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",
PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, aData));
if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize);
}
i64 offset = (pgno-1)*(i64)pPager->pageSize;
rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize, offset);
if( 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){
int rc;
int master_open = 0;
OsFile *master = 0;
sqlite3_file *master = 0;
char *zMasterJournal = 0; /* Contents 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;
goto delmaster_out;
}
rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal);
rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal, 0);
if( rc!=SQLITE_OK ) goto delmaster_out;
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
** so, return without deleting the master journal file.
*/
OsFile *journal = 0;
sqlite3_file *journal = 0;
int c;
rc = sqlite3OsOpenReadOnly(zJournal, &journal);
@ -1424,7 +1417,6 @@ static int pager_playback(Pager *pPager, int isHot){
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
goto end_playback;
}
sqlite3OsSeek(pPager->jfd, 0);
pPager->journalOff = 0;
/* 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.
*/
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_DONE ){
rc = SQLITE_OK;
@ -1567,7 +1559,6 @@ static int pager_stmt_playback(Pager *pPager){
/* Figure out how many records are in the statement journal.
*/
assert( pPager->stmtInUse && pPager->journalOpen );
sqlite3OsSeek(pPager->stfd, 0);
nRec = pPager->stmtNRec;
/* 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
** journals.
*/
for(i=nRec-1; i>=0; i--){
rc = pager_playback_one_page(pPager, pPager->stfd, 0);
for(i=0; i<nRec; i++){
i64 offset = i*(4+pPager->pageSize);
rc = pager_playback_one_page(pPager, pPager->stfd, offset, 0);
assert( rc!=SQLITE_DONE );
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
** 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->cksumInit = pPager->stmtCksum;
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 );
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);
}
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 );
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
** closed.
*/
static int sqlite3PagerOpentemp(OsFile **pFd){
static int sqlite3PagerOpentemp(sqlite3_file **pFd){
int cnt = 8;
int rc;
char zFile[SQLITE_TEMPNAME_SIZE];
@ -1733,7 +1721,7 @@ int sqlite3PagerOpen(
Pager *pPager = 0;
char *zFullPathname = 0;
int nameLen; /* Compiler is wrong. This is always initialized before use */
OsFile *fd = 0;
sqlite3_file *fd = 0;
int rc = SQLITE_OK;
int i;
int tempFile = 0;
@ -1970,11 +1958,8 @@ int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
int rc = SQLITE_OK;
memset(pDest, 0, N);
if( MEMDB==0 ){
disable_simulated_io_errors();
sqlite3OsSeek(pPager->fd, 0);
enable_simulated_io_errors();
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 ){
rc = SQLITE_OK;
}
@ -2381,6 +2366,8 @@ static int syncJournal(Pager *pPager){
}
#endif
{
i64 jrnlOff;
/* Write the nRec value into the journal file header. If in
** full-synchronous mode, sync the journal first. This ensures that
** 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);
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;
}
PAGERTRACE2("SYNC journal of %d\n", PAGERID(pPager));
@ -2545,19 +2527,18 @@ static int pager_write_pagelist(PgHdr *pList){
pList = sort_pagelist(pList);
while( pList ){
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
** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
** make the file smaller (presumably by auto-vacuum code). Do not write
** any such pages to the file.
*/
if( pList->pgno<=pPager->dbSize ){
i64 offset = (pList->pgno-1)*(i64)pPager->pageSize;
char *pData = CODEC2(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
PAGERTRACE4("STORE %d page %d hash(%08x)\n",
PAGERID(pPager), pList->pgno, pager_pagehash(pList));
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(pPager->nWrite);
if( pList->pgno==1 ){
@ -2796,12 +2777,10 @@ int sqlite3PagerReleaseMemory(int nReq){
*/
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
int rc;
i64 offset;
assert( MEMDB==0 );
rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
if( rc==SQLITE_OK ){
rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg),
pPager->pageSize);
}
offset = (pgno-1)*(i64)pPager->pageSize;
rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize, offset);
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
IOTRACE(("PGIN %p %d\n", pPager, pgno));
@ -2934,11 +2913,7 @@ static int pagerSharedLock(Pager *pPager){
if( pPager->dbSize>0 ){
IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
rc = sqlite3OsSeek(pPager->fd, 24);
if( rc!=SQLITE_OK ){
return rc;
}
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers));
rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
if( rc!=SQLITE_OK ){
return rc;
}
@ -3332,9 +3307,11 @@ static int pager_open_journal(Pager *pPager){
}
goto failed_to_open_journal;
}
#if 0
sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync);
sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync);
sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
#endif
pPager->journalOpen = 1;
pPager->journalStarted = 0;
pPager->needSync = 0;
@ -3583,7 +3560,7 @@ static int pager_write(PgHdr *pPg){
put32bits(pEnd, cksum);
szPg = pPager->pageSize+8;
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,
pPager->journalOff, szPg));
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);
page_add_to_stmt_list(pPg);
}else{
i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7)-4;
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);
if( rc!=SQLITE_OK ){
return rc;
@ -4215,7 +4193,6 @@ int sqlite3PagerStmtCommit(Pager *pPager){
PgHdr *pPg, *pNext;
PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
if( !MEMDB ){
sqlite3OsSeek(pPager->stfd, 0);
/* sqlite3OsTruncate(pPager->stfd, 0); */
sqliteFree( pPager->aInStmt );
pPager->aInStmt = 0;

View File

@ -30,7 +30,7 @@
** the version number) and changes its name to "sqlite3.h" as
** 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_
#define _SQLITE3_H_
@ -488,7 +488,7 @@ struct sqlite3_io_methods {
int iVersion;
int (*xClose)(sqlite3_file*);
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 (*xSync)(sqlite3_file*, int flags);
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
** 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 "os.h"
@ -546,12 +546,7 @@ static int fake_big_file(
}
offset = n;
offset *= 1024*1024;
rc = sqlite3OsSeek(fd, offset);
if( rc ){
Tcl_AppendResult(interp, "seek failed: ", errorName(rc), 0);
return TCL_ERROR;
}
rc = sqlite3OsWrite(fd, "Hello, World!", 14);
rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
sqlite3OsClose(&fd);
if( rc ){
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;
char *zMaster = 0; /* File-name for the master journal */
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
OsFile *master = 0;
sqlite3_file *master = 0;
i64 offset = 0;
/* Select a master journal file name */
do {
@ -1164,7 +1165,8 @@ static int vdbeCommit(sqlite3 *db){
if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
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 ){
sqlite3OsClose(&master);
sqlite3OsDelete(zMaster);
@ -1179,6 +1181,7 @@ static int vdbeCommit(sqlite3 *db){
** the master journal file is store in so that it gets synced too.
*/
zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
#if 0
rc = sqlite3OsOpenDirectory(master, zMainFile);
if( rc!=SQLITE_OK ||
(needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){
@ -1187,6 +1190,7 @@ static int vdbeCommit(sqlite3 *db){
sqliteFree(zMaster);
return rc;
}
#endif
/* Sync all the db files involved in the transaction. The same call
** sets the master journal pointer in each individual journal. If