aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/btree.c56
-rw-r--r--src/pager.c6
2 files changed, 37 insertions, 25 deletions
diff --git a/src/btree.c b/src/btree.c
index 7324b37fd..608f5e254 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.331 2006/11/30 13:05:29 drh Exp $
+** $Id: btree.c,v 1.332 2006/12/18 18:34:51 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -421,7 +421,8 @@ struct BtCursor {
*/
#if SQLITE_TEST
# define TRACE(X) if( sqlite3_btree_trace )\
- { sqlite3DebugPrintf X; fflush(stdout); }
+/* { sqlite3DebugPrintf X; fflush(stdout); } */ \
+{ printf X; fflush(stdout); }
int sqlite3_btree_trace=0; /* True to enable tracing */
#else
# define TRACE(X)
@@ -3569,14 +3570,14 @@ static int allocatePage(
int rc;
int n; /* Number of pages on the freelist */
int k; /* Number of leaves on the trunk of the freelist */
+ MemPage *pTrunk = 0;
+ MemPage *pPrevTrunk = 0;
pPage1 = pBt->pPage1;
n = get4byte(&pPage1->aData[36]);
if( n>0 ){
/* There are pages on the freelist. Reuse one of those pages. */
- MemPage *pTrunk = 0;
Pgno iTrunk;
- MemPage *pPrevTrunk = 0;
u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
/* If the 'exact' parameter was true and a query of the pointer-map
@@ -3617,16 +3618,8 @@ static int allocatePage(
}
rc = getPage(pBt, iTrunk, &pTrunk);
if( rc ){
- releasePage(pPrevTrunk);
- return rc;
- }
-
- /* TODO: This should move to after the loop? */
- rc = sqlite3pager_write(pTrunk->aData);
- if( rc ){
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- return rc;
+ pTrunk = 0;
+ goto end_allocate_page;
}
k = get4byte(&pTrunk->aData[4]);
@@ -3635,6 +3628,10 @@ static int allocatePage(
** So extract the trunk page itself and use it as the newly
** allocated page */
assert( pPrevTrunk==0 );
+ rc = sqlite3pager_write(pTrunk->aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
*pPgno = iTrunk;
memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
*ppPage = pTrunk;
@@ -3642,7 +3639,8 @@ static int allocatePage(
TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
}else if( k>pBt->usableSize/4 - 8 ){
/* Value of k is out of range. Database corruption */
- return SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_BKPT;
+ goto end_allocate_page;
#ifndef SQLITE_OMIT_AUTOVACUUM
}else if( searchList && nearby==iTrunk ){
/* The list is being searched and this trunk page is the page
@@ -3651,6 +3649,10 @@ static int allocatePage(
assert( *pPgno==iTrunk );
*ppPage = pTrunk;
searchList = 0;
+ rc = sqlite3pager_write(pTrunk->aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
if( k==0 ){
if( !pPrevTrunk ){
memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
@@ -3666,26 +3668,26 @@ static int allocatePage(
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
rc = getPage(pBt, iNewTrunk, &pNewTrunk);
if( rc!=SQLITE_OK ){
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- return rc;
+ goto end_allocate_page;
}
rc = sqlite3pager_write(pNewTrunk->aData);
if( rc!=SQLITE_OK ){
releasePage(pNewTrunk);
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- return rc;
+ goto end_allocate_page;
}
memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
put4byte(&pNewTrunk->aData[4], k-1);
memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
+ releasePage(pNewTrunk);
if( !pPrevTrunk ){
put4byte(&pPage1->aData[32], iNewTrunk);
}else{
+ rc = sqlite3pager_write(pPrevTrunk->aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
put4byte(&pPrevTrunk->aData[0], iNewTrunk);
}
- releasePage(pNewTrunk);
}
pTrunk = 0;
TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
@@ -3695,6 +3697,10 @@ static int allocatePage(
int closest;
Pgno iPage;
unsigned char *aData = pTrunk->aData;
+ rc = sqlite3pager_write(aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
if( nearby>0 ){
int i, dist;
closest = 0;
@@ -3738,8 +3744,8 @@ static int allocatePage(
}
}
releasePage(pPrevTrunk);
+ pPrevTrunk = 0;
}while( searchList );
- releasePage(pTrunk);
}else{
/* There are no pages on the freelist, so create a new page at the
** end of the file */
@@ -3768,6 +3774,10 @@ static int allocatePage(
}
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+
+end_allocate_page:
+ releasePage(pTrunk);
+ releasePage(pPrevTrunk);
return rc;
}
diff --git a/src/pager.c b/src/pager.c
index 7e0293d59..ffadb59d3 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.276 2006/11/23 11:58:44 drh Exp $
+** @(#) $Id: pager.c,v 1.277 2006/12/18 18:34:51 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -31,6 +31,7 @@
** Macros for troubleshooting. Normally turned off
*/
#if 0
+#define sqlite3DebugPrintf printf
#define TRACE1(X) sqlite3DebugPrintf(X)
#define TRACE2(X,Y) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z)
@@ -3335,7 +3336,8 @@ void sqlite3pager_dont_rollback(void *pData){
PgHdr *pPg = DATA_TO_PGHDR(pData);
Pager *pPager = pPg->pPager;
- if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return;
+ assert( pPager->state>=PAGER_RESERVED );
+ if( pPager->journalOpen==0 ) return;
if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
assert( pPager->aInJournal!=0 );