/ Check-in [cb6be84d]
Login

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

Overview
Comment:Modifications to pager.c to avoid the unsigned/signed warnings. (CVS 5909)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:cb6be84dfc5d6546d07359b32fe04555561325de
User & Date: danielk1977 2008-11-17 04:56:24
Context
2008-11-17
08:05
Added support for vxworks >= 6.4; RTP mode tested, kernel mode untested. (CVS 5910) check-in: f45a1493 user: chw tags: trunk
04:56
Modifications to pager.c to avoid the unsigned/signed warnings. (CVS 5909) check-in: cb6be84d user: danielk1977 tags: trunk
2008-11-15
11:22
Fix compiler warnings in pcache1.c related to comparison of unsigned and signed values. (CVS 5908) check-in: ce77ea98 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
...
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
....
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
....
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
....
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
....
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
....
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
....
2100
2101
2102
2103
2104
2105
2106

2107
2108
2109
2110
2111
2112
2113
....
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
....
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
....
2689
2690
2691
2692
2693
2694
2695

2696
2697
2698
2699
2700
2701
2702
....
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
....
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
....
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
....
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
....
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
....
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
....
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
....
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
....
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
....
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
....
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.503 2008/11/13 14:28:29 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
  u8 journalMode;             /* On of the PAGER_JOURNALMODE_* values */
  u8 dbModified;              /* True if there are any changes to the Db */
  u8 changeCountDone;         /* Set after incrementing the change-counter */

  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  int errCode;                /* One of several kinds of errors */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */
  int pageSize;               /* Number of bytes in a page */
  int nPage;                  /* Total number of in-memory pages */
  int mxPage;                 /* Maximum number of pages to hold in cache */
................................................................................
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file 
** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() for details.
*/
/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)

/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647

