From 47a2b4a0b0067bcae3960bb07e616589d509def2 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Apr 2013 16:09:29 +0000 Subject: [PATCH] Avoid using posix_fallocate() in WAL mode, as it is not supported by all file-systems. FossilOrigin-Name: 9c7523dabf4aee609287732ce787c9b9a9087e7f --- manifest | 15 ++++--- manifest.uuid | 2 +- src/os_unix.c | 109 ++++++++++++++++++++++++++++++-------------------- 3 files changed, 75 insertions(+), 51 deletions(-) diff --git a/manifest b/manifest index 914f1bde6e..72d6bee5a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rebalance\sFTS\sexpressions\safter\sparsing\sto\slimit\srecursion\sduring\sevaluation.\sAvoid\srecursion\swhen\sdeleting\sFTS\sexpression\strees.\sEnforce\sa\slimit\s(currently\s12)\son\sthe\sdepth\sof\san\sexpression\stree. -D 2013-04-26T14:13:15.156 +C Avoid\susing\sposix_fallocate()\sin\sWAL\smode,\sas\sit\sis\snot\ssupported\sby\sall\sfile-systems. +D 2013-04-26T16:09:29.947 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,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 460752b8575320163d2659bb7ff24aff41e2bb66 2648966f17bc1b783ef6d3b2368c613f6e02945e -R 3adacbaf5ab67ae1f94478e13972158e +P 49d23ef61f9ce2ffe13237b51a0e01b0b46ba96b +R c26b6b9eda44a997204fb8564cbd02a4 +T *branch * avoid-fallocate +T *sym-avoid-fallocate * +T -sym-trunk * U dan -Z 40f0df5151b2a7d6fa4a01e133941564 +Z 8ca670519b4ace84695b56a8d0f2a643 diff --git a/manifest.uuid b/manifest.uuid index 64a0465053..a357f425fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49d23ef61f9ce2ffe13237b51a0e01b0b46ba96b \ No newline at end of file +9c7523dabf4aee609287732ce787c9b9a9087e7f \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 7448afe4c7..1200ff352b 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_sizeh, 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 } } -- 2.39.5