/* ** The first argument to this function is a handle open on a journal file. ** This function reads the journal file and adds the page number for each ** page in the journal to the Bitvec object passed as the second argument. */ static int readJournalFile(jt_file *p, jt_file *pMain){ int rc = SQLITE_OK; unsigned char zBuf[28]; sqlite3_file *pReal = p->pReal; sqlite3_int64 iOff = 0; sqlite3_int64 iSize = p->iMaxOff; unsigned char *aPage; int iSave; int iSave2; aPage = sqlite3_malloc(pMain->nPagesize); if( !aPage ){ return SQLITE_IOERR_NOMEM; } stop_ioerr_simulation(&iSave, &iSave2); while( rc==SQLITE_OK && iOff<iSize ){ u32 nRec, nPage, nSector, nPagesize; u32 ii; /* Read and decode the next journal-header from the journal file. */ rc = sqlite3OsRead(pReal, zBuf, 28, iOff); if( rc!=SQLITE_OK || decodeJournalHdr(zBuf, &nRec, &nPage, &nSector, &nPagesize) ){ goto finish_rjf; } iOff += nSector; if( nRec==0 ){ /* A trick. There might be another journal-header immediately ** following this one. In this case, 0 records means 0 records, ** not "read until the end of the file". See also ticket #2565. */ if( iSize>=(iOff+nSector) ){ rc = sqlite3OsRead(pReal, zBuf, 28, iOff); if( rc!=SQLITE_OK || 0==decodeJournalHdr(zBuf, 0, 0, 0, 0) ){ continue; } } nRec = (iSize-iOff) / (pMain->nPagesize+8); } /* Read all the records that follow the journal-header just read. */ for(ii=0; rc==SQLITE_OK && ii<nRec && iOff<iSize; ii++){ u32 pgno; rc = sqlite3OsRead(pReal, zBuf, 4, iOff); if( rc==SQLITE_OK ){ pgno = decodeUint32(zBuf); if( pgno>0 && pgno<=pMain->nPage ){ if( 0==sqlite3BitvecTest(pMain->pWritable, pgno) ){ rc = sqlite3OsRead(pReal, aPage, pMain->nPagesize, iOff+4); if( rc==SQLITE_OK ){ u32 cksum = genCksum(aPage, pMain->nPagesize); assert( cksum==pMain->aCksum[pgno-1] ); } } sqlite3BitvecSet(pMain->pWritable, pgno); } iOff += (8 + pMain->nPagesize); } } iOff = ((iOff + (nSector-1)) / nSector) * nSector; } finish_rjf: start_ioerr_simulation(iSave, iSave2); sqlite3_free(aPage); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } return rc; }
static int readJournalFile(jt_file *p, jt_file *pMain){ int rc = SQLITE_OK; unsigned char zBuf[28]; sqlite3_file *pReal = p->pReal; sqlite3_int64 iOff = 0; sqlite3_int64 iSize = p->iMaxOff; unsigned char *aPage; int iSave; int iSave2; aPage = sqlite3_malloc(pMain->nPagesize); if( !aPage ){ return SQLITE_IOERR_NOMEM; } stop_ioerr_simulation(&iSave, &iSave2); while( rc==SQLITE_OK && iOff<iSize ){ u32 nRec, nPage, nSector, nPagesize; u32 ii; rc = sqlite3OsRead(pReal, zBuf, 28, iOff); if( rc!=SQLITE_OK || decodeJournalHdr(zBuf, &nRec, &nPage, &nSector, &nPagesize) ){ goto finish_rjf; } iOff += nSector; if( nRec==0 ){ if( iSize>=(iOff+nSector) ){ rc = sqlite3OsRead(pReal, zBuf, 28, iOff); if( rc!=SQLITE_OK || 0==decodeJournalHdr(zBuf, 0, 0, 0, 0) ){ continue; } } nRec = (iSize-iOff) / (pMain->nPagesize+8); } for(ii=0; rc==SQLITE_OK && ii<nRec && iOff<iSize; ii++){ u32 pgno; rc = sqlite3OsRead(pReal, zBuf, 4, iOff); if( rc==SQLITE_OK ){ pgno = decodeUint32(zBuf); if( pgno>0 && pgno<=pMain->nPage ){ if( 0==sqlite3BitvecTest(pMain->pWritable, pgno) ){ rc = sqlite3OsRead(pReal, aPage, pMain->nPagesize, iOff+4); if( rc==SQLITE_OK ){ u32 cksum = genCksum(aPage, pMain->nPagesize); assert( cksum==pMain->aCksum[pgno-1] ); } } sqlite3BitvecSet(pMain->pWritable, pgno); } iOff += (8 + pMain->nPagesize); } } iOff = ((iOff + (nSector-1)) / nSector) * nSector; } finish_rjf: start_ioerr_simulation(iSave, iSave2); sqlite3_free(aPage); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } return rc; }