/*
................................................................................
** name in the journal is longer than nMaster bytes (including a
** nul-terminator), then this is handled as if no master journal name
** were present in the journal.
**
** If no master journal file name is present zMaster[0] is set to 0 and
** SQLITE_OK returned.
*/
static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, int nMaster){
  int rc;
  u32 len;
  i64 szJ;
  u32 cksum;
  u32 u;                   /* Unsigned loop counter */
  unsigned char aMagic[8]; /* A buffer to hold the magic header */

................................................................................
** - 4 bytes: Database page size.
** 
** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
*/
static int writeJournalHdr(Pager *pPager){
  int rc = SQLITE_OK;
  char *zHeader = pPager->pTmpSpace;
  int nHeader = pPager->pageSize;
  int nWrite;

  if( nHeader>JOURNAL_HDR_SZ(pPager) ){
    nHeader = JOURNAL_HDR_SZ(pPager);
  }

  if( pPager->stmtHdrOff==0 ){
    pPager->stmtHdrOff = pPager->journalOff;
................................................................................
** on the pager file (by this or any other process), it will be
** treated as a hot-journal and rolled back.
*/
static void pager_unlock(Pager *pPager){
  if( !pPager->exclusiveMode ){
    int rc = osUnlock(pPager->fd, NO_LOCK);
    if( rc ) pPager->errCode = rc;
    pPager->dbSize = -1;
    IOTRACE(("UNLOCK %p\n", pPager))

    /* Always close the journal file when dropping the database lock.
    ** Otherwise, another connection with journal_mode=delete might
    ** delete the file out from under us.
    */
    if( pPager->journalOpen ){
................................................................................
    pPager->state = PAGER_EXCLUSIVE;
  }
  pPager->origDbSize = 0;
  pPager->setMaster = 0;
  pPager->needSync = 0;
  /* lruListSetFirstSynced(pPager); */
  if( !MEMDB ){
    pPager->dbSize = -1;
  }
  pPager->dbModified = 0;

  return (rc==SQLITE_OK?rc2:rc);
}

/*
................................................................................
** which has extended the file size and the new pages are still all held
** in cache, then an INSERT or UPDATE does a statement rollback.  Some
** operating system implementations can get confused if you try to
** truncate a file to some size that is larger than it currently is,
** so detect this case and write a single zero byte to the end of the new
** file instead.
*/
static int pager_truncate(Pager *pPager, int nPage){
  int rc = SQLITE_OK;
  if( pPager->state>=PAGER_EXCLUSIVE && pPager->fd->pMethods ){
    i64 currentSize, newSize;
    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
    newSize = pPager->pageSize*(i64)nPage;
    if( rc==SQLITE_OK && currentSize!=newSize ){
      if( currentSize>newSize ){
................................................................................
    memcpy(pPager->zFilename, zPathname, nPathname+1);
    sqlite3_free(zPathname);
  }

  /* Open the pager file.
  */
  if( zFilename && zFilename[0] && !memDb ){
    if( nPathname>(pVfs->mxPathname - sizeof("-journal")) ){
      rc = SQLITE_CANTOPEN;
    }else{
      int fout = 0;
      rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd,
                         pPager->vfsFlags, &fout);
      readOnly = (fout&SQLITE_OPEN_READONLY);

................................................................................

  /* pPager->journalOpen = 0; */
  pPager->useJournal = useJournal;
  pPager->noReadlock = noReadlock && readOnly;
  /* pPager->stmtOpen = 0; */
  /* pPager->stmtInUse = 0; */
  /* pPager->nRef = 0; */
  pPager->dbSize = memDb-1;
  pPager->pageSize = szPageDflt;
  /* pPager->stmtSize = 0; */
  /* pPager->stmtJSize = 0; */
  /* pPager->nPage = 0; */
  pPager->mxPage = 100;
  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
  /* pPager->state = PAGER_UNLOCK; */
................................................................................
  i64 n = 0;
  int rc;
  assert( pPager!=0 );
  if( pPager->errCode ){
    rc = pPager->errCode;
    return rc;
  }
  if( pPager->dbSize>=0 ){
    n = pPager->dbSize;
  } else {
    assert(pPager->fd->pMethods||pPager->tempFile);
    if( (pPager->fd->pMethods)
     && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
      pager_error(pPager, rc);
      return rc;
................................................................................
    if( n>0 && n<pPager->pageSize ){
      n = 1;
    }else{
      n /= pPager->pageSize;
    }
    if( pPager->state!=PAGER_UNLOCK ){
      pPager->dbSize = n;

    }
  }
  if( n==(PENDING_BYTE/pPager->pageSize) ){
    n++;
  }
  if( n>pPager->mxPgno ){
    pPager->mxPgno = n;
................................................................................

  /* The OS lock values must be the same as the Pager lock values */
  assert( PAGER_SHARED==SHARED_LOCK );
  assert( PAGER_RESERVED==RESERVED_LOCK );
  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );

  /* If the file is currently unlocked then the size must be unknown */
  assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 );

  if( pPager->state>=locktype ){
    rc = SQLITE_OK;
  }else{
    if( pPager->pBusyHandler ) pPager->pBusyHandler->nBusy = 0;
    do {
      rc = sqlite3OsLock(pPager->fd, locktype);
................................................................................
int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
  int rc = SQLITE_OK;
  assert( pPager->state>=PAGER_SHARED );

  sqlite3PagerPagecount(pPager, 0);
  if( pPager->errCode ){
    rc = pPager->errCode;
  }else if( nPage<(unsigned)pPager->dbSize ){
    rc = syncJournal(pPager);
    if( rc==SQLITE_OK ){
      /* Get an exclusive lock on the database before truncating. */
      rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
    }
    if( rc==SQLITE_OK ){
      rc = pager_truncate(pPager, nPage);
................................................................................
      sqlite3PagerPagecount(pPager, 0);

      if( pPager->errCode ){
        rc = pPager->errCode;
        goto failed;
      }


      if( pPager->dbSize>0 ){
        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
        if( rc!=SQLITE_OK ){
          goto failed;
        }
      }else{
................................................................................
    pPager->dbModified = 1;
  
    /* The transaction journal now exists and we have a RESERVED or an
    ** EXCLUSIVE lock on the main database file.  Write the current page to
    ** the transaction journal if it is not there already.
    */
    if( !pageInJournal(pPg) && pPager->journalOpen ){
      if( (int)pPg->pgno <= pPager->origDbSize ){
        u32 cksum;
        char *pData2;

        /* We should never write to the journal file the page that
        ** contains the database locks.  The following assert verifies
        ** that we do not. */
        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
................................................................................
    /* If the statement journal is open and the page is not in it,
    ** then write the current page to the statement journal.  Note that
    ** the statement journal format differs from the standard journal format
    ** in that it omits the checksums and the header.
    */
    if( pPager->stmtInUse 
     && !pageInStatement(pPg) 
     && (int)pPg->pgno<=pPager->stmtSize 
    ){
      i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
      char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
      assert( pageInJournal(pPg) || (int)pPg->pgno>pPager->origDbSize );
      rc = write32bits(pPager->stfd, offset, pPg->pgno);
      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize, offset+4);
      }
      PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
      if( rc!=SQLITE_OK ){
        return rc;
................................................................................
      sqlite3BitvecSet(pPager->pInStmt, pPg->pgno);
    }
  }

  /* Update the database size and return.
  */
  assert( pPager->state>=PAGER_SHARED );
  if( pPager->dbSize<(int)pPg->pgno ){
    pPager->dbSize = pPg->pgno;
    if( pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
      pPager->dbSize++;
    }
  }
  return rc;
}

/*
................................................................................
      return SQLITE_NOMEM;
    }
  }
  rc = sqlite3BitvecSet(pPager->pAlwaysRollback, pPg->pgno);

  if( rc==SQLITE_OK && (pPg->flags&PGHDR_DIRTY) && !pPager->stmtInUse ){
    assert( pPager->state>=PAGER_SHARED );
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
      ** gets written at least once so that the disk file will be the correct
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database
      ** corruption during the next transaction.
................................................................................
   || sqlite3BitvecTest(pPager->pAlwaysRollback, pPg->pgno)
   || pPg->pgno>pPager->origDbSize
  ){
    return;
  }

#ifdef SQLITE_SECURE_DELETE
  if( (pPg->flags & PGHDR_IN_JOURNAL)!=0 || (int)pPg->pgno>pPager->origDbSize ){
    return;
  }
#endif

  /* If SECURE_DELETE is disabled, then there is no way that this
  ** routine can be called on a page for which sqlite3PagerDontWrite()
  ** has not been previously called during the same transaction.
................................................................................
#ifndef SQLITE_OMIT_AUTOVACUUM
        if( nTrunc!=0 ){
          /* If this transaction has made the database smaller, then all pages
          ** being discarded by the truncation must be written to the journal
          ** file.
          */
          Pgno i;
          int iSkip = PAGER_MJ_PGNO(pPager);
          for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
            if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
              rc = sqlite3PagerGet(pPager, i, &pPg);
              if( rc!=SQLITE_OK ) goto sync_exit;
              rc = sqlite3PagerWrite(pPg);
              sqlite3PagerUnref(pPg);
              if( rc!=SQLITE_OK ) goto sync_exit;
................................................................................
        rc = rc2;
      }
    }else{
      rc = pager_playback(pPager, 0);
    }

    if( !MEMDB ){
      pPager->dbSize = -1;
    }

    /* If an error occurs during a ROLLBACK, we can no longer trust the pager
    ** cache. So call pager_error() on the way out to make any error 
    ** persistent.
    */
    rc = pager_error(pPager, rc);
................................................................................
** This routine is used for testing and analysis only.
*/
int *sqlite3PagerStats(Pager *pPager){
  static int a[11];
  a[0] = sqlite3PcacheRefCount(pPager->pPCache);
  a[1] = sqlite3PcachePagecount(pPager->pPCache);
  a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
  a[3] = pPager->dbSize;
  a[4] = pPager->state;
  a[5] = pPager->errCode;
  a[6] = pPager->nHit;
  a[7] = pPager->nMiss;
  a[8] = 0;  /* Used to be pPager->nOvfl */
  a[9] = pPager->nRead;
  a[10] = pPager->nWrite;
................................................................................
** open.  A new statement journal is created that can be used to rollback
** changes of a single SQL command within a larger transaction.
*/
static int pagerStmtBegin(Pager *pPager){
  int rc;
  assert( !pPager->stmtInUse );
  assert( pPager->state>=PAGER_SHARED );
  assert( pPager->dbSize>=0 );
  PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
  if( !pPager->journalOpen ){
    pPager->stmtAutoopen = 1;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen );
  assert( pPager->pInStmt==0 );
................................................................................
  **
  ** If the isCommit flag is set, there is no need to remember that
  ** the journal needs to be sync()ed before database page pPg->pgno 
  ** can be written to. The caller has already promised not to write to it.
  */
  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
    needSyncPgno = pPg->pgno;
    assert( pageInJournal(pPg) || (int)pgno>pPager->origDbSize );
    assert( pPg->flags&PGHDR_DIRTY );
    assert( pPager->needSync );
  }

  /* If the cache contains a page with page-number pgno, remove it
  ** from its hash chain. Also, if the PgHdr.needSync was set for 
  ** page pgno before the 'move' operation, it needs to be retained 
................................................................................
    ** sure the Pager.needSync flag is set too.
    */
    int rc;
    PgHdr *pPgHdr;
    assert( pPager->needSync );
    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
    if( rc!=SQLITE_OK ){
      if( pPager->pInJournal && (int)needSyncPgno<=pPager->origDbSize ){
        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno);
      }
      return rc;
    }
    pPager->needSync = 1;
    assert( pPager->noSync==0 && !MEMDB );
    pPgHdr->flags |= PGHDR_NEED_SYNC;







|







 







>


|
|
|







 







|







 







|







 







|
|







 







|







 







|







 







|







 







|







 







|







 







|







 







>







 







|







 







|







 







>







 







|







 







|



|







 







|

|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
...
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
....
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
....
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
....
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
....
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
....
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
....
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
....
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
....
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
....
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
....
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
....
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
....
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
....
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
....
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
....
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
....
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
....
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
....
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
....
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
....
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.504 2008/11/17 04:56:24 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSync;               /* Boolean. While true, do not spill the cache */
  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
  u8 journalMode;             /* On of the PAGER_JOURNALMODE_* values */
  u8 dbModified;              /* True if there are any changes to the Db */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u8 dbSizeValid;             /* Set when dbSize is correct */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  int errCode;                /* One of several kinds of errors */
  Pgno dbSize;                /* Number of pages in the file */
  Pgno origDbSize;            /* dbSize before the current change */
  Pgno stmtSize;              /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */
  int pageSize;               /* Number of bytes in a page */
  int nPage;                  /* Total number of in-memory pages */
  int mxPage;                 /* Maximum number of pages to hold in cache */
................................................................................
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file 
** is devoted to storing a master journal name - there are no more pages to
** roll back. See comments for function writeMasterJournal() for details.
*/
/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */
#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))

/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647

/*
................................................................................
** name in the journal is longer than nMaster bytes (including a
** nul-terminator), then this is handled as if no master journal name
** were present in the journal.
**
** If no master journal file name is present zMaster[0] is set to 0 and
** SQLITE_OK returned.
*/
static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
  int rc;
  u32 len;
  i64 szJ;
  u32 cksum;
  u32 u;                   /* Unsigned loop counter */
  unsigned char aMagic[8]; /* A buffer to hold the magic header */

................................................................................
** - 4 bytes: Database page size.
** 
** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
*/
static int writeJournalHdr(Pager *pPager){
  int rc = SQLITE_OK;
  char *zHeader = pPager->pTmpSpace;
  u32 nHeader = pPager->pageSize;
  u32 nWrite;

  if( nHeader>JOURNAL_HDR_SZ(pPager) ){
    nHeader = JOURNAL_HDR_SZ(pPager);
  }

  if( pPager->stmtHdrOff==0 ){
    pPager->stmtHdrOff = pPager->journalOff;
................................................................................
** on the pager file (by this or any other process), it will be
** treated as a hot-journal and rolled back.
*/
static void pager_unlock(Pager *pPager){
  if( !pPager->exclusiveMode ){
    int rc = osUnlock(pPager->fd, NO_LOCK);
    if( rc ) pPager->errCode = rc;
    pPager->dbSizeValid = 0;
    IOTRACE(("UNLOCK %p\n", pPager))

    /* Always close the journal file when dropping the database lock.
    ** Otherwise, another connection with journal_mode=delete might
    ** delete the file out from under us.
    */
    if( pPager->journalOpen ){
................................................................................
    pPager->state = PAGER_EXCLUSIVE;
  }
  pPager->origDbSize = 0;
  pPager->setMaster = 0;
  pPager->needSync = 0;
  /* lruListSetFirstSynced(pPager); */
  if( !MEMDB ){
    pPager->dbSizeValid = 0;
  }
  pPager->dbModified = 0;

  return (rc==SQLITE_OK?rc2:rc);
}

/*
................................................................................
** which has extended the file size and the new pages are still all held
** in cache, then an INSERT or UPDATE does a statement rollback.  Some
** operating system implementations can get confused if you try to
** truncate a file to some size that is larger than it currently is,
** so detect this case and write a single zero byte to the end of the new
** file instead.
*/
static int pager_truncate(Pager *pPager, Pgno nPage){
  int rc = SQLITE_OK;
  if( pPager->state>=PAGER_EXCLUSIVE && pPager->fd->pMethods ){
    i64 currentSize, newSize;
    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
    newSize = pPager->pageSize*(i64)nPage;
    if( rc==SQLITE_OK && currentSize!=newSize ){
      if( currentSize>newSize ){
................................................................................
    memcpy(pPager->zFilename, zPathname, nPathname+1);
    sqlite3_free(zPathname);
  }

  /* Open the pager file.
  */
  if( zFilename && zFilename[0] && !memDb ){
    if( nPathname>(pVfs->mxPathname - (int)sizeof("-journal")) ){
      rc = SQLITE_CANTOPEN;
    }else{
      int fout = 0;
      rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd,
                         pPager->vfsFlags, &fout);
      readOnly = (fout&SQLITE_OPEN_READONLY);

................................................................................

  /* pPager->journalOpen = 0; */
  pPager->useJournal = useJournal;
  pPager->noReadlock = noReadlock && readOnly;
  /* pPager->stmtOpen = 0; */
  /* pPager->stmtInUse = 0; */
  /* pPager->nRef = 0; */
  pPager->dbSizeValid = memDb;
  pPager->pageSize = szPageDflt;
  /* pPager->stmtSize = 0; */
  /* pPager->stmtJSize = 0; */
  /* pPager->nPage = 0; */
  pPager->mxPage = 100;
  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
  /* pPager->state = PAGER_UNLOCK; */
................................................................................
  i64 n = 0;
  int rc;
  assert( pPager!=0 );
  if( pPager->errCode ){
    rc = pPager->errCode;
    return rc;
  }
  if( pPager->dbSizeValid ){
    n = pPager->dbSize;
  } else {
    assert(pPager->fd->pMethods||pPager->tempFile);
    if( (pPager->fd->pMethods)
     && (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
      pager_error(pPager, rc);
      return rc;
................................................................................
    if( n>0 && n<pPager->pageSize ){
      n = 1;
    }else{
      n /= pPager->pageSize;
    }
    if( pPager->state!=PAGER_UNLOCK ){
      pPager->dbSize = n;
      pPager->dbSizeValid = 1;
    }
  }
  if( n==(PENDING_BYTE/pPager->pageSize) ){
    n++;
  }
  if( n>pPager->mxPgno ){
    pPager->mxPgno = n;
................................................................................

  /* The OS lock values must be the same as the Pager lock values */
  assert( PAGER_SHARED==SHARED_LOCK );
  assert( PAGER_RESERVED==RESERVED_LOCK );
  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );

  /* If the file is currently unlocked then the size must be unknown */
  assert( pPager->state>=PAGER_SHARED || pPager->dbSizeValid==0 );

  if( pPager->state>=locktype ){
    rc = SQLITE_OK;
  }else{
    if( pPager->pBusyHandler ) pPager->pBusyHandler->nBusy = 0;
    do {
      rc = sqlite3OsLock(pPager->fd, locktype);
................................................................................
int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
  int rc = SQLITE_OK;
  assert( pPager->state>=PAGER_SHARED );

  sqlite3PagerPagecount(pPager, 0);
  if( pPager->errCode ){
    rc = pPager->errCode;
  }else if( nPage<pPager->dbSize ){
    rc = syncJournal(pPager);
    if( rc==SQLITE_OK ){
      /* Get an exclusive lock on the database before truncating. */
      rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
    }
    if( rc==SQLITE_OK ){
      rc = pager_truncate(pPager, nPage);
................................................................................
      sqlite3PagerPagecount(pPager, 0);

      if( pPager->errCode ){
        rc = pPager->errCode;
        goto failed;
      }

      assert( pPager->dbSizeValid );
      if( pPager->dbSize>0 ){
        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
        if( rc!=SQLITE_OK ){
          goto failed;
        }
      }else{
................................................................................
    pPager->dbModified = 1;
  
    /* The transaction journal now exists and we have a RESERVED or an
    ** EXCLUSIVE lock on the main database file.  Write the current page to
    ** the transaction journal if it is not there already.
    */
    if( !pageInJournal(pPg) && pPager->journalOpen ){
      if( pPg->pgno<=pPager->origDbSize ){
        u32 cksum;
        char *pData2;

        /* We should never write to the journal file the page that
        ** contains the database locks.  The following assert verifies
        ** that we do not. */
        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
................................................................................
    /* If the statement journal is open and the page is not in it,
    ** then write the current page to the statement journal.  Note that
    ** the statement journal format differs from the standard journal format
    ** in that it omits the checksums and the header.
    */
    if( pPager->stmtInUse 
     && !pageInStatement(pPg) 
     && pPg->pgno<=pPager->stmtSize 
    ){
      i64 offset = pPager->stmtNRec*(4+pPager->pageSize);
      char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
      assert( pageInJournal(pPg) || pPg->pgno>pPager->origDbSize );
      rc = write32bits(pPager->stfd, offset, pPg->pgno);
      if( rc==SQLITE_OK ){
        rc = sqlite3OsWrite(pPager->stfd, pData2, pPager->pageSize, offset+4);
      }
      PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
      if( rc!=SQLITE_OK ){
        return rc;
................................................................................
      sqlite3BitvecSet(pPager->pInStmt, pPg->pgno);
    }
  }

  /* Update the database size and return.
  */
  assert( pPager->state>=PAGER_SHARED );
  if( pPager->dbSize<pPg->pgno ){
    pPager->dbSize = pPg->pgno;
    if( pPager->dbSize==(PAGER_MJ_PGNO(pPager)-1) ){
      pPager->dbSize++;
    }
  }
  return rc;
}

/*
................................................................................
      return SQLITE_NOMEM;
    }
  }
  rc = sqlite3BitvecSet(pPager->pAlwaysRollback, pPg->pgno);

  if( rc==SQLITE_OK && (pPg->flags&PGHDR_DIRTY) && !pPager->stmtInUse ){
    assert( pPager->state>=PAGER_SHARED );
    if( pPager->dbSize==pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
      ** gets written at least once so that the disk file will be the correct
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database
      ** corruption during the next transaction.
................................................................................
   || sqlite3BitvecTest(pPager->pAlwaysRollback, pPg->pgno)
   || pPg->pgno>pPager->origDbSize
  ){
    return;
  }

#ifdef SQLITE_SECURE_DELETE
  if( (pPg->flags & PGHDR_IN_JOURNAL)!=0 || pPg->pgno>pPager->origDbSize ){
    return;
  }
#endif

  /* If SECURE_DELETE is disabled, then there is no way that this
  ** routine can be called on a page for which sqlite3PagerDontWrite()
  ** has not been previously called during the same transaction.
................................................................................
#ifndef SQLITE_OMIT_AUTOVACUUM
        if( nTrunc!=0 ){
          /* If this transaction has made the database smaller, then all pages
          ** being discarded by the truncation must be written to the journal
          ** file.
          */
          Pgno i;
          Pgno iSkip = PAGER_MJ_PGNO(pPager);
          for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
            if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
              rc = sqlite3PagerGet(pPager, i, &pPg);
              if( rc!=SQLITE_OK ) goto sync_exit;
              rc = sqlite3PagerWrite(pPg);
              sqlite3PagerUnref(pPg);
              if( rc!=SQLITE_OK ) goto sync_exit;
................................................................................
        rc = rc2;
      }
    }else{
      rc = pager_playback(pPager, 0);
    }

    if( !MEMDB ){
      pPager->dbSizeValid = 0;
    }

    /* If an error occurs during a ROLLBACK, we can no longer trust the pager
    ** cache. So call pager_error() on the way out to make any error 
    ** persistent.
    */
    rc = pager_error(pPager, rc);
................................................................................
** This routine is used for testing and analysis only.
*/
int *sqlite3PagerStats(Pager *pPager){
  static int a[11];
  a[0] = sqlite3PcacheRefCount(pPager->pPCache);
  a[1] = sqlite3PcachePagecount(pPager->pPCache);
  a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
  a[3] = pPager->dbSizeValid ? (int) pPager->dbSize : -1;
  a[4] = pPager->state;
  a[5] = pPager->errCode;
  a[6] = pPager->nHit;
  a[7] = pPager->nMiss;
  a[8] = 0;  /* Used to be pPager->nOvfl */
  a[9] = pPager->nRead;
  a[10] = pPager->nWrite;
................................................................................
** open.  A new statement journal is created that can be used to rollback
** changes of a single SQL command within a larger transaction.
*/
static int pagerStmtBegin(Pager *pPager){
  int rc;
  assert( !pPager->stmtInUse );
  assert( pPager->state>=PAGER_SHARED );
  assert( pPager->dbSizeValid );
  PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
  if( !pPager->journalOpen ){
    pPager->stmtAutoopen = 1;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen );
  assert( pPager->pInStmt==0 );
................................................................................
  **
  ** If the isCommit flag is set, there is no need to remember that
  ** the journal needs to be sync()ed before database page pPg->pgno 
  ** can be written to. The caller has already promised not to write to it.
  */
  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
    needSyncPgno = pPg->pgno;
    assert( pageInJournal(pPg) || pgno>pPager->origDbSize );
    assert( pPg->flags&PGHDR_DIRTY );
    assert( pPager->needSync );
  }

  /* If the cache contains a page with page-number pgno, remove it
  ** from its hash chain. Also, if the PgHdr.needSync was set for 
  ** page pgno before the 'move' operation, it needs to be retained 
................................................................................
    ** sure the Pager.needSync flag is set too.
    */
    int rc;
    PgHdr *pPgHdr;
    assert( pPager->needSync );
    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
    if( rc!=SQLITE_OK ){
      if( pPager->pInJournal && needSyncPgno<=pPager->origDbSize ){
        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno);
      }
      return rc;
    }
    pPager->needSync = 1;
    assert( pPager->noSync==0 && !MEMDB );
    pPgHdr->flags |= PGHDR_NEED_SYNC;