1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Avoid using posix_fallocate() in WAL mode, as it is not supported by all file-systems.

FossilOrigin-Name: 9c7523dabf4aee609287732ce787c9b9a9087e7f
This commit is contained in:
dan
2013-04-26 16:09:29 +00:00
parent 5e2f28c1aa
commit 47a2b4a0b0
3 changed files with 78 additions and 54 deletions

View File

@@ -3193,6 +3193,51 @@ static int unixRead(
}
}
/*
** Attempt to seek the file-descriptor passed as the first argument to
** absolute offset iOff, then attempt to write nBuf bytes of data from
** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise,
** return the actual number of bytes written (which may be less than
** nBuf).
*/
static int seekAndWriteFd(
int fd, /* File descriptor to write to */
i64 iOff, /* File offset to begin writing at */
const void *pBuf, /* Copy data from this buffer to the file */
int nBuf, /* Size of buffer pBuf in bytes */
int *piErrno /* OUT: Error number if error occurs */
){
int rc = 0; /* Value returned by system call */
assert( nBuf==(nBuf&0x1ffff) );
nBuf &= 0x1ffff;
TIMER_START;
#if defined(USE_PREAD)
do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
#elif defined(USE_PREAD64)
do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
#else
do{
i64 iSeek = lseek(fd, iOff, SEEK_SET);
SimulateIOError( iSeek-- );
if( iSeek!=iOff ){
if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
return -1;
}
rc = osWrite(fd, pBuf, nBuf);
}while( rc<0 && errno==EINTR );
#endif
TIMER_END;
OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
if( rc<0 && piErrno ) *piErrno = errno;
return rc;
}
/*
** Seek to the offset in id->offset then read cnt bytes into pBuf.
** Return the number of bytes actually read. Update the offset.
@@ -3201,39 +3246,7 @@ static int unixRead(
** is set before returning.
*/
static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
int got;
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
i64 newOffset;
#endif
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
TIMER_START;
#if defined(USE_PREAD)
do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
#elif defined(USE_PREAD64)
do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
#else
do{
newOffset = lseek(id->h, offset, SEEK_SET);
SimulateIOError( newOffset-- );
if( newOffset!=offset ){
if( newOffset == -1 ){
((unixFile*)id)->lastErrno = errno;
}else{
((unixFile*)id)->lastErrno = 0;
}
return -1;
}
got = osWrite(id->h, pBuf, cnt);
}while( got<0 && errno==EINTR );
#endif
TIMER_END;
if( got<0 ){
((unixFile*)id)->lastErrno = errno;
}
OSTRACE(("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
return got;
return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno);
}
@@ -4322,24 +4335,32 @@ static int unixShmMap(
if( sStat.st_size<nByte ){
/* The requested memory region does not exist. If bExtend is set to
** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
**
** Alternatively, if bExtend is true, use ftruncate() to allocate
** the requested memory region.
*/
if( !bExtend ) goto shmpage_out;
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
pShmNode->zFilename);
if( !bExtend ){
goto shmpage_out;
}
#else
if( robust_ftruncate(pShmNode->h, nByte) ){
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
pShmNode->zFilename);
goto shmpage_out;
/* Alternatively, if bExtend is true, extend the file. Do this by
** writing a single byte to the end of each (OS) page being
** allocated or extended. Technically, we need only write to the
** last page in order to extend the file. But writing to all new
** pages forces the OS to allocate them immediately, which reduces
** the chances of SIGBUS while accessing the mapped region later on.
*/
else{
static const int pgsz = 4096;
int iPg;
/* Write to the last byte of each newly allocated or extended page */
assert( (nByte % pgsz)==0 );
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
goto shmpage_out;
}
}
}
#endif
}
}