aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordan <dan@noemail.net>2013-04-26 17:00:52 +0000
committerdan <dan@noemail.net>2013-04-26 17:00:52 +0000
commit77b428aa33b4fe7f070a79f610bfd38d7d50a30f (patch)
tree2ebf9febc89be2c333675f4c27416ce291fa61c6
parent9ea88b2b484b0d80ccc0e194e70a03c545f3fdf5 (diff)
parent47a2b4a0b0067bcae3960bb07e616589d509def2 (diff)
downloadsqlite-77b428aa33b4fe7f070a79f610bfd38d7d50a30f.tar.gz
sqlite-77b428aa33b4fe7f070a79f610bfd38d7d50a30f.zip
Avoid using posix_fallocate() in WAL mode, as it is not supported by all file-systems.
FossilOrigin-Name: 1bbb4be1a25947f75b2b0c6f368199016b6f7de3
-rw-r--r--manifest14
-rw-r--r--manifest.uuid2
-rw-r--r--src/os_unix.c109
3 files changed, 73 insertions, 52 deletions
diff --git a/manifest b/manifest
index 59fe24e66..de4051d56 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sdocumentation\swith\snew\shyperlinks.\s\sNo\schanges\sto\scode.
-D 2013-04-26T15:55:57.095
+C Avoid\susing\sposix_fallocate()\sin\sWAL\smode,\sas\sit\sis\snot\ssupported\sby\sall\sfile-systems.
+D 2013-04-26T17:00:52.665
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ce81671efd6223d19d4c8c6b88ac2c4134427111
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -177,7 +177,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
-F src/os_unix.c 5a9ac4a566fb566a2ff9b9e3a9d723075d9d26a7
+F src/os_unix.c f86cd628ffb9ccf3adcc5c15b02c00a64eaf598e
F src/os_win.c 673b3e3d1fa3040d8d95a7f1f5e0e553aed56cfb
F src/pager.c 6c3a8a5d665498b0344395a2c9f82d5abc4cc771
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
@@ -1062,7 +1062,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 49d23ef61f9ce2ffe13237b51a0e01b0b46ba96b
-R 9dfdc1bbf9c2e5197fa469091ec011ea
-U drh
-Z 247eb74d6133c2eb692e1fce731d0d35
+P 640eb54ad6aac9bc7109cba167389a9bcec3f21e 9c7523dabf4aee609287732ce787c9b9a9087e7f
+R b4ea9ecffc738493e7005d865dad4b9a
+U dan
+Z 8914d43d4bd2278afd40d03ae3982d74
diff --git a/manifest.uuid b/manifest.uuid
index de2ac0cb3..86ca24f5f 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-640eb54ad6aac9bc7109cba167389a9bcec3f21e \ No newline at end of file
+1bbb4be1a25947f75b2b0c6f368199016b6f7de3 \ No newline at end of file
diff --git a/src/os_unix.c b/src/os_unix.c
index 7448afe4c..1200ff352 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3194,46 +3194,59 @@ static int unixRead(
}
/*
-** Seek to the offset in id->offset then read cnt bytes into pBuf.
-** Return the number of bytes actually read. Update the offset.
-**
-** To avoid stomping the errno value on a failed write the lastErrno value
-** 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;
+** 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{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
+ do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
#elif defined(USE_PREAD64)
- do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
+ do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<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;
- }
+ i64 iSeek = lseek(fd, iOff, SEEK_SET);
+ SimulateIOError( iSeek-- );
+
+ if( iSeek!=iOff ){
+ if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
return -1;
}
- got = osWrite(id->h, pBuf, cnt);
- }while( got<0 && errno==EINTR );
+ rc = osWrite(fd, pBuf, nBuf);
+ }while( rc<0 && errno==EINTR );
#endif
+
TIMER_END;
- if( got<0 ){
- ((unixFile*)id)->lastErrno = errno;
- }
+ OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
+
+ if( rc<0 && piErrno ) *piErrno = errno;
+ return rc;
+}
+
- OSTRACE(("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
- return got;
+/*
+** Seek to the offset in id->offset then read cnt bytes into pBuf.
+** Return the number of bytes actually read. Update the offset.
+**
+** To avoid stomping the errno value on a failed write the lastErrno value
+** is set before returning.
+*/
+static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
+ 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
}
}