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:
115
src/os_unix.c
115
src/os_unix.c
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user