mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Add an experimental fix to avoid attempting to mmap memory from an offset that is not a multiple of the system page size on systems with page sizes larger than 32KB.
FossilOrigin-Name: 6f3a5c24d254fc6faf607b505bdef4a7aafc21af
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Avoid\ssome\sunnecessary\scalls\sto\ssqlite3VdbeRecordUnpack()\sthat\swere\sbeing\smade\swhen\smerging\sdata\sfrom\stwo\sor\smore\stemp\sfiles\stogether\sin\svdbesort.c
|
C Add\san\sexperimental\sfix\sto\savoid\sattempting\sto\smmap\smemory\sfrom\san\soffset\sthat\sis\snot\sa\smultiple\sof\sthe\ssystem\spage\ssize\son\ssystems\swith\spage\ssizes\slarger\sthan\s32KB.
|
||||||
D 2014-03-19T20:01:25.712
|
D 2014-03-20T08:59:47.455
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -203,7 +203,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
|||||||
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
|
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
|
||||||
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||||
F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5
|
F src/os_unix.c 7e2f6348e99bd215d36cb5d40161b06456089e21
|
||||||
F src/os_win.c e71678ac927d0a0fb11d993db20a9748eabf808e
|
F src/os_win.c e71678ac927d0a0fb11d993db20a9748eabf808e
|
||||||
F src/pager.c 97a8908bf4e6e7c3adea09d3597cfa48ae33ab4e
|
F src/pager.c 97a8908bf4e6e7c3adea09d3597cfa48ae33ab4e
|
||||||
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
|
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
|
||||||
@@ -1156,7 +1156,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P ecd9d3f9453be0bb8e312d8027fd1a9e55882f36
|
P 707ea170b3e26965b7e3982f7554d122d130b9a6
|
||||||
R 597feeb3c9b32d5be1e5c696f1b077da
|
R df2b4ee35d794d54be353b7886f4773f
|
||||||
|
T *branch * shm-mapping-fix
|
||||||
|
T *sym-shm-mapping-fix *
|
||||||
|
T -sym-trunk *
|
||||||
U dan
|
U dan
|
||||||
Z 03e3772c0627172d43f05f231b29ede3
|
Z 8f1167a615e2deebf3a41d21381f8bfc
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
707ea170b3e26965b7e3982f7554d122d130b9a6
|
6f3a5c24d254fc6faf607b505bdef4a7aafc21af
|
||||||
@@ -4105,6 +4105,33 @@ static int unixShmSystemLock(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the system page size.
|
||||||
|
*/
|
||||||
|
static int unixGetPagesize(void){
|
||||||
|
#if defined(_BSD_SOURCE)
|
||||||
|
return getpagesize();
|
||||||
|
#else
|
||||||
|
return (int)sysconf(_SC_PAGESIZE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the minimum number of 32KB shm regions that should be mapped at
|
||||||
|
** a time, assuming that each mapping must be an integer multiple of the
|
||||||
|
** current system page-size.
|
||||||
|
**
|
||||||
|
** Usually, this is 1. The exception seems to be systems that are configured
|
||||||
|
** to use 64KB pages - in this case each mapping must cover at least two
|
||||||
|
** shm regions.
|
||||||
|
*/
|
||||||
|
static int unixShmRegionPerMap(void){
|
||||||
|
int shmsz = 32*1024; /* SHM region size */
|
||||||
|
int pgsz = unixGetPagesize(); /* System page size */
|
||||||
|
assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */
|
||||||
|
if( pgsz<shmsz ) return 1;
|
||||||
|
return pgsz/shmsz;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
|
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
|
||||||
@@ -4116,10 +4143,11 @@ static void unixShmPurge(unixFile *pFd){
|
|||||||
unixShmNode *p = pFd->pInode->pShmNode;
|
unixShmNode *p = pFd->pInode->pShmNode;
|
||||||
assert( unixMutexHeld() );
|
assert( unixMutexHeld() );
|
||||||
if( p && p->nRef==0 ){
|
if( p && p->nRef==0 ){
|
||||||
|
int nShmPerMap = unixShmRegionPerMap();
|
||||||
int i;
|
int i;
|
||||||
assert( p->pInode==pFd->pInode );
|
assert( p->pInode==pFd->pInode );
|
||||||
sqlite3_mutex_free(p->mutex);
|
sqlite3_mutex_free(p->mutex);
|
||||||
for(i=0; i<p->nRegion; i++){
|
for(i=0; i<p->nRegion; i+=nShmPerMap){
|
||||||
if( p->h>=0 ){
|
if( p->h>=0 ){
|
||||||
osMunmap(p->apRegion[i], p->szRegion);
|
osMunmap(p->apRegion[i], p->szRegion);
|
||||||
}else{
|
}else{
|
||||||
@@ -4326,6 +4354,8 @@ static int unixShmMap(
|
|||||||
unixShm *p;
|
unixShm *p;
|
||||||
unixShmNode *pShmNode;
|
unixShmNode *pShmNode;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
int nShmPerMap = unixShmRegionPerMap();
|
||||||
|
int nReqRegion;
|
||||||
|
|
||||||
/* If the shared-memory file has not yet been opened, open it now. */
|
/* If the shared-memory file has not yet been opened, open it now. */
|
||||||
if( pDbFd->pShm==0 ){
|
if( pDbFd->pShm==0 ){
|
||||||
@@ -4341,9 +4371,12 @@ static int unixShmMap(
|
|||||||
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
|
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
|
||||||
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
|
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
|
||||||
|
|
||||||
if( pShmNode->nRegion<=iRegion ){
|
/* Minimum number of regions required to be mapped. */
|
||||||
|
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
|
||||||
|
|
||||||
|
if( pShmNode->nRegion<nReqRegion ){
|
||||||
char **apNew; /* New apRegion[] array */
|
char **apNew; /* New apRegion[] array */
|
||||||
int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
|
int nByte = nReqRegion*szRegion; /* Minimum required file size */
|
||||||
struct stat sStat; /* Used by fstat() */
|
struct stat sStat; /* Used by fstat() */
|
||||||
|
|
||||||
pShmNode->szRegion = szRegion;
|
pShmNode->szRegion = szRegion;
|
||||||
@@ -4392,17 +4425,19 @@ static int unixShmMap(
|
|||||||
|
|
||||||
/* Map the requested memory region into this processes address space. */
|
/* Map the requested memory region into this processes address space. */
|
||||||
apNew = (char **)sqlite3_realloc(
|
apNew = (char **)sqlite3_realloc(
|
||||||
pShmNode->apRegion, (iRegion+1)*sizeof(char *)
|
pShmNode->apRegion, nReqRegion*sizeof(char *)
|
||||||
);
|
);
|
||||||
if( !apNew ){
|
if( !apNew ){
|
||||||
rc = SQLITE_IOERR_NOMEM;
|
rc = SQLITE_IOERR_NOMEM;
|
||||||
goto shmpage_out;
|
goto shmpage_out;
|
||||||
}
|
}
|
||||||
pShmNode->apRegion = apNew;
|
pShmNode->apRegion = apNew;
|
||||||
while(pShmNode->nRegion<=iRegion){
|
while( pShmNode->nRegion<nReqRegion ){
|
||||||
|
int nMap = szRegion*nShmPerMap;
|
||||||
|
int i;
|
||||||
void *pMem;
|
void *pMem;
|
||||||
if( pShmNode->h>=0 ){
|
if( pShmNode->h>=0 ){
|
||||||
pMem = osMmap(0, szRegion,
|
pMem = osMmap(0, nMap,
|
||||||
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
|
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
|
||||||
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
|
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
|
||||||
);
|
);
|
||||||
@@ -4418,8 +4453,11 @@ static int unixShmMap(
|
|||||||
}
|
}
|
||||||
memset(pMem, 0, szRegion);
|
memset(pMem, 0, szRegion);
|
||||||
}
|
}
|
||||||
pShmNode->apRegion[pShmNode->nRegion] = pMem;
|
|
||||||
pShmNode->nRegion++;
|
for(i=0; i<nShmPerMap; i++){
|
||||||
|
pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
|
||||||
|
}
|
||||||
|
pShmNode->nRegion += nShmPerMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4633,19 +4671,6 @@ static void unixUnmapfile(unixFile *pFd){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Return the system page size.
|
|
||||||
*/
|
|
||||||
static int unixGetPagesize(void){
|
|
||||||
#if HAVE_MREMAP
|
|
||||||
return 512;
|
|
||||||
#elif defined(_BSD_SOURCE)
|
|
||||||
return getpagesize();
|
|
||||||
#else
|
|
||||||
return (int)sysconf(_SC_PAGESIZE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Attempt to set the size of the memory mapping maintained by file
|
** Attempt to set the size of the memory mapping maintained by file
|
||||||
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
||||||
@@ -4682,8 +4707,12 @@ static void unixRemapfile(
|
|||||||
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
||||||
|
|
||||||
if( pOrig ){
|
if( pOrig ){
|
||||||
|
#if HAVE_MREMAP
|
||||||
|
i64 nReuse = pFd->mmapSize;
|
||||||
|
#else
|
||||||
const int szSyspage = unixGetPagesize();
|
const int szSyspage = unixGetPagesize();
|
||||||
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
|
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
|
||||||
|
#endif
|
||||||
u8 *pReq = &pOrig[nReuse];
|
u8 *pReq = &pOrig[nReuse];
|
||||||
|
|
||||||
/* Unmap any pages of the existing mapping that cannot be reused. */
|
/* Unmap any pages of the existing mapping that cannot be reused. */
|
||||||
|
|||||||
Reference in New Issue
Block a user