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

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
This commit is contained in:
dan
2011-04-01 11:56:32 +00:00
parent 211fb08433
commit ea83bc614e
4 changed files with 46 additions and 52 deletions

View File

@@ -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;
}