mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Correctly handle I/O errors that occur during OsUnlock(). Before this
fix, an I/O error during OsUnlock() could lead to database corruption. That is not a serious problem, though, since errors during OsUnlock() are not possible on most systems. (CVS 4838) FossilOrigin-Name: b4c1258edb4a40501d13c9da674d0366d5a8c694
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Cleanup\sthe\slocking-style\scode\sin\sos_unix.c.\s(CVS\s4837)
|
C Correctly\shandle\sI/O\serrors\sthat\soccur\sduring\sOsUnlock().\s\sBefore\sthis\nfix,\san\sI/O\serror\sduring\sOsUnlock()\scould\slead\sto\sdatabase\scorruption.\nThat\sis\snot\sa\sserious\sproblem,\sthough,\ssince\serrors\sduring\sOsUnlock()\nare\snot\spossible\son\smost\ssystems.\s(CVS\s4838)
|
||||||
D 2008-03-07T15:34:11
|
D 2008-03-07T19:51:14
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in d521464011d6965bbda1b699f1850c6e33141c73
|
F Makefile.in d521464011d6965bbda1b699f1850c6e33141c73
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -120,16 +120,16 @@ F src/mutex_unix.c a6e111947a3cdaa2cda394ed060d7f496fcb4af8
|
|||||||
F src/mutex_w32.c 6e197765f283815496193e78e9548b5d0e53b68e
|
F src/mutex_w32.c 6e197765f283815496193e78e9548b5d0e53b68e
|
||||||
F src/os.c 2f2753b8d33f79d169c43d6bb0b25b3c58fd33de
|
F src/os.c 2f2753b8d33f79d169c43d6bb0b25b3c58fd33de
|
||||||
F src/os.h d04706d54a072c7a30ab9e346ad916ef28c842d5
|
F src/os.h d04706d54a072c7a30ab9e346ad916ef28c842d5
|
||||||
F src/os_common.h a66179e3b9a2686ba0f17a26d065d3e29202b7b8
|
F src/os_common.h e8b748b2f2ecc8a498e50bfe5d8721f189c19d2a
|
||||||
F src/os_os2.c 10b23539e0050bdfc9f136242086a5c18c70c6f8
|
F src/os_os2.c 10b23539e0050bdfc9f136242086a5c18c70c6f8
|
||||||
F src/os_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b
|
F src/os_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b
|
||||||
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 bf339cd689054c8edc603c0209d91f62444c1477
|
F src/os_unix.c 04ff58d84ae02d4ef732103455bfe36ce7780738
|
||||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||||
F src/os_win.c aa3f4bbee3b8c182d25a33fbc319f486857c12c1
|
F src/os_win.c aa3f4bbee3b8c182d25a33fbc319f486857c12c1
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c d09885bb88e9868a5c322a0181d4022cf294d98b
|
F src/pager.c 803d361f7aabfea1eebf8951916492c77d3781a2
|
||||||
F src/pager.h 8174615ffd14ccc2cad2b081b919a398fa95e3f9
|
F src/pager.h 8174615ffd14ccc2cad2b081b919a398fa95e3f9
|
||||||
F src/parse.y 00f2698c8ae84f315be5e3f10b63c94f531fdd6d
|
F src/parse.y 00f2698c8ae84f315be5e3f10b63c94f531fdd6d
|
||||||
F src/pragma.c e3f39f8576234887ecd0c1de43dc51af5855930c
|
F src/pragma.c e3f39f8576234887ecd0c1de43dc51af5855930c
|
||||||
@@ -146,7 +146,7 @@ F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
|||||||
F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
|
F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
|
||||||
F src/tclsqlite.c d95e0e74c7167b2807f9f4f73bf45f7c58096297
|
F src/tclsqlite.c d95e0e74c7167b2807f9f4f73bf45f7c58096297
|
||||||
F src/test1.c c3d43a6bd299f3c115f6617af6715004819ca5cb
|
F src/test1.c c3d43a6bd299f3c115f6617af6715004819ca5cb
|
||||||
F src/test2.c 355d5693ca3ee705548fa7f795592a37b2372b70
|
F src/test2.c 89793e863188028b49bd259026a73820426539b3
|
||||||
F src/test3.c 5c7452038ab27aa698070799b10132f26cdd2a80
|
F src/test3.c 5c7452038ab27aa698070799b10132f26cdd2a80
|
||||||
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
||||||
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
||||||
@@ -353,7 +353,7 @@ F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
|
|||||||
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
|
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
|
||||||
F test/io.test f2e9890eb3f159973fcb11008054596b0caeca4f
|
F test/io.test f2e9890eb3f159973fcb11008054596b0caeca4f
|
||||||
F test/ioerr.test 5382046b2ef19b9084652e7d2d1e82ab33c0deda
|
F test/ioerr.test 5382046b2ef19b9084652e7d2d1e82ab33c0deda
|
||||||
F test/ioerr2.test e3d52c40f43f9b61da9b38951a737e7b84ebae96
|
F test/ioerr2.test b9c9a0491a812707762a7c002876553be54d9969
|
||||||
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||||
F test/join.test af0443185378b64878750aa1cf4b83c216f246b4
|
F test/join.test af0443185378b64878750aa1cf4b83c216f246b4
|
||||||
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
|
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
|
||||||
@@ -458,7 +458,7 @@ F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455
|
|||||||
F test/tableapi.test 4546eb710d979db023bfcc16b0c108b1557fcb43
|
F test/tableapi.test 4546eb710d979db023bfcc16b0c108b1557fcb43
|
||||||
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
||||||
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
||||||
F test/tester.tcl 7760c4101448e5595b2ee095e540643fa31a1610
|
F test/tester.tcl 8f1df98df42667d05ee56ac4ba1ee58f9bb1e885
|
||||||
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
||||||
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
||||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||||
@@ -623,7 +623,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 9819cefbd7032fe6884c6c891e8e399000e0821f
|
P 40f55c09dbd31f861b9f9c7641cce92553d94e35
|
||||||
R 94e0b03717c8cb302d6990c16331816e
|
R 862dd7b7066eb395b14356fb582df1d4
|
||||||
U drh
|
U drh
|
||||||
Z c7afd0fbb52cbc7669e22683bc9d24e9
|
Z aa58e6aa52b1bd4468d6e2d048a914af
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
40f55c09dbd31f861b9f9c7641cce92553d94e35
|
b4c1258edb4a40501d13c9da674d0366d5a8c694
|
||||||
@@ -86,19 +86,22 @@ static unsigned int elapse;
|
|||||||
** is used for testing the I/O recovery logic.
|
** is used for testing the I/O recovery logic.
|
||||||
*/
|
*/
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
int sqlite3_io_error_hit = 0;
|
int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
|
||||||
int sqlite3_io_error_pending = 0;
|
int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
|
||||||
int sqlite3_io_error_persist = 0;
|
int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
|
||||||
|
int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
|
||||||
|
int sqlite3_io_error_benign = 0; /* True if errors are benign */
|
||||||
int sqlite3_diskfull_pending = 0;
|
int sqlite3_diskfull_pending = 0;
|
||||||
int sqlite3_diskfull = 0;
|
int sqlite3_diskfull = 0;
|
||||||
|
#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
|
||||||
#define SimulateIOError(CODE) \
|
#define SimulateIOError(CODE) \
|
||||||
if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \
|
if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
|
||||||
if( sqlite3_io_error_pending-- == 1 \
|
|| sqlite3_io_error_pending-- == 1 ) \
|
||||||
|| (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \
|
{ local_ioerr(); CODE; }
|
||||||
{ local_ioerr(); CODE; }
|
|
||||||
static void local_ioerr(){
|
static void local_ioerr(){
|
||||||
IOTRACE(("IOERR\n"));
|
IOTRACE(("IOERR\n"));
|
||||||
sqlite3_io_error_hit = 1;
|
sqlite3_io_error_hit++;
|
||||||
|
if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
|
||||||
}
|
}
|
||||||
#define SimulateDiskfullError(CODE) \
|
#define SimulateDiskfullError(CODE) \
|
||||||
if( sqlite3_diskfull_pending ){ \
|
if( sqlite3_diskfull_pending ){ \
|
||||||
@@ -112,6 +115,7 @@ static void local_ioerr(){
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#define SimulateIOErrorBenign(X)
|
||||||
#define SimulateIOError(A)
|
#define SimulateIOError(A)
|
||||||
#define SimulateDiskfullError(A)
|
#define SimulateDiskfullError(A)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1326,6 +1326,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
struct flock lock;
|
struct flock lock;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
|
int h;
|
||||||
|
|
||||||
assert( pFile );
|
assert( pFile );
|
||||||
OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
|
OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
|
||||||
@@ -1339,17 +1340,20 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
return SQLITE_MISUSE;
|
return SQLITE_MISUSE;
|
||||||
}
|
}
|
||||||
enterMutex();
|
enterMutex();
|
||||||
|
h = pFile->h;
|
||||||
pLock = pFile->pLock;
|
pLock = pFile->pLock;
|
||||||
assert( pLock->cnt!=0 );
|
assert( pLock->cnt!=0 );
|
||||||
if( pFile->locktype>SHARED_LOCK ){
|
if( pFile->locktype>SHARED_LOCK ){
|
||||||
assert( pLock->locktype==pFile->locktype );
|
assert( pLock->locktype==pFile->locktype );
|
||||||
|
SimulateIOErrorBenign(1);
|
||||||
|
SimulateIOError( h=(-1) )
|
||||||
|
SimulateIOErrorBenign(0);
|
||||||
if( locktype==SHARED_LOCK ){
|
if( locktype==SHARED_LOCK ){
|
||||||
lock.l_type = F_RDLCK;
|
lock.l_type = F_RDLCK;
|
||||||
lock.l_whence = SEEK_SET;
|
lock.l_whence = SEEK_SET;
|
||||||
lock.l_start = SHARED_FIRST;
|
lock.l_start = SHARED_FIRST;
|
||||||
lock.l_len = SHARED_SIZE;
|
lock.l_len = SHARED_SIZE;
|
||||||
if( fcntl(pFile->h, F_SETLK, &lock)==(-1) ){
|
if( fcntl(h, F_SETLK, &lock)==(-1) ){
|
||||||
/* This should never happen */
|
|
||||||
rc = SQLITE_IOERR_RDLOCK;
|
rc = SQLITE_IOERR_RDLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1357,10 +1361,10 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
lock.l_whence = SEEK_SET;
|
lock.l_whence = SEEK_SET;
|
||||||
lock.l_start = PENDING_BYTE;
|
lock.l_start = PENDING_BYTE;
|
||||||
lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE );
|
lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE );
|
||||||
if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){
|
if( fcntl(h, F_SETLK, &lock)!=(-1) ){
|
||||||
pLock->locktype = SHARED_LOCK;
|
pLock->locktype = SHARED_LOCK;
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
|
rc = SQLITE_IOERR_UNLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( locktype==NO_LOCK ){
|
if( locktype==NO_LOCK ){
|
||||||
@@ -1375,10 +1379,14 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
lock.l_type = F_UNLCK;
|
lock.l_type = F_UNLCK;
|
||||||
lock.l_whence = SEEK_SET;
|
lock.l_whence = SEEK_SET;
|
||||||
lock.l_start = lock.l_len = 0L;
|
lock.l_start = lock.l_len = 0L;
|
||||||
if( fcntl(pFile->h, F_SETLK, &lock)!=(-1) ){
|
SimulateIOErrorBenign(1);
|
||||||
|
SimulateIOError( h=(-1) )
|
||||||
|
SimulateIOErrorBenign(0);
|
||||||
|
if( fcntl(h, F_SETLK, &lock)!=(-1) ){
|
||||||
pLock->locktype = NO_LOCK;
|
pLock->locktype = NO_LOCK;
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
|
rc = SQLITE_IOERR_UNLOCK;
|
||||||
|
pLock->cnt = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1386,21 +1394,23 @@ static int unixUnlock(sqlite3_file *id, int locktype){
|
|||||||
** count reaches zero, close any other file descriptors whose close
|
** count reaches zero, close any other file descriptors whose close
|
||||||
** was deferred because of outstanding locks.
|
** was deferred because of outstanding locks.
|
||||||
*/
|
*/
|
||||||
pOpen = pFile->pOpen;
|
if( rc==SQLITE_OK ){
|
||||||
pOpen->nLock--;
|
pOpen = pFile->pOpen;
|
||||||
assert( pOpen->nLock>=0 );
|
pOpen->nLock--;
|
||||||
if( pOpen->nLock==0 && pOpen->nPending>0 ){
|
assert( pOpen->nLock>=0 );
|
||||||
int i;
|
if( pOpen->nLock==0 && pOpen->nPending>0 ){
|
||||||
for(i=0; i<pOpen->nPending; i++){
|
int i;
|
||||||
close(pOpen->aPending[i]);
|
for(i=0; i<pOpen->nPending; i++){
|
||||||
|
close(pOpen->aPending[i]);
|
||||||
|
}
|
||||||
|
free(pOpen->aPending);
|
||||||
|
pOpen->nPending = 0;
|
||||||
|
pOpen->aPending = 0;
|
||||||
}
|
}
|
||||||
free(pOpen->aPending);
|
|
||||||
pOpen->nPending = 0;
|
|
||||||
pOpen->aPending = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaveMutex();
|
leaveMutex();
|
||||||
pFile->locktype = locktype;
|
if( rc==SQLITE_OK ) pFile->locktype = locktype;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1454,8 +1464,8 @@ static int unixClose(sqlite3_file *id){
|
|||||||
*/
|
*/
|
||||||
typedef struct afpLockingContext afpLockingContext;
|
typedef struct afpLockingContext afpLockingContext;
|
||||||
struct afpLockingContext {
|
struct afpLockingContext {
|
||||||
unsigned long long sharedLockByte; /* Byte offset of shared lock byte */
|
unsigned long long sharedLockByte;
|
||||||
const char *filePath; /* Name of the file */
|
char *filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ByteRangeLockPB2
|
struct ByteRangeLockPB2
|
||||||
@@ -1752,7 +1762,9 @@ static int afpUnixClose(sqlite3_file *id) {
|
|||||||
sqlite3_free(pFile->lockingContext);
|
sqlite3_free(pFile->lockingContext);
|
||||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||||
pFile->dirfd = -1;
|
pFile->dirfd = -1;
|
||||||
|
enterMutex();
|
||||||
close(pFile->h);
|
close(pFile->h);
|
||||||
|
leaveMutex();
|
||||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
memset(pFile, 0, sizeof(unixFile));
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
@@ -1843,7 +1855,10 @@ static int flockUnixClose(sqlite3_file *id) {
|
|||||||
|
|
||||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||||
pFile->dirfd = -1;
|
pFile->dirfd = -1;
|
||||||
|
|
||||||
|
enterMutex();
|
||||||
close(pFile->h);
|
close(pFile->h);
|
||||||
|
leaveMutex();
|
||||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
memset(pFile, 0, sizeof(unixFile));
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
@@ -1953,7 +1968,9 @@ static int dotlockUnixClose(sqlite3_file *id) {
|
|||||||
sqlite3_free(pFile->lockingContext);
|
sqlite3_free(pFile->lockingContext);
|
||||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||||
pFile->dirfd = -1;
|
pFile->dirfd = -1;
|
||||||
|
enterMutex();
|
||||||
close(pFile->h);
|
close(pFile->h);
|
||||||
|
leaveMutex();
|
||||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
memset(pFile, 0, sizeof(unixFile));
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
@@ -1989,7 +2006,9 @@ static int nolockUnixClose(sqlite3_file *id) {
|
|||||||
if( !pFile ) return SQLITE_OK;
|
if( !pFile ) return SQLITE_OK;
|
||||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||||
pFile->dirfd = -1;
|
pFile->dirfd = -1;
|
||||||
|
enterMutex();
|
||||||
close(pFile->h);
|
close(pFile->h);
|
||||||
|
leaveMutex();
|
||||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||||
OpenCounter(-1);
|
OpenCounter(-1);
|
||||||
memset(pFile, 0, sizeof(unixFile));
|
memset(pFile, 0, sizeof(unixFile));
|
||||||
|
|||||||
18
src/pager.c
18
src/pager.c
@@ -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.412 2008/02/26 18:40:12 drh Exp $
|
** @(#) $Id: pager.c,v 1.413 2008/03/07 19:51:14 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -1241,9 +1241,8 @@ static void pager_reset(Pager *pPager){
|
|||||||
static void pager_unlock(Pager *pPager){
|
static void pager_unlock(Pager *pPager){
|
||||||
if( !pPager->exclusiveMode ){
|
if( !pPager->exclusiveMode ){
|
||||||
if( !MEMDB ){
|
if( !MEMDB ){
|
||||||
if( pPager->fd->pMethods ){
|
int rc = osUnlock(pPager->fd, NO_LOCK);
|
||||||
osUnlock(pPager->fd, NO_LOCK);
|
if( rc ) pager_error(pPager, rc);
|
||||||
}
|
|
||||||
pPager->dbSize = -1;
|
pPager->dbSize = -1;
|
||||||
IOTRACE(("UNLOCK %p\n", pPager))
|
IOTRACE(("UNLOCK %p\n", pPager))
|
||||||
|
|
||||||
@@ -1252,7 +1251,7 @@ static void pager_unlock(Pager *pPager){
|
|||||||
** cache can be discarded and the error code safely cleared.
|
** cache can be discarded and the error code safely cleared.
|
||||||
*/
|
*/
|
||||||
if( pPager->errCode ){
|
if( pPager->errCode ){
|
||||||
pPager->errCode = SQLITE_OK;
|
if( rc==SQLITE_OK ) pPager->errCode = SQLITE_OK;
|
||||||
pager_reset(pPager);
|
pager_reset(pPager);
|
||||||
if( pPager->stmtOpen ){
|
if( pPager->stmtOpen ){
|
||||||
sqlite3OsClose(pPager->stfd);
|
sqlite3OsClose(pPager->stfd);
|
||||||
@@ -3384,7 +3383,14 @@ static int pagerSharedLock(Pager *pPager){
|
|||||||
}
|
}
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
pager_unlock(pPager);
|
pager_unlock(pPager);
|
||||||
return ((rc==SQLITE_NOMEM||rc==SQLITE_IOERR_NOMEM)?rc:SQLITE_BUSY);
|
switch( rc ){
|
||||||
|
case SQLITE_NOMEM:
|
||||||
|
case SQLITE_IOERR_UNLOCK:
|
||||||
|
case SQLITE_IOERR_NOMEM:
|
||||||
|
return rc;
|
||||||
|
default:
|
||||||
|
return SQLITE_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pPager->journalOpen = 1;
|
pPager->journalOpen = 1;
|
||||||
pPager->journalStarted = 0;
|
pPager->journalStarted = 0;
|
||||||
|
|||||||
@@ -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.53 2008/02/18 14:47:34 drh Exp $
|
** $Id: test2.c,v 1.54 2008/03/07 19:51:14 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -666,6 +666,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
|||||||
extern int sqlite3_io_error_persist;
|
extern int sqlite3_io_error_persist;
|
||||||
extern int sqlite3_io_error_pending;
|
extern int sqlite3_io_error_pending;
|
||||||
extern int sqlite3_io_error_hit;
|
extern int sqlite3_io_error_hit;
|
||||||
|
extern int sqlite3_io_error_hardhit;
|
||||||
extern int sqlite3_diskfull_pending;
|
extern int sqlite3_diskfull_pending;
|
||||||
extern int sqlite3_diskfull;
|
extern int sqlite3_diskfull;
|
||||||
extern int sqlite3_pager_n_sort_bucket;
|
extern int sqlite3_pager_n_sort_bucket;
|
||||||
@@ -708,6 +709,8 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
|||||||
(char*)&sqlite3_io_error_persist, TCL_LINK_INT);
|
(char*)&sqlite3_io_error_persist, TCL_LINK_INT);
|
||||||
Tcl_LinkVar(interp, "sqlite_io_error_hit",
|
Tcl_LinkVar(interp, "sqlite_io_error_hit",
|
||||||
(char*)&sqlite3_io_error_hit, TCL_LINK_INT);
|
(char*)&sqlite3_io_error_hit, TCL_LINK_INT);
|
||||||
|
Tcl_LinkVar(interp, "sqlite_io_error_hardhit",
|
||||||
|
(char*)&sqlite3_io_error_hardhit, TCL_LINK_INT);
|
||||||
Tcl_LinkVar(interp, "sqlite_diskfull_pending",
|
Tcl_LinkVar(interp, "sqlite_diskfull_pending",
|
||||||
(char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
|
(char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
|
||||||
Tcl_LinkVar(interp, "sqlite_diskfull",
|
Tcl_LinkVar(interp, "sqlite_diskfull",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
# The tests in this file use special facilities that are only
|
# The tests in this file use special facilities that are only
|
||||||
# available in the SQLite test fixture.
|
# available in the SQLite test fixture.
|
||||||
#
|
#
|
||||||
# $Id: ioerr2.test,v 1.6 2007/09/12 17:01:45 danielk1977 Exp $
|
# $Id: ioerr2.test,v 1.7 2008/03/07 19:51:15 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -52,7 +52,7 @@ proc check_db {testname} {
|
|||||||
# connection. Otherwise, try a ROLLBACK, in case a transaction
|
# connection. Otherwise, try a ROLLBACK, in case a transaction
|
||||||
# is still active.
|
# is still active.
|
||||||
set rc [catch {execsql {PRAGMA integrity_check}} msg]
|
set rc [catch {execsql {PRAGMA integrity_check}} msg]
|
||||||
if {$rc && $msg eq "disk I/O error"} {
|
if {$rc && ($msg eq "disk I/O error" || $msg eq "database is locked")} {
|
||||||
db close
|
db close
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
set refcnt 0
|
set refcnt 0
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
# This file implements some common TCL routines used for regression
|
# This file implements some common TCL routines used for regression
|
||||||
# testing the SQLite library
|
# testing the SQLite library
|
||||||
#
|
#
|
||||||
# $Id: tester.tcl,v 1.105 2008/02/16 16:21:46 drh Exp $
|
# $Id: tester.tcl,v 1.106 2008/03/07 19:51:15 drh Exp $
|
||||||
|
|
||||||
|
|
||||||
set tcl_precision 15
|
set tcl_precision 15
|
||||||
@@ -526,7 +526,10 @@ proc do_ioerr_test {testname args} {
|
|||||||
# there are at least N IO operations performed by SQLite as
|
# there are at least N IO operations performed by SQLite as
|
||||||
# a result of the script, the Nth will fail.
|
# a result of the script, the Nth will fail.
|
||||||
do_test $testname.$n.3 {
|
do_test $testname.$n.3 {
|
||||||
|
set ::sqlite_io_error_hit 0
|
||||||
|
set ::sqlite_io_error_hardhit 0
|
||||||
set r [catch $::ioerrorbody msg]
|
set r [catch $::ioerrorbody msg]
|
||||||
|
set ::errseen $r
|
||||||
set rc [sqlite3_errcode $::DB]
|
set rc [sqlite3_errcode $::DB]
|
||||||
if {$::ioerropts(-erc)} {
|
if {$::ioerropts(-erc)} {
|
||||||
# If we are in extended result code mode, make sure all of the
|
# If we are in extended result code mode, make sure all of the
|
||||||
@@ -558,6 +561,9 @@ proc do_ioerr_test {testname args} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set s [expr $::sqlite_io_error_hit==0]
|
set s [expr $::sqlite_io_error_hit==0]
|
||||||
|
if {$::sqlite_io_error_hit>$::sqlite_io_error_hardhit && $r==0} {
|
||||||
|
set r 1
|
||||||
|
}
|
||||||
set ::sqlite_io_error_hit 0
|
set ::sqlite_io_error_hit 0
|
||||||
|
|
||||||
# One of two things must have happened. either
|
# One of two things must have happened. either
|
||||||
@@ -569,7 +575,7 @@ proc do_ioerr_test {testname args} {
|
|||||||
|
|
||||||
# If an IO error occured, then the checksum of the database should
|
# If an IO error occured, then the checksum of the database should
|
||||||
# be the same as before the script that caused the IO error was run.
|
# be the same as before the script that caused the IO error was run.
|
||||||
if {$::go && $::ioerropts(-cksum)} {
|
if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-cksum)} {
|
||||||
do_test $testname.$n.4 {
|
do_test $testname.$n.4 {
|
||||||
catch {db close}
|
catch {db close}
|
||||||
set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db]
|
set ::DB [sqlite3 db test.db; sqlite3_connection_pointer db]
|
||||||
@@ -577,6 +583,7 @@ proc do_ioerr_test {testname args} {
|
|||||||
} $checksum
|
} $checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set ::sqlite_io_error_hardhit 0
|
||||||
set ::sqlite_io_error_pending 0
|
set ::sqlite_io_error_pending 0
|
||||||
if {[info exists ::ioerropts(-cleanup)]} {
|
if {[info exists ::ioerropts(-cleanup)]} {
|
||||||
catch $::ioerropts(-cleanup)
|
catch $::ioerropts(-cleanup)
|
||||||
|
|||||||
Reference in New Issue
Block a user