/ Check-in [f99a902f]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fixes for error handling with temp databases. And for errors that occur within OS locking primitives.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: f99a902f9b3d0bf6f607c4ba641b4096fbbef5d5
User & Date: dan 2010-08-05 15:30:22
Context
2010-08-05
16:08
Catch an error code that was not being propagated back to the caller. check-in: 800f4969 user: dan tags: experimental
15:30
Fixes for error handling with temp databases. And for errors that occur within OS locking primitives. check-in: f99a902f user: dan tags: experimental
2010-08-04
19:14
Fix some problems with error recovery introduced while reworking pager state. check-in: 77eaab6f user: dan tags: experimental
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/pager.c.

   341    341   */
   342    342   #define PAGER_UNLOCK      0
   343    343   #define PAGER_SHARED      1   /* same as SHARED_LOCK */
   344    344   #define PAGER_RESERVED    2   /* same as RESERVED_LOCK */
   345    345   #define PAGER_EXCLUSIVE   4   /* same as EXCLUSIVE_LOCK */
   346    346   #define PAGER_SYNCED      5
   347    347   
          348  +#define UNKNOWN_LOCK      (EXCLUSIVE_LOCK+1)
          349  +
   348    350   /*
   349    351   ** A macro used for invoking the codec if there is one
   350    352   */
   351    353   #ifdef SQLITE_HAS_CODEC
   352    354   # define CODEC1(P,D,N,X,E) \
   353    355       if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
   354    356   # define CODEC2(P,D,N,X,E,O) \
................................................................................
   717    719     ** on the file.
   718    720     */
   719    721     assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
   720    722   
   721    723     switch( p->eState ){
   722    724       case PAGER_NONE:
   723    725         assert( !MEMDB );
   724         -      assert( !p->tempFile );
   725    726         assert( pPager->errCode==SQLITE_OK );
   726         -      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
          727  +      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
   727    728         break;
   728    729   
   729    730       case PAGER_READER:
   730    731         assert( pPager->errCode==SQLITE_OK );
          732  +      assert( p->eLock!=UNKNOWN_LOCK );
   731    733         assert( p->eLock>=SHARED_LOCK || p->noReadlock );
   732    734         break;
   733    735   
   734    736       case PAGER_WRITER_INITIAL:
          737  +      assert( p->eLock!=UNKNOWN_LOCK );
   735    738         assert( pPager->errCode==SQLITE_OK );
   736    739         if( !pagerUseWal(pPager) ){
   737    740           assert( p->eLock>=RESERVED_LOCK );
   738    741         }
   739    742         assert( pPager->dbSize==pPager->dbOrigSize );
   740    743         assert( pPager->dbOrigSize==pPager->dbFileSize );
   741    744         assert( pPager->setMaster==0 );
   742    745         break;
   743    746   
   744    747       case PAGER_WRITER_CACHEMOD:
          748  +      assert( p->eLock!=UNKNOWN_LOCK );
   745    749         assert( pPager->errCode==SQLITE_OK );
   746    750         if( !pagerUseWal(pPager) ){
   747    751           /* It is possible that if journal_mode=wal here that neither the
   748    752           ** journal file nor the WAL file are open. This happens during
   749    753           ** a rollback transaction that switches from journal_mode=off
   750    754           ** to journal_mode=wal.
   751    755           */
................................................................................
   755    759                || p->journalMode==PAGER_JOURNALMODE_WAL 
   756    760           );
   757    761         }
   758    762         assert( pPager->dbOrigSize==pPager->dbFileSize );
   759    763         break;
   760    764   
   761    765       case PAGER_WRITER_DBMOD:
          766  +      assert( p->eLock==EXCLUSIVE_LOCK );
   762    767         assert( pPager->errCode==SQLITE_OK );
   763    768         assert( !pagerUseWal(pPager) );
   764         -      assert( p->eLock>=EXCLUSIVE_LOCK || pagerUseWal(pPager) );
          769  +      assert( p->eLock>=EXCLUSIVE_LOCK );
   765    770         assert( isOpen(p->jfd) 
   766    771              || p->journalMode==PAGER_JOURNALMODE_OFF 
   767    772              || p->journalMode==PAGER_JOURNALMODE_WAL 
   768    773         );
   769    774         break;
   770    775   
   771    776       case PAGER_WRITER_FINISHED:
          777  +      assert( p->eLock==EXCLUSIVE_LOCK );
   772    778         assert( pPager->errCode==SQLITE_OK );
   773    779         assert( !pagerUseWal(pPager) );
   774         -      assert( p->eLock>=EXCLUSIVE_LOCK || pagerUseWal(pPager) );
   775    780         assert( isOpen(p->jfd) 
   776    781              || p->journalMode==PAGER_JOURNALMODE_OFF 
   777    782              || p->journalMode==PAGER_JOURNALMODE_WAL 
   778    783         );
   779    784         break;
   780    785   
   781    786       case PAGER_ERROR:
................................................................................
   794    799   /*
   795    800   ** (gdb) printf "%s", print_pager_state(pPager)
   796    801   */
   797    802   static char *print_pager_state(Pager *p){
   798    803     static char zRet[1024];
   799    804   
   800    805     sqlite3_snprintf(1024, zRet,
   801         -      "State:         %s\n"
          806  +      "State:         %s errCode=%d\n"
   802    807         "Lock:          %s\n"
   803    808         "Locking mode:  locking_mode=%s\n"
   804    809         "Journal mode:  journal_mode=%s\n"
   805    810         "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
          811  +      "Journal:       journalOff=%lld journalHdr=%lld\n"
   806    812         , p->eState==PAGER_NONE            ? "NONE" :
   807    813           p->eState==PAGER_READER          ? "READER" :
   808    814           p->eState==PAGER_WRITER_INITIAL  ? "WRITER_INITIAL" :
   809    815           p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
   810    816           p->eState==PAGER_WRITER_DBMOD    ? "WRITER_DBMOD" :
   811    817           p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
   812    818           p->eState==PAGER_ERROR           ? "ERROR" : "?error?"
          819  +      , (int)p->errCode
   813    820         , p->eLock==NO_LOCK         ? "NONE" :
   814    821           p->eLock==RESERVED_LOCK   ? "RESERVED" :
   815    822           p->eLock==EXCLUSIVE_LOCK  ? "EXCLUSIVE" :
   816         -        p->eLock==SHARED_LOCK     ? "SHARED" : "?error?"
          823  +        p->eLock==SHARED_LOCK     ? "SHARED" :
          824  +        p->eLock==UNKNOWN_LOCK    ? "UNKNOWN" : "?error?"
   817    825         , p->exclusiveMode ? "exclusive" : "normal"
   818    826         , p->journalMode==PAGER_JOURNALMODE_MEMORY   ? "memory" :
   819    827           p->journalMode==PAGER_JOURNALMODE_OFF      ? "off" :
   820    828           p->journalMode==PAGER_JOURNALMODE_DELETE   ? "delete" :
   821    829           p->journalMode==PAGER_JOURNALMODE_PERSIST  ? "persist" :
   822    830           p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
   823    831           p->journalMode==PAGER_JOURNALMODE_WAL      ? "wal" : "?error?"
   824    832         , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
          833  +      , p->journalOff, p->journalHdr
   825    834     );
   826    835   
   827    836     return zRet;
   828    837   }
   829    838   #endif
   830    839   
   831    840   /*
................................................................................
   886    895   static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
   887    896     char ac[4];
   888    897     put32bits(ac, val);
   889    898     return sqlite3OsWrite(fd, ac, 4, offset);
   890    899   }
   891    900   
   892    901   /*
   893         -** If file pFd is open, call sqlite3OsUnlock() on it.
          902  +** This function and pagerLockDb() are wrappers around sqlite3OsLock() and
          903  +** sqlite3OsUnlock() that set the Pager.eLock variable to reflect the
          904  +** current lock held on the database file.
   894    905   */
   895         -static int osUnlock(Pager *pPager, int eLock){
          906  +static int pagerUnlockDb(Pager *pPager, int eLock){
   896    907     int rc = SQLITE_OK;
          908  +  assert( !pPager->exclusiveMode );
   897    909     if( isOpen(pPager->fd) ){
   898    910       assert( pPager->eLock>=eLock );
   899    911       assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
   900    912       rc = sqlite3OsUnlock(pPager->fd, eLock);
   901         -    if( rc==SQLITE_OK ){
          913  +    if( pPager->eLock!=UNKNOWN_LOCK ){
   902    914         pPager->eLock = eLock;
   903    915       }
          916  +    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
   904    917     }
   905    918     return rc;
   906    919   }
   907    920   
   908         -static int osLock(Pager *pPager, int eLock){
          921  +static int pagerLockDb(Pager *pPager, int eLock){
   909    922     int rc;
   910    923     assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
   911         -  if( pPager->eLock>=eLock ){
          924  +  if( pPager->eLock>=eLock && pPager->eLock!=UNKNOWN_LOCK ){
   912    925       rc = SQLITE_OK;
   913    926     }else{
   914    927       rc = sqlite3OsLock(pPager->fd, eLock);
   915         -    if( rc==SQLITE_OK ){
          928  +    if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
   916    929         pPager->eLock = eLock;
   917         -      IOTRACE(("LOCK %p %d\n", pPager, locktype))
          930  +      IOTRACE(("LOCK %p %d\n", pPager, eLock))
   918    931       }
   919    932     }
   920    933     return rc;
   921    934   }
   922    935   
   923    936   /*
   924    937   ** This function determines whether or not the atomic-write optimization
................................................................................
  1546   1559     releaseAllSavepoints(pPager);
  1547   1560   
  1548   1561     if( pagerUseWal(pPager) ){
  1549   1562       assert( !isOpen(pPager->jfd) );
  1550   1563       sqlite3WalEndReadTransaction(pPager->pWal);
  1551   1564       pPager->eState = PAGER_NONE;
  1552   1565     }else if( !pPager->exclusiveMode ){
         1566  +    int rc;                       /* Error code returned by pagerUnlockDb() */
  1553   1567       int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
  1554   1568   
  1555   1569       /* If the operating system support deletion of open files, then
  1556   1570       ** close the journal file when dropping the database lock.  Otherwise
  1557   1571       ** another connection with journal_mode=delete might delete the file
  1558   1572       ** out from under us.
  1559   1573       */
................................................................................
  1564   1578       assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
  1565   1579       assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
  1566   1580       if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
  1567   1581        || 1!=(pPager->journalMode & 5)
  1568   1582       ){
  1569   1583         sqlite3OsClose(pPager->jfd);
  1570   1584       }
  1571         -    osUnlock(pPager, NO_LOCK);
         1585  +
         1586  +    rc = pagerUnlockDb(pPager, NO_LOCK);
         1587  +    if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
         1588  +      pPager->eLock = UNKNOWN_LOCK;
         1589  +    }
  1572   1590   
  1573   1591       /* The pager state may be changed from PAGER_ERROR to PAGER_NONE here
  1574   1592       ** without clearing the error code. This is intentional - the error
  1575   1593       ** code is cleared and the cache reset in the block below.
  1576   1594       */
  1577   1595       assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
  1578   1596       pPager->changeCountDone = 0;
  1579   1597       pPager->eState = PAGER_NONE;
  1580         -    IOTRACE(("UNLOCK %p\n", pPager))
  1581   1598     }
  1582   1599   
  1583   1600     /* If Pager.errCode is set, the contents of the pager cache cannot be
  1584   1601     ** trusted. Now that there are no outstanding references to the pager,
  1585   1602     ** it can safely move back to PAGER_NONE state. This happens in both
  1586   1603     ** normal and exclusive-locking mode.
  1587   1604     */
  1588         -  if( pPager->errCode && !pPager->tempFile ){
         1605  +  if( pPager->errCode && !MEMDB ){
  1589   1606       pager_reset(pPager);
  1590         -    pPager->changeCountDone = 0;
         1607  +    pPager->changeCountDone = pPager->tempFile;
  1591   1608       pPager->eState = PAGER_NONE;
  1592   1609       pPager->errCode = SQLITE_OK;
  1593   1610     }
         1611  +
         1612  +  pPager->journalOff = 0;
         1613  +  pPager->journalHdr = 0;
         1614  +  pPager->setMaster = 0;
  1594   1615   }
  1595   1616   
  1596   1617   /*
  1597   1618   ** This function should be called when an IOERR, CORRUPT or FULL error
  1598   1619   ** may have occurred. The first argument is a pointer to the pager 
  1599   1620   ** structure, the second the error-code about to be returned by a pager 
  1600   1621   ** API function. The value returned is a copy of the second argument 
................................................................................
  1748   1769       */
  1749   1770       rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
  1750   1771       assert( rc2==SQLITE_OK );
  1751   1772     }
  1752   1773     if( !pPager->exclusiveMode 
  1753   1774      && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
  1754   1775     ){
  1755         -    rc2 = osUnlock(pPager, SHARED_LOCK);
         1776  +    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
  1756   1777       pPager->changeCountDone = 0;
  1757   1778     }
  1758   1779     pPager->eState = PAGER_READER;
  1759   1780     pPager->setMaster = 0;
  1760   1781   
  1761   1782     return (rc==SQLITE_OK?rc2:rc);
  1762   1783   }
................................................................................
  1930   1951   
  1931   1952     /* If this page has already been played by before during the current
  1932   1953     ** rollback, then don't bother to play it back again.
  1933   1954     */
  1934   1955     if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
  1935   1956       return rc;
  1936   1957     }
  1937         -  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
         1958  +  assert( pPager->eState>=PAGER_WRITER_CACHEMOD 
         1959  +       || (pPager->eState==PAGER_NONE && isMainJrnl)
         1960  +  );
  1938   1961   
  1939   1962     /* When playing back page 1, restore the nReserve setting
  1940   1963     */
  1941   1964     if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
  1942   1965       pPager->nReserve = ((u8*)aData)[20];
  1943   1966       pagerReportSize(pPager);
  1944   1967     }
................................................................................
  1986   2009              (isMainJrnl?"main-journal":"sub-journal")
  1987   2010     ));
  1988   2011     if( isMainJrnl ){
  1989   2012       isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
  1990   2013     }else{
  1991   2014       isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
  1992   2015     }
  1993         -  if( (pPager->eState>=PAGER_WRITER_DBMOD)
         2016  +  if( (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_NONE)
  1994   2017      && isOpen(pPager->fd)
  1995   2018      && isSynced
  1996   2019     ){
  1997   2020       i64 ofst = (pgno-1)*(i64)pPager->pageSize;
  1998   2021       testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
  1999   2022       assert( !pagerUseWal(pPager) );
  2000   2023       rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst);
................................................................................
  2235   2258   **
  2236   2259   ** If successful, return SQLITE_OK. If an IO error occurs while modifying
  2237   2260   ** the database file, return the error code to the caller.
  2238   2261   */
  2239   2262   static int pager_truncate(Pager *pPager, Pgno nPage){
  2240   2263     int rc = SQLITE_OK;
  2241   2264     assert( pPager->eState!=PAGER_ERROR );
  2242         -  if( pPager->eState>=PAGER_WRITER_DBMOD && isOpen(pPager->fd) ){
         2265  +  assert( pPager->eState!=PAGER_READER );
         2266  +  
         2267  +  if( isOpen(pPager->fd) 
         2268  +   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_NONE) 
         2269  +  ){
  2243   2270       i64 currentSize, newSize;
  2244   2271       /* TODO: Is it safe to use Pager.dbFileSize here? */
  2245   2272       rc = sqlite3OsFileSize(pPager->fd, &currentSize);
  2246   2273       newSize = pPager->pageSize*(i64)nPage;
  2247   2274       if( rc==SQLITE_OK && currentSize!=newSize ){
  2248   2275         if( currentSize>newSize ){
  2249   2276           rc = sqlite3OsTruncate(pPager->fd, newSize);
................................................................................
  2813   2840       }else{
  2814   2841         rc = sqlite3OsAccess(
  2815   2842             pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
  2816   2843         );
  2817   2844       }
  2818   2845       if( rc==SQLITE_OK ){
  2819   2846         if( isWal ){
  2820         -        assert( sqlite3PcachePagecount(pPager->pPCache)==0 );
         2847  +        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
  2821   2848           rc = sqlite3PagerOpenWal(pPager, 0);
  2822   2849           if( rc==SQLITE_OK ){
  2823   2850             rc = pagerBeginReadTransaction(pPager);
  2824   2851           }
  2825   2852         }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
  2826   2853           pPager->journalMode = PAGER_JOURNALMODE_DELETE;
  2827   2854         }
................................................................................
  3140   3167           rc = sqlite3OsFileSize(pPager->fd, &nByte);
  3141   3168           if( rc!=SQLITE_OK ) return rc;
  3142   3169         }
  3143   3170         pNew = (char *)sqlite3PageMalloc(pageSize);
  3144   3171         if( !pNew ){
  3145   3172           rc = SQLITE_NOMEM;
  3146   3173         }else{
  3147         -        assert( pPager->eState==PAGER_NONE || pPager->eState==PAGER_READER );
  3148   3174           pager_reset(pPager);
  3149   3175           pPager->dbSize = nByte/pageSize;
  3150   3176           pPager->pageSize = pageSize;
  3151   3177           sqlite3PageFree(pPager->pTmpSpace);
  3152   3178           pPager->pTmpSpace = pNew;
  3153   3179           sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
  3154   3180         }
................................................................................
  3293   3319     ** sqlite3PagerSetBusyhandler().
  3294   3320     */
  3295   3321     assert( (pPager->eLock>=locktype)
  3296   3322          || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
  3297   3323          || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
  3298   3324     );
  3299   3325   
  3300         -  if( pPager->eLock>=locktype ){
  3301         -    rc = SQLITE_OK;
  3302         -  }else{
  3303         -    do {
  3304         -      rc = osLock(pPager, locktype);
  3305         -    }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
  3306         -  }
         3326  +  do {
         3327  +    rc = pagerLockDb(pPager, locktype);
         3328  +  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
  3307   3329     return rc;
  3308   3330   }
  3309   3331   
  3310   3332   /*
  3311   3333   ** Function assertTruncateConstraint(pPager) checks that one of the 
  3312   3334   ** following is true for all dirty pages currently in the page-cache:
  3313   3335   **
................................................................................
  4296   4318         ** a RESERVED lock to avoid race conditions and to avoid violating
  4297   4319         ** [H33020].
  4298   4320         */
  4299   4321         rc = pagerPagecount(pPager, &nPage);
  4300   4322         if( rc==SQLITE_OK ){
  4301   4323           if( nPage==0 ){
  4302   4324             sqlite3BeginBenignMalloc();
  4303         -          if( osLock(pPager, RESERVED_LOCK)==SQLITE_OK ){
         4325  +          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
  4304   4326               sqlite3OsDelete(pVfs, pPager->zJournal, 0);
  4305         -            osUnlock(pPager, SHARED_LOCK);
         4327  +            pagerUnlockDb(pPager, SHARED_LOCK);
  4306   4328             }
  4307   4329             sqlite3EndBenignMalloc();
  4308   4330           }else{
  4309   4331             /* The journal file exists and no other connection has a reserved
  4310   4332             ** or greater lock on the database file. Now check that there is
  4311   4333             ** at least one non-zero bytes at the start of the journal file.
  4312   4334             ** If there is, then we consider this journal to be hot. If not, 
................................................................................
  4384   4406   
  4385   4407     /* This routine is only called from b-tree and only when there are no
  4386   4408     ** outstanding pages. This implies that the pager state should either
  4387   4409     ** be NONE or READER. READER is only possible if the pager is or was in 
  4388   4410     ** exclusive access mode.
  4389   4411     */
  4390   4412     assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
         4413  +  assert( assert_pager_state(pPager) );
  4391   4414     assert( pPager->eState==PAGER_NONE || pPager->eState==PAGER_READER );
  4392         -  assert( assert_pager_state(pPager) );
  4393   4415     if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
  4394   4416   
  4395   4417     if( !pagerUseWal(pPager) && pPager->eState==PAGER_NONE ){
  4396   4418       int bHotJournal = 1;          /* True if there exists a hot journal-file */
  4397   4419   
  4398         -    assert( !MEMDB && !pPager->tempFile );
         4420  +    assert( !MEMDB );
  4399   4421       assert( pPager->noReadlock==0 || pPager->readOnly );
  4400   4422   
  4401   4423       if( pPager->noReadlock==0 ){
  4402   4424         rc = pager_wait_on_lock(pPager, SHARED_LOCK);
  4403   4425         if( rc!=SQLITE_OK ){
  4404   4426           assert( pPager->eLock==PAGER_UNLOCK );
  4405   4427           goto failed;
................................................................................
  4427   4449         ** other process attempting to access the database file will get to 
  4428   4450         ** this point in the code and fail to obtain its own EXCLUSIVE lock 
  4429   4451         ** on the database file.
  4430   4452         **
  4431   4453         ** Unless the pager is in locking_mode=exclusive mode, the lock is
  4432   4454         ** downgraded to SHARED_LOCK before this function returns.
  4433   4455         */
  4434         -      rc = osLock(pPager, EXCLUSIVE_LOCK);
         4456  +      rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
  4435   4457         if( rc!=SQLITE_OK ){
  4436   4458           goto failed;
  4437   4459         }
  4438   4460    
  4439   4461         /* If it is not already open and the file exists on disk, open the 
  4440   4462         ** journal for read/write access. Write access is required because 
  4441   4463         ** in exclusive-access mode the file descriptor will be kept open 
................................................................................
  4462   4484             assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
  4463   4485             if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
  4464   4486               rc = SQLITE_CANTOPEN_BKPT;
  4465   4487               sqlite3OsClose(pPager->jfd);
  4466   4488             }
  4467   4489           }
  4468   4490         }
  4469         -      if( rc!=SQLITE_OK ){
  4470         -        goto failed;
  4471         -      }
  4472         -
  4473         -      /* Reset the journal status fields to indicates that we have no
  4474         -      ** rollback journal at this time. */
  4475         -      pPager->journalOff = 0;
  4476         -      pPager->setMaster = 0;
  4477         -      pPager->journalHdr = 0;
  4478         - 
  4479         -      /* Make sure the journal file has been synced to disk. */
  4480   4491    
  4481   4492         /* Playback and delete the journal.  Drop the database write
  4482   4493         ** lock and reacquire the read lock. Purge the cache before
  4483   4494         ** playing back the hot-journal so that we don't end up with
  4484   4495         ** an inconsistent cache.  Sync the hot journal before playing
  4485   4496         ** it back since the process that crashed and left the hot journal
  4486   4497         ** probably did not sync it and we are required to always sync
  4487   4498         ** the journal before playing it back.
  4488         -      **
  4489         -      ** Even if an error occurs while syncing or rolling back the 
  4490         -      ** hot-journal, there is no need to enter the ERROR state here, as
  4491         -      ** the pager never left state NONE anyhow.
  4492   4499         */
  4493   4500         if( isOpen(pPager->jfd) ){
         4501  +        assert( rc==SQLITE_OK );
  4494   4502           rc = pagerSyncHotJournal(pPager);
  4495   4503           if( rc==SQLITE_OK ){
  4496         -          assert( pPager->eState==PAGER_NONE );
  4497         -          pPager->eState = PAGER_WRITER_FINISHED;
  4498   4504             rc = pager_playback(pPager, 1);
  4499   4505             pPager->eState = PAGER_NONE;
  4500   4506           }
  4501         -        if( rc!=SQLITE_OK ){
  4502         -          goto failed;
  4503         -        }
  4504         -      }else{
  4505         -        osUnlock(pPager, SHARED_LOCK);
         4507  +      }else if( !pPager->exclusiveMode ){
         4508  +        pagerUnlockDb(pPager, SHARED_LOCK);
         4509  +      }
         4510  +
         4511  +      if( rc!=SQLITE_OK ){
         4512  +        pager_error(pPager, rc);
         4513  +        goto failed;
  4506   4514         }
  4507   4515   
  4508   4516         assert( pPager->eState==PAGER_NONE );
  4509   4517         assert( (pPager->eLock==SHARED_LOCK)
  4510   4518              || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
  4511   4519         );
  4512   4520       }
  4513   4521   
  4514         -    if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){
         4522  +    if( !pPager->tempFile 
         4523  +     && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0) 
         4524  +    ){
  4515   4525         /* The shared-lock has just been acquired on the database file
  4516   4526         ** and there are already pages in the cache (from a previous
  4517   4527         ** read or write transaction).  Check to see if the database
  4518   4528         ** has been modified.  If the database has changed, flush the
  4519   4529         ** cache.
  4520   4530         **
  4521   4531         ** Database changes is detected by looking at 15 bytes beginning
................................................................................
  4902   4912       assert( pPager->pInJournal==0 );
  4903   4913   
  4904   4914       if( pagerUseWal(pPager) ){
  4905   4915         /* If the pager is configured to use locking_mode=exclusive, and an
  4906   4916         ** exclusive lock on the database is not already held, obtain it now.
  4907   4917         */
  4908   4918         if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
  4909         -        rc = osLock(pPager, EXCLUSIVE_LOCK);
         4919  +        rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
  4910   4920           if( rc!=SQLITE_OK ){
  4911   4921             return rc;
  4912   4922           }
  4913   4923           sqlite3WalExclusiveMode(pPager->pWal, 1);
  4914   4924         }
  4915   4925   
  4916   4926         /* Grab the write lock on the log file. If successful, upgrade to
................................................................................
  4921   4931         rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
  4922   4932       }else{
  4923   4933         /* Obtain a RESERVED lock on the database file. If the exFlag parameter
  4924   4934         ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
  4925   4935         ** busy-handler callback can be used when upgrading to the EXCLUSIVE
  4926   4936         ** lock, but not when obtaining the RESERVED lock.
  4927   4937         */
  4928         -      rc = osLock(pPager, RESERVED_LOCK);
         4938  +      rc = pagerLockDb(pPager, RESERVED_LOCK);
  4929   4939         if( rc==SQLITE_OK && exFlag ){
  4930   4940           rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
  4931   4941         }
  4932   4942       }
  4933   4943   
  4934   4944   
  4935   4945       if( rc==SQLITE_OK ){
................................................................................
  5870   5880   ** then savepoint iSavepoint is also destroyed.
  5871   5881   **
  5872   5882   ** This function may return SQLITE_NOMEM if a memory allocation fails,
  5873   5883   ** or an IO error code if an IO error occurs while rolling back a 
  5874   5884   ** savepoint. If no errors occur, SQLITE_OK is returned.
  5875   5885   */ 
  5876   5886   int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
  5877         -  int rc = SQLITE_OK;
         5887  +  int rc = pPager->errCode;       /* Return code */
  5878   5888   
  5879   5889     assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
  5880   5890     assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
  5881   5891   
  5882         -  if( iSavepoint<pPager->nSavepoint ){
         5892  +  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
  5883   5893       int ii;            /* Iterator variable */
  5884   5894       int nNew;          /* Number of remaining savepoints after this op. */
  5885   5895   
  5886   5896       /* Figure out how many savepoints will still be active after this
  5887   5897       ** operation. Store this value in nNew. Then free resources associated 
  5888   5898       ** with any savepoints that are destroyed by this operation.
  5889   5899       */
................................................................................
  5911   5921       ** the database file, so the playback operation can be skipped.
  5912   5922       */
  5913   5923       else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
  5914   5924         PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
  5915   5925         rc = pagerPlaybackSavepoint(pPager, pSavepoint);
  5916   5926         assert(rc!=SQLITE_DONE);
  5917   5927       }
  5918         -  
  5919   5928     }
         5929  +
  5920   5930     return rc;
  5921   5931   }
  5922   5932   
  5923   5933   /*
  5924   5934   ** Return the full pathname of the database file.
  5925   5935   */
  5926   5936   const char *sqlite3PagerFilename(Pager *pPager){
................................................................................
  6087   6097         sqlite3PcacheDrop(pPgOld);
  6088   6098       }
  6089   6099     }
  6090   6100   
  6091   6101     origPgno = pPg->pgno;
  6092   6102     sqlite3PcacheMove(pPg, pgno);
  6093   6103     sqlite3PcacheMakeDirty(pPg);
         6104  +
         6105  +  /* For an in-memory database, make sure the original page continues
         6106  +  ** to exist, in case the transaction needs to roll back.  Use pPgOld
         6107  +  ** as the original page since it has already been allocated.
         6108  +  */
         6109  +  if( MEMDB ){
         6110  +    assert( pPgOld );
         6111  +    sqlite3PcacheMove(pPgOld, origPgno);
         6112  +    sqlite3PagerUnref(pPgOld);
         6113  +  }
  6094   6114   
  6095   6115     if( needSyncPgno ){
  6096   6116       /* If needSyncPgno is non-zero, then the journal file needs to be 
  6097   6117       ** sync()ed before any data is written to database file page needSyncPgno.
  6098   6118       ** Currently, no such page exists in the page-cache and the 
  6099   6119       ** "is journaled" bitvec flag has been set. This needs to be remedied by
  6100   6120       ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
................................................................................
  6117   6137         return rc;
  6118   6138       }
  6119   6139       pPgHdr->flags |= PGHDR_NEED_SYNC;
  6120   6140       sqlite3PcacheMakeDirty(pPgHdr);
  6121   6141       sqlite3PagerUnref(pPgHdr);
  6122   6142     }
  6123   6143   
  6124         -  /*
  6125         -  ** For an in-memory database, make sure the original page continues
  6126         -  ** to exist, in case the transaction needs to roll back.  Use pPgOld
  6127         -  ** as the original page since it has already been allocated.
  6128         -  */
  6129         -  if( MEMDB ){
  6130         -    sqlite3PcacheMove(pPgOld, origPgno);
  6131         -    sqlite3PagerUnref(pPgOld);
  6132         -  }
  6133         -
  6134   6144     return SQLITE_OK;
  6135   6145   }
  6136   6146   #endif
  6137   6147   
  6138   6148   /*
  6139   6149   ** Return a pointer to the data for the specified page.
  6140   6150   */
................................................................................
  6217   6227       assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
  6218   6228       if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
  6219   6229         eMode = eOld;
  6220   6230       }
  6221   6231     }
  6222   6232   
  6223   6233     if( eMode!=eOld ){
  6224         -    /* When changing between rollback modes, close the journal file prior
  6225         -    ** to the change.  But when changing from a rollback mode to WAL, keep
  6226         -    ** the journal open since there is a rollback-style transaction in play
  6227         -    ** used to convert the version numbers in the btree header.
  6228         -    */
  6229         -    if( isOpen(pPager->jfd) && eMode!=PAGER_JOURNALMODE_WAL ){
  6230         -      sqlite3OsClose(pPager->jfd);
  6231         -    }
  6232   6234   
  6233   6235       /* Change the journal mode. */
  6234   6236       pPager->journalMode = (u8)eMode;
  6235   6237   
  6236   6238       /* When transistioning from TRUNCATE or PERSIST to any other journal
  6237   6239       ** mode except WAL (and we are not in locking_mode=EXCLUSIVE) then 
  6238   6240       ** delete the journal file.
................................................................................
  6242   6244       assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
  6243   6245       assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
  6244   6246       assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
  6245   6247       assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
  6246   6248   
  6247   6249       assert( isOpen(pPager->fd) || pPager->exclusiveMode );
  6248   6250       if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
         6251  +
         6252  +      sqlite3OsClose(pPager->jfd);
  6249   6253   
  6250   6254         /* In this case we would like to delete the journal file. If it is
  6251   6255         ** not possible, then that is not a problem. Deleting the journal file
  6252   6256         ** here is an optimization only.
  6253   6257         **
  6254   6258         ** Before deleting the journal file, obtain a RESERVED lock on the
  6255   6259         ** database file. This ensures that the journal file is not deleted
................................................................................
  6258   6262         int rc = SQLITE_OK;
  6259   6263         int state = pPager->eState;
  6260   6264         if( state==PAGER_NONE ){
  6261   6265           rc = sqlite3PagerSharedLock(pPager);
  6262   6266         }
  6263   6267         if( pPager->eState==PAGER_READER ){
  6264   6268           assert( rc==SQLITE_OK );
  6265         -        rc = osLock(pPager, RESERVED_LOCK);
         6269  +        rc = pagerLockDb(pPager, RESERVED_LOCK);
  6266   6270         }
  6267   6271         if( rc==SQLITE_OK ){
  6268   6272           sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
  6269   6273         }
  6270   6274         if( rc==SQLITE_OK && state==PAGER_READER ){
  6271         -        osUnlock(pPager, SHARED_LOCK);
         6275  +        pagerUnlockDb(pPager, SHARED_LOCK);
  6272   6276         }else if( state==PAGER_NONE ){
  6273   6277           pager_unlock(pPager);
  6274   6278         }
  6275   6279         assert( state==pPager->eState );
  6276   6280       }
  6277   6281     }
  6278   6282   
................................................................................
  6289   6293   
  6290   6294   /*
  6291   6295   ** Return TRUE if the pager is in a state where it is OK to change the
  6292   6296   ** journalmode.  Journalmode changes can only happen when the database
  6293   6297   ** is unmodified.
  6294   6298   */
  6295   6299   int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
         6300  +  assert( assert_pager_state(pPager) );
  6296   6301     if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
  6297   6302     if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
  6298   6303     return 1;
  6299   6304   }
  6300   6305   
  6301   6306   /*
  6302   6307   ** Get/set the size-limit used for persistent journal files.
................................................................................
  6375   6380     assert( pPager->eState==PAGER_NONE   || pbOpen );
  6376   6381     assert( pPager->eState==PAGER_READER || !pbOpen );
  6377   6382     assert( pbOpen==0 || *pbOpen==0 );
  6378   6383     assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
  6379   6384   
  6380   6385     if( !pPager->tempFile && !pPager->pWal ){
  6381   6386       if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
         6387  +
         6388  +    if( isOpen(pPager->jfd) ){
         6389  +      sqlite3OsClose(pPager->jfd);
         6390  +    }
  6382   6391   
  6383   6392       /* Open the connection to the log file. If this operation fails, 
  6384   6393       ** (e.g. due to malloc() failure), unlock the database file and 
  6385   6394       ** return an error code.
  6386   6395       */
  6387   6396       rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal);
  6388   6397       if( rc==SQLITE_OK ){
................................................................................
  6412   6421   
  6413   6422     /* If the log file is not already open, but does exist in the file-system,
  6414   6423     ** it may need to be checkpointed before the connection can switch to
  6415   6424     ** rollback mode. Open it now so this can happen.
  6416   6425     */
  6417   6426     if( !pPager->pWal ){
  6418   6427       int logexists = 0;
  6419         -    rc = osLock(pPager, SHARED_LOCK);
         6428  +    rc = pagerLockDb(pPager, SHARED_LOCK);
  6420   6429       if( rc==SQLITE_OK ){
  6421   6430         rc = sqlite3OsAccess(
  6422   6431             pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
  6423   6432         );
  6424   6433       }
  6425   6434       if( rc==SQLITE_OK && logexists ){
  6426   6435         rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
................................................................................
  6428   6437       }
  6429   6438     }
  6430   6439       
  6431   6440     /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
  6432   6441     ** the database file, the log and log-summary files will be deleted.
  6433   6442     */
  6434   6443     if( rc==SQLITE_OK && pPager->pWal ){
  6435         -    rc = osLock(pPager, EXCLUSIVE_LOCK);
         6444  +    rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
  6436   6445       if( rc==SQLITE_OK ){
  6437   6446         rc = sqlite3WalClose(pPager->pWal,
  6438   6447                              (pPager->noSync ? 0 : pPager->sync_flags), 
  6439   6448           pPager->pageSize, (u8*)pPager->pTmpSpace
  6440   6449         );
  6441   6450         pPager->pWal = 0;
  6442   6451       }else{
  6443   6452         /* If we cannot get an EXCLUSIVE lock, downgrade the PENDING lock
  6444   6453         ** that we did get back to SHARED. */
  6445         -      osUnlock(pPager, SQLITE_LOCK_SHARED);
         6454  +      pagerUnlockDb(pPager, SQLITE_LOCK_SHARED);
  6446   6455       }
  6447   6456     }
  6448   6457     return rc;
  6449   6458   }
  6450   6459   
  6451   6460   #ifdef SQLITE_HAS_CODEC
  6452   6461   /*