-C Fix\sa\sproblem\sin\sthe\sunix\sVFS\simplementation\sof\sxNextSystemCall().\sAlso\ssome\stypos\sthat\sprevent\scompilation\swhen\sHAVE_POSIX_FALLOCATE\sis\sdefined.
-D 2011-03-29T10:04:23
+C Fix\sa\sproblem\swhereby\sfollowing\san\sIO\serror\sin\sCommitPhaseTwo()\sof\sa\smulti-file\stransaction\sthe\sb-tree\slayer\scould\sbe\sleft\sin\sTRANS_WRITE\sstate,\scausing\sproblems\slater\son.
+D 2011-03-29T15:40:55.407
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
-F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
+F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk 7e4d4d0433c9cbfd906c6451a7cc50310a8f4555
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F src/analyze.c a038162344265ac21dfb24b3fcc06c666ebb9c07
F src/attach.c 438ea6f6b5d5961c1f49b737f2ce0f14ce7c6877
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
-F src/backup.c 6728d6d48d55b449af76a3e51c0808849cb32a2e
+F src/backup.c 537f89c7ef5021cb580f31f782e556ffffcb2ed1
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
-F src/btree.c 43302cc4f3de6479b90fa6bb271b65d86333d00e
-F src/btree.h e2f2cd9933bf30724f53ffa12c4c5a3a864bbd6e
+F src/btree.c 2b9c81ff64da339a67dda4f94c0d763627be0b67
+F src/btree.h 8d36f774ec4b1d0027b8966f8c03d9a72a518c14
F src/btreeInt.h 20f73dc93b1eeb83afd7259fbc6bd7dcf2df7fe4
F src/build.c 6c490fe14dedb094a202f559e3b29a276abffcf8
F src/callback.c 5069f224882cbdccd559f591271d28d7f37745bc
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
F src/test_stat.c f682704b5d1ba8e1d4e7e882a6d7922e2dcf066c
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
-F src/test_syscall.c b2b3aef993253395da25d564a920014cc3673f09
+F src/test_syscall.c bbdc88d0a5e42d0c35eaff8ae7ec86e8867f5543
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
F src/test_vfs.c 2ed8853c1e51ac6f9ea091f7ce4e0d618bba8b86
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
F src/vdbeInt.h e1c6254641168507d25b46affb6dfb53c782f553
F src/vdbeapi.c a09ad9164cafc505250d5dd6b69660c960f1308c
-F src/vdbeaux.c cfd3f3ac674691ba1166ceb9a2698b0d00b2ef91
+F src/vdbeaux.c 9211dfa7d79d94d4e50714bfd0497ff3588a739d
F src/vdbeblob.c c3ccb7c8732858c680f442932e66ad06bb036562
F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5
F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
F test/fts3fault.test f83e556465bb69dc8bc676339eca408dce4ca246
-F test/fts3fault2.test f275554f4a4fc7abf71e2975a9d6f4693f390526
+F test/fts3fault2.test dc96203af6ba31ce20163fc35460e1556e8edf4d
F test/fts3malloc.test 9c8cc3f885bb4dfc66d0460c52f68f45e4710d1b
F test/fts3matchinfo.test cc0b009edbbf575283d5fdb53271179e0d8019ba
F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
-F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
+F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
-F test/syscall.test 2f3e4e2cf91c3b870c4eac37f62c61208a199403
-F test/sysfault.test 63144f0000167f12676adccee2a0db45eb5c2314
+F test/syscall.test 5ae4b3d4f2aca2ef3c3a777f619e0c6b0cf592aa
+F test/sysfault.test 359ea90a58788c867ac0f9cb52431f56ed975672
F test/table.test 04ba066432430657712d167ebf28080fe878d305
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 7270f80ac5dd17b979f1f790b2dfcf811866c1dc
-R 667989871349daf241bf6e2f9ef88c3d
+P bc6cce81565b17f886478bd51500bba2ed11ec1d
+R 4ba5c752b69008d11d64e0bac5b06138
U dan
-Z e094d9a9a392624fe79d654e33f9ed32
+Z d0374b5c64afa57baa2ab5bac0bd8f73
-bc6cce81565b17f886478bd51500bba2ed11ec1d
\ No newline at end of file
+dbe569a099c2855480e35c0cc4d9332821ad80da
\ No newline at end of file
/* Finish committing the transaction to the destination database. */
if( SQLITE_OK==rc
- && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest))
+ && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
){
rc = SQLITE_DONE;
}
if( bCloseTrans ){
TESTONLY( int rc2 );
TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
- TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc);
+ TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0);
assert( rc2==SQLITE_OK );
}
** the rollback journal (which causes the transaction to commit) and
** drop locks.
**
+** Normally, if an error occurs while the pager layer is attempting to
+** finalize the underlying journal file, this function returns an error and
+** the upper layer will attempt a rollback. However, if the second argument
+** is non-zero then this b-tree transaction is part of a multi-file
+** transaction. In this case, the transaction has already been committed
+** (by deleting a master journal file) and the caller will ignore this
+** functions return code. So, even if an error occurs in the pager layer,
+** reset the b-tree objects internal state to indicate that the write
+** transaction has been closed. This is quite safe, as the pager will have
+** transitioned to the error state.
+**
** This will release the write lock on the database file. If there
** are no active cursors, it also releases the read lock.
*/
-int sqlite3BtreeCommitPhaseTwo(Btree *p){
+int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){
if( p->inTrans==TRANS_NONE ) return SQLITE_OK;
sqlite3BtreeEnter(p);
assert( pBt->inTransaction==TRANS_WRITE );
assert( pBt->nTransaction>0 );
rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
- if( rc!=SQLITE_OK ){
+ if( rc!=SQLITE_OK && bCleanup==0 ){
sqlite3BtreeLeave(p);
return rc;
}
sqlite3BtreeEnter(p);
rc = sqlite3BtreeCommitPhaseOne(p, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeCommitPhaseTwo(p);
+ rc = sqlite3BtreeCommitPhaseTwo(p, 0);
}
sqlite3BtreeLeave(p);
return rc;
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int);
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
-int sqlite3BtreeCommitPhaseTwo(Btree*);
+int sqlite3BtreeCommitPhaseTwo(Btree*, int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*);
int sqlite3BtreeBeginStmt(Btree*,int);
/* 3 */ { "getcwd", (sqlite3_syscall_ptr)ts_getcwd, 0, 0, 0 },
/* 4 */ { "stat", (sqlite3_syscall_ptr)ts_stat, 0, 0, 0 },
/* 5 */ { "fstat", (sqlite3_syscall_ptr)ts_fstat, 0, 0, 0 },
- /* 6 */ { "ftruncate", (sqlite3_syscall_ptr)ts_ftruncate, 0, 0, 0 },
+ /* 6 */ { "ftruncate", (sqlite3_syscall_ptr)ts_ftruncate, 0, EIO, 0 },
/* 7 */ { "fcntl", (sqlite3_syscall_ptr)ts_fcntl, 0, 0, 0 },
/* 8 */ { "read", (sqlite3_syscall_ptr)ts_read, 0, 0, 0 },
/* 9 */ { "pread", (sqlite3_syscall_ptr)ts_pread, 0, 0, 0 },
#define orig_fchmod ((int(*)(int,mode_t))aSyscall[14].xOrig)
#define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig)
-
/*
** This function is called exactly once from within each invocation of a
** system call wrapper in this file. It returns 1 if the function should
** A wrapper around ftruncate().
*/
static int ts_ftruncate(int fd, off_t n){
- if( tsIsFail() ){
+ if( tsIsFailErrno("ftruncate") ){
return -1;
}
return orig_ftruncate(fd, n);
int i;
} aErrno[] = {
{ "EACCES", EACCES },
+ { "EINTR", EINTR },
+ { "EIO", EIO },
{ 0, 0 }
};
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
- rc = sqlite3BtreeCommitPhaseTwo(pBt);
+ rc = sqlite3BtreeCommitPhaseTwo(pBt, 0);
}
}
if( rc==SQLITE_OK ){
for(i=0; i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
- sqlite3BtreeCommitPhaseTwo(pBt);
+ sqlite3BtreeCommitPhaseTwo(pBt, 1);
}
}
sqlite3EndBenignMalloc();
source $testdir/tester.tcl
set ::testprefix fts3fault2
+# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
+ifcapable !fts3 { finish_test ; return }
+
do_test 1.0 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts4(x);
if {[test_syscall exists fallocate]} {lappend syscall_list fallocate}
do_test 3.1 { test_syscall list } $syscall_list
+#-------------------------------------------------------------------------
+# This test verifies that if a call to open() fails and errno is set to
+# EINTR, the call is retried. If it succeeds, execution continues as if
+# nothing happened.
+#
+test_syscall reset
+forcedelete test.db2
+do_execsql_test 4.1 {
+ CREATE TABLE t1(x, y);
+ INSERT INTO t1 VALUES(1, 2);
+ ATTACH 'test.db2' AS aux;
+ CREATE TABLE aux.t2(x, y);
+ INSERT INTO t2 VALUES(3, 4);
+}
+
+db_save_and_close
+test_syscall install open
+foreach jrnl [list wal delete] {
+ for {set i 1} {$i < 20} {incr i} {
+ db_restore_and_reopen
+ test_syscall fault $i 0
+ test_syscall errno open EINTR
+
+ do_test 4.2.$jrnl.$i {
+ sqlite3 db test.db
+ execsql { ATTACH 'test.db2' AS aux }
+ execsql "PRAGMA main.journal_mode = $jrnl"
+ execsql "PRAGMA aux.journal_mode = $jrnl"
+ execsql {
+ BEGIN;
+ INSERT INTO t1 VALUES(5, 6);
+ INSERT INTO t2 VALUES(7, 8);
+ COMMIT;
+ }
+
+ db close
+ sqlite3 db test.db
+ execsql { ATTACH 'test.db2' AS aux }
+ execsql {
+ SELECT * FROM t1;
+ SELECT * FROM t2;
+ }
+ } {1 2 5 6 3 4 7 8}
+ }
+
+}
+
+
+
finish_test
{1 {attempt to write a readonly database}}
}
+#-------------------------------------------------------------------------
+# Check that a single EINTR error does not affect processing.
+#
+proc vfsfault_install {} {
+ test_syscall reset
+ test_syscall install {open ftruncate close}
+}
+
+forcedelete test.db test.db2
+sqlite3 db test.db
+do_test 2.setup {
+ execsql {
+ CREATE TABLE t1(a, b, c, PRIMARY KEY(a));
+ INSERT INTO t1 VALUES('abc', 'def', 'ghi');
+ ATTACH 'test.db2' AS 'aux';
+ CREATE TABLE aux.t2(x);
+ INSERT INTO t2 VALUES(1);
+ }
+ faultsim_save_and_close
+} {}
+
+do_faultsim_test 2.1 -faults vfsfault-transient -prep {
+ catch { db close }
+ faultsim_restore
+} -body {
+ test_syscall errno open EINTR
+ test_syscall errno ftruncate EINTR
+ test_syscall errno close EINTR
+
+ sqlite3 db test.db
+ set res [db eval {
+ ATTACH 'test.db2' AS 'aux';
+ SELECT * FROM t1;
+ PRAGMA journal_mode = truncate;
+ BEGIN;
+ INSERT INTO t1 VALUES('jkl', 'mno', 'pqr');
+ UPDATE t2 SET x = 2;
+ COMMIT;
+ SELECT * FROM t1;
+ SELECT * FROM t2;
+ }]
+ db close
+ set res
+} -test {
+ faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}}
+}
+
+do_faultsim_test 2.2 -faults vfsfault-* -prep {
+ catch { db close }
+ faultsim_restore
+} -body {
+ sqlite3 db test.db
+ set res [db eval {
+ ATTACH 'test.db2' AS 'aux';
+ SELECT * FROM t1;
+ PRAGMA journal_mode = truncate;
+ BEGIN;
+ INSERT INTO t1 VALUES('jkl', 'mno', 'pqr');
+ UPDATE t2 SET x = 2;
+ COMMIT;
+ SELECT * FROM t1;
+ SELECT * FROM t2;
+ }]
+ db close
+ set res
+} -test {
+ faultsim_test_result {0 {abc def ghi truncate abc def ghi jkl mno pqr 2}} \
+ {1 {unable to open database file}} \
+ {1 {unable to open database: test.db2}} \
+ {1 {attempt to write a readonly database}} \
+ {1 {disk I/O error}}
+}
+
+
finish_test