/ Check-in [5c9e9df2]
Login

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

Overview
Comment:Fix cases where xRead() was being used to read from a memory mapped part of the database file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental-mmap
Files: files | file ages | folders
SHA1: 5c9e9df27b9f2c46cd55388a858d4e78ee564975
User & Date: dan 2013-03-21 20:39:55
Context
2013-03-22
08:58
Add assert statements to os_unix.c to ensure that any mapped region of the database file is not being read or written using the xRead() or xWrite() methods. check-in: 765615f9 user: dan tags: experimental-mmap
2013-03-21
20:39
Fix cases where xRead() was being used to read from a memory mapped part of the database file. check-in: 5c9e9df2 user: dan tags: experimental-mmap
20:00
Avoid calling xRead() on a part of the database file that is memory mapped. check-in: c8eac290 user: dan tags: experimental-mmap
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/pager.c.

  2082   2082       pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
  2083   2083                              (int)pPager->nReserve);
  2084   2084     }
  2085   2085   }
  2086   2086   #else
  2087   2087   # define pagerReportSize(X)     /* No-op if we do not support a codec */
  2088   2088   #endif
         2089  +
         2090  +/*
         2091  +** Write nBuf bytes of data from buffer pBuf to offset iOff of the 
         2092  +** database file. If this part of the database file is memory mapped,
         2093  +** use memcpy() to do so. Otherwise, call sqlite3OsWrite().
         2094  +**
         2095  +** Return SQLITE_OK if successful, or an SQLite error code if an error 
         2096  +** occurs.
         2097  +*/
         2098  +static int pagerWriteData(Pager *pPager, const void *pBuf, int nBuf, i64 iOff){
         2099  +  int rc = SQLITE_OK;
         2100  +  if( pPager->nMapValid>=(iOff+nBuf) ){
         2101  +    memcpy(&((u8 *)(pPager->pMap))[iOff], pBuf, nBuf);
         2102  +  }else{
         2103  +    rc = sqlite3OsWrite(pPager->fd, pBuf, nBuf, iOff);
         2104  +  }
         2105  +  return rc;
         2106  +}
  2089   2107   
  2090   2108   /*
  2091   2109   ** Read a single page from either the journal file (if isMainJrnl==1) or
  2092   2110   ** from the sub-journal (if isMainJrnl==0) and playback that page.
  2093   2111   ** The page begins at offset *pOffset into the file. The *pOffset
  2094   2112   ** value is increased to the start of the next page in the journal.
  2095   2113   **
................................................................................
  2257   2275     if( isOpen(pPager->fd)
  2258   2276      && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
  2259   2277      && isSynced
  2260   2278     ){
  2261   2279       i64 ofst = (pgno-1)*(i64)pPager->pageSize;
  2262   2280       testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
  2263   2281       assert( !pagerUseWal(pPager) );
  2264         -    rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst);
         2282  +    rc = pagerWriteData(pPager, aData, pPager->pageSize, ofst);
  2265   2283       if( pgno>pPager->dbFileSize ){
  2266   2284         pPager->dbFileSize = pgno;
  2267   2285       }
  2268   2286       if( pPager->pBackup ){
  2269   2287         CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
  2270   2288         sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
  2271   2289         CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
................................................................................
  3849   3867     return rc;
  3850   3868   }
  3851   3869   
  3852   3870   /*
  3853   3871   ** Unmap any memory mapping of the database file.
  3854   3872   */
  3855   3873   static int pagerUnmap(Pager *pPager){
         3874  +  assert( pPager->nMmapOut==0 );
  3856   3875     if( pPager->pMap ){
  3857   3876       sqlite3OsMremap(pPager->fd, 0, 0, pPager->nMap, 0, &pPager->pMap);
  3858   3877       pPager->nMap = 0;
  3859   3878       pPager->nMapValid = 0;
  3860   3879     }
  3861   3880     return SQLITE_OK;
  3862   3881   }
................................................................................
  4278   4297         assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
  4279   4298         if( pList->pgno==1 ) pager_write_changecounter(pList);
  4280   4299   
  4281   4300         /* Encode the database */
  4282   4301         CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
  4283   4302   
  4284   4303         /* Write out the page data. */
  4285         -      if( pPager->nMapValid>=(offset+pPager->pageSize) ){
  4286         -        memcpy(&((u8 *)(pPager->pMap))[offset], pData, pPager->pageSize);
  4287         -      }else{
  4288         -        rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
  4289         -      }
         4304  +      pagerWriteData(pPager, pData, pPager->pageSize, offset);
  4290   4305   
  4291   4306         /* If page 1 was just written, update Pager.dbFileVers to match
  4292   4307         ** the value now stored in the database file. If writing this 
  4293   4308         ** page caused the database file to grow, update dbFileSize. 
  4294   4309         */
  4295   4310         if( pgno==1 ){
  4296   4311           memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
................................................................................
  7081   7096     int rc = SQLITE_OK;             /* Return code */
  7082   7097   
  7083   7098     assert( assert_pager_state(pPager) );
  7084   7099     assert( pPager->eState==PAGER_OPEN   || pbOpen );
  7085   7100     assert( pPager->eState==PAGER_READER || !pbOpen );
  7086   7101     assert( pbOpen==0 || *pbOpen==0 );
  7087   7102     assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
         7103  +
         7104  +  pagerUnmap(pPager);
  7088   7105   
  7089   7106     if( !pPager->tempFile && !pPager->pWal ){
  7090   7107       if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
  7091   7108   
  7092   7109       /* Close any rollback journal previously open */
  7093   7110       sqlite3OsClose(pPager->jfd);
  7094   7111