off_t fileSize;
OFF_T fileSize;
int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){  PgHdr *pPg;  int rc;  /* Make sure we have not hit any critical errors.  */   assert( pPager!=0 );  assert( pgno!=0 );  *ppPage = 0;  if( pPager->errMask & ~(PAGER_ERR_FULL) ){    return pager_errcode(pPager);  }  /* If this is the first page accessed, then get a read lock  ** on the database file.  */  if( pPager->nRef==0 ){    rc = sqliteOsReadLock(&pPager->fd);    if( rc!=SQLITE_OK ){      return rc;    }    pPager->state = SQLITE_READLOCK;    /* If a journal file exists, try to play it back.    */    if( pPager->useJournal && sqliteOsFileExists(pPager->zJournal) ){       int rc;       /* Get a write lock on the database       */       rc = sqliteOsWriteLock(&pPager->fd);       if( rc!=SQLITE_OK ){         if( sqliteOsUnlock(&pPager->fd)!=SQLITE_OK ){           /* This should never happen! */           rc = SQLITE_INTERNAL;         }         return rc;       }       pPager->state = SQLITE_WRITELOCK;       /* Open the journal for reading only.  Return SQLITE_BUSY if       ** we are unable to open the journal file.        **       ** The journal file does not need to be locked itself.  The       ** journal file is never open unless the main database file holds       ** a write lock, so there is never any chance of two or more       ** processes opening the journal at the same time.       */       rc = sqliteOsOpenReadOnly(pPager->zJournal, &pPager->jfd);       if( rc!=SQLITE_OK ){         rc = sqliteOsUnlock(&pPager->fd);         assert( rc==SQLITE_OK );         return SQLITE_BUSY;       }       pPager->journalOpen = 1;       pPager->journalStarted = 0;       /* Playback and delete the journal.  Drop the database write       ** lock and reacquire the read lock.       */       rc = pager_playback(pPager, 0);       if( rc!=SQLITE_OK ){         return rc;       }    }    pPg = 0;  }else{    /* Search for page in cache */    pPg = pager_lookup(pPager, pgno);  }  if( pPg==0 ){    /* The requested page is not in the page cache. */    int h;    pPager->nMiss++;    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){      /* Create a new page */      pPg = sqliteMallocRaw( sizeof(*pPg) + SQLITE_PAGE_SIZE                               + sizeof(u32) + pPager->nExtra );      if( pPg==0 ){        pager_unwritelock(pPager);        pPager->errMask |= PAGER_ERR_MEM;        return SQLITE_NOMEM;      }      memset(pPg, 0, sizeof(*pPg));      pPg->pPager = pPager;      pPg->pNextAll = pPager->pAll;      if( pPager->pAll ){        pPager->pAll->pPrevAll = pPg;      }      pPg->pPrevAll = 0;      pPager->pAll = pPg;      pPager->nPage++;    }else{      /* Find a page to recycle.  Try to locate a page that does not      ** require us to do an fsync() on the journal.      */      pPg = pPager->pFirstSynced;      /* If we could not find a page that does not require an fsync()      ** on the journal file then fsync the journal file.  This is a      ** very slow operation, so we work hard to avoid it.  But sometimes      ** it can't be helped.      */      if( pPg==0 ){        int rc = syncJournal(pPager);        if( rc!=0 ){          sqlitepager_rollback(pPager);          return SQLITE_IOERR;        }        pPg = pPager->pFirst;      }      assert( pPg->nRef==0 );      /* Write the page to the database file if it is dirty.      */      if( pPg->dirty ){        assert( pPg->needSync==0 );        pPg->pDirty = 0;        rc = pager_write_pagelist( pPg );        if( rc!=SQLITE_OK ){          sqlitepager_rollback(pPager);          return SQLITE_IOERR;        }      }      assert( pPg->dirty==0 );      /* If the page we are recycling is marked as alwaysRollback, then      ** set the global alwaysRollback flag, thus disabling the      ** sqlite_dont_rollback() optimization for the rest of this transaction.      ** It is necessary to do this because the page marked alwaysRollback      ** might be reloaded at a later time but at that point we won't remember      ** that is was marked alwaysRollback.  This means that all pages must      ** be marked as alwaysRollback from here on out.      */      if( pPg->alwaysRollback ){        pPager->alwaysRollback = 1;      }      /* Unlink the old page from the free list and the hash table      */      if( pPg==pPager->pFirstSynced ){        PgHdr *p = pPg->pNextFree;        while( p && p->needSync ){ p = p->pNextFree; }        pPager->pFirstSynced = p;      }      if( pPg->pPrevFree ){        pPg->pPrevFree->pNextFree = pPg->pNextFree;      }else{        assert( pPager->pFirst==pPg );        pPager->pFirst = pPg->pNextFree;      }      if( pPg->pNextFree ){        pPg->pNextFree->pPrevFree = pPg->pPrevFree;      }else{        assert( pPager->pLast==pPg );        pPager->pLast = pPg->pPrevFree;      }      pPg->pNextFree = pPg->pPrevFree = 0;      if( pPg->pNextHash ){        pPg->pNextHash->pPrevHash = pPg->pPrevHash;      }      if( pPg->pPrevHash ){        pPg->pPrevHash->pNextHash = pPg->pNextHash;      }else{        h = pager_hash(pPg->pgno);        assert( pPager->aHash[h]==pPg );        pPager->aHash[h] = pPg->pNextHash;      }      pPg->pNextHash = pPg->pPrevHash = 0;      pPager->nOvfl++;    }    pPg->pgno = pgno;    if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){      sqliteCheckMemory(pPager->aInJournal, pgno/8);      assert( pPager->journalOpen );      pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;      pPg->needSync = 0;    }else{      pPg->inJournal = 0;      pPg->needSync = 0;    }    if( pPager->aInCkpt && (int)pgno<=pPager->ckptSize             && (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0 ){      page_add_to_ckpt_list(pPg);    }else{      page_remove_from_ckpt_list(pPg);    }    pPg->dirty = 0;    pPg->nRef = 1;    REFINFO(pPg);    pPager->nRef++;    h = pager_hash(pgno);    pPg->pNextHash = pPager->aHash[h];    pPager->aHash[h] = pPg;    if( pPg->pNextHash ){      assert( pPg->pNextHash->pPrevHash==0 );      pPg->pNextHash->pPrevHash = pPg;    }    if( pPager->nExtra>0 ){      memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);    }    if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);    if( pPager->errMask!=0 ){      sqlitepager_unref(PGHDR_TO_DATA(pPg));      rc = pager_errcode(pPager);      return rc;    }    if( pPager->dbSize<(int)pgno ){      memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);    }else{      int rc;      sqliteOsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);      rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);      TRACE2("FETCH %d\n", pPg->pgno);      CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);      if( rc!=SQLITE_OK ){        off_t fileSize;        if( sqliteOsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK               || fileSize>=pgno*SQLITE_PAGE_SIZE ){          sqlitepager_unref(PGHDR_TO_DATA(pPg));          return rc;        }else{          memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);        }      }    }  }else{    /* The requested page is in the page cache. */    pPager->nHit++;    page_ref(pPg);  }  *ppPage = PGHDR_TO_DATA(pPg);  return SQLITE_OK;}