From: dan Date: Fri, 1 Apr 2011 11:56:32 +0000 (+0000) Subject: In os_unix.c, do not return SQLITE_BUSY to SQLite following an error in fcntl(F_UNLCK... X-Git-Tag: version-3.7.6~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea83bc614eb05ac266e0375f883169d677fd52d1;p=thirdparty%2Fsqlite.git In os_unix.c, do not return SQLITE_BUSY to SQLite following an error in fcntl(F_UNLCK), regardless of the value of errno. FossilOrigin-Name: ff6dfe6ed74f9ff1669b2bda41d61a01cd0a1bc6 --- diff --git a/manifest b/manifest index a3f317b4e1..662518317a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sproblems\sin\sos_unix.c\swhen\scompiled\swith\sENABLE_LOCKING_STYLE\son\sOSX.\sAlso\ssome\sminor\sissues\swith\stest\sscripts. -D 2011-04-01T09:04:37 +C In\sos_unix.c,\sdo\snot\sreturn\sSQLITE_BUSY\sto\sSQLite\sfollowing\san\serror\sin\sfcntl(F_UNLCK),\sregardless\sof\sthe\svalue\sof\serrno. +D 2011-04-01T11:56:33 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -162,7 +162,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf -F src/os_unix.c 9a129123a054572d4d8cf1766fb093b0e45ab57c +F src/os_unix.c 8115c85152a7fce1bccdc195e3b0aeffcea2afd7 F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -673,7 +673,7 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082 F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3 F test/syscall.test d1dae1fee88613cf763d97ad0038d867509e0c42 -F test/sysfault.test a2c3ca66d82f3b4ac7d29f1aeaba8962f4f5a22a +F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f F test/table.test 04ba066432430657712d167ebf28080fe878d305 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3 @@ -920,7 +920,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e3bf2d5ce4f87535e030a446e03d911f421805f7 -R c7b1df6afcd246671bef4e02c46ac2c9 +P 8088031bc949bd4efb5edf33bbd1bce5700fca56 +R 9af7bbe929f0a94074f942a296a7973f U dan -Z f228344db51d960df69afeb4fae2d9e8 +Z d897a548359e67df244f4d51f77e5957 diff --git a/manifest.uuid b/manifest.uuid index cf5632fe46..2f3043a27c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8088031bc949bd4efb5edf33bbd1bce5700fca56 \ No newline at end of file +ff6dfe6ed74f9ff1669b2bda41d61a01cd0a1bc6 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 4799181072..6f93351112 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -630,8 +630,15 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { case EPERM: return SQLITE_PERM; + /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And + ** this module never makes such a call. And the code in SQLite itself + ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons + ** this case is also commented out. If the system does set errno to EDEADLK, + ** the default SQLITE_IOERR_XXX code will be returned. */ +#if 0 case EDEADLK: return SQLITE_IOERR_BLOCKED; +#endif #if EOPNOTSUPP!=ENOTSUP case EOPNOTSUPP: @@ -1192,10 +1199,9 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; - if (-1 == osFcntl(pFile->h, F_GETLK, &lock)) { - int tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); - pFile->lastErrno = tErrno; + if( osFcntl(pFile->h, F_GETLK, &lock) ){ + rc = SQLITE_IOERR_CHECKRESERVEDLOCK; + pFile->lastErrno = errno; } else if( lock.l_type!=F_UNLCK ){ reserved = 1; } @@ -1425,7 +1431,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ /* This could happen with a network mount */ tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; } if( rc ){ @@ -1596,7 +1602,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_len = divSize; if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } @@ -1620,7 +1626,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_len = SHARED_SIZE-divSize; if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } @@ -1634,11 +1640,14 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; if( unixFileLock(pFile, &lock) ){ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); - if( rc!=SQLITE_BUSY ){ - pFile->lastErrno = tErrno; - } + /* In theory, the call to unixFileLock() cannot fail because another + ** process is holding an incompatible lock. If it does, this + ** indicates that the other process is not following the locking + ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ + rc = SQLITE_IOERR_RDLOCK; + pFile->lastErrno = errno; goto end_unlock; } } @@ -1650,11 +1659,8 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( unixFileLock(pFile, &lock)==0 ){ pInode->eFileLock = SHARED_LOCK; }else{ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( rc!=SQLITE_BUSY ){ - pFile->lastErrno = tErrno; - } + rc = SQLITE_IOERR_UNLOCK; + pFile->lastErrno = errno; goto end_unlock; } } @@ -1674,11 +1680,8 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( unixFileLock(pFile, &lock)==0 ){ pInode->eFileLock = NO_LOCK; }else{ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( rc!=SQLITE_BUSY ){ - pFile->lastErrno = tErrno; - } + rc = SQLITE_IOERR_UNLOCK; + pFile->lastErrno = errno; pInode->eFileLock = NO_LOCK; pFile->eFileLock = NO_LOCK; } @@ -1986,7 +1989,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) { int rc = 0; int tErrno = errno; if( ENOENT != tErrno ){ - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + rc = SQLITE_IOERR_UNLOCK; } if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -2074,7 +2077,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ if ( lrc ) { int tErrno = errno; /* unlock failed with an error */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + lrc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(lrc) ){ pFile->lastErrno = tErrno; rc = lrc; @@ -2196,21 +2199,12 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) { } /* no, really, unlock. */ - int rc = robust_flock(pFile->h, LOCK_UN); - if (rc) { - int r, tErrno = errno; - r = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( IS_LOCK_ERROR(r) ){ - pFile->lastErrno = tErrno; - } + if( robust_flock(pFile->h, LOCK_UN) ){ #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (r & SQLITE_IOERR) == SQLITE_IOERR ){ - r = SQLITE_BUSY; - } + return SQLITE_OK; #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - - return r; - } else { + return SQLITE_IOERR_UNLOCK; + }else{ pFile->eFileLock = NO_LOCK; return SQLITE_OK; } diff --git a/test/sysfault.test b/test/sysfault.test index c8c6f512f1..07d525ca9e 100644 --- a/test/sysfault.test +++ b/test/sysfault.test @@ -94,13 +94,13 @@ foreach {tn errno errlist} { # foreach vfs {unix unix-excl} { foreach {tn errno errlist} { - 1 EAGAIN {{database is locked}} - 2 ETIMEDOUT {{database is locked}} - 3 EBUSY {{database is locked}} - 4 EINTR {{database is locked}} - 5 ENOLCK {{database is locked}} - 6 EACCES {{database is locked}} - 7 EPERM {{access permission denied}} + 1 EAGAIN {{database is locked} {disk I/O error}} + 2 ETIMEDOUT {{database is locked} {disk I/O error}} + 3 EBUSY {{database is locked} {disk I/O error}} + 4 EINTR {{database is locked} {disk I/O error}} + 5 ENOLCK {{database is locked} {disk I/O error}} + 6 EACCES {{database is locked} {disk I/O error}} + 7 EPERM {{access permission denied} {disk I/O error}} 8 EDEADLK {{disk I/O error}} 9 ENOMEM {{disk I/O error}} } {