From ad94b58a5e478d1476449de265fd91498250d651 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Mon, 20 Aug 2007 06:44:22 +0000 Subject: [PATCH] Update the locking-style code in os_unix.c. The updates are as yet untested. (CVS 4244) FossilOrigin-Name: 41f2175b1ed7eccf271b687ee5c3ea262a0cd096 --- manifest | 12 +- manifest.uuid | 2 +- src/os_unix.c | 628 +++++++++++++++++--------------------------------- 3 files changed, 216 insertions(+), 426 deletions(-) diff --git a/manifest b/manifest index 0640fb4c1f..013fe39644 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfull_fsync()\srelated\sfunctionality\sbroken\sas\spart\sof\sthe\smigration\sto\ssqlite3_vfs.\s(CVS\s4243) -D 2007-08-20T05:36:51 +C Update\sthe\slocking-style\scode\sin\sos_unix.c.\sThe\supdates\sare\sas\syet\suntested.\s(CVS\s4244) +D 2007-08-20T06:44:22 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -98,7 +98,7 @@ F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446 F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 -F src/os_unix.c bf192a86b9aa5ca3889613fde9bac084274f5eed +F src/os_unix.c dc726e5fa18f114c4a7e0a0205af0ea898b85374 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b @@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P a258c4ec240f96bccfe493e98d0827ec7dd12e67 -R 92a15d078029bdab5b614dc93495e5a2 +P cb24cda179c2b526c5ac48be75e372d2b9db808c +R a091562a0f5306b5cbde266cfb56849b U danielk1977 -Z 04438648939c1033589e63dd0eec6b5f +Z fa00070b2e6492f7113b7bd3fe1e6225 diff --git a/manifest.uuid b/manifest.uuid index 31b1e74128..bfaf77d55e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb24cda179c2b526c5ac48be75e372d2b9db808c \ No newline at end of file +41f2175b1ed7eccf271b687ee5c3ea262a0cd096 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 15bf9d2214..f1575562ed 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -81,7 +81,7 @@ /* -** The unixFile structure is subclass of OsFile specific for the unix +** The unixFile structure is subclass of sqlite3_file specific for the unix ** protability layer. */ typedef struct unixFile unixFile; @@ -98,7 +98,7 @@ struct unixFile { int dirfd; /* File descriptor for the directory */ i64 offset; /* Seek offset */ #ifdef SQLITE_UNIX_THREADS - pthread_t tid; /* The thread that "owns" this OsFile */ + pthread_t tid; /* The thread that "owns" this unixFile */ #endif }; @@ -134,7 +134,6 @@ struct unixFile { */ #ifndef SQLITE_OMIT_DISKIO - /* ** Define various macros that are missing from some systems. */ @@ -173,18 +172,18 @@ struct unixFile { #endif /* -** Set or check the OsFile.tid field. This field is set when an OsFile -** is first opened. All subsequent uses of the OsFile verify that the -** same thread is operating on the OsFile. Some operating systems do +** Set or check the unixFile.tid field. This field is set when an unixFile +** is first opened. All subsequent uses of the unixFile verify that the +** same thread is operating on the unixFile. Some operating systems do ** not allow locks to be overridden by other threads and that restriction ** means that sqlite3* database handles cannot be moved from one thread ** to another. This logic makes sure a user does not try to do that ** by mistake. ** -** Version 3.3.1 (2006-01-15): OsFiles can be moved from one thread to +** Version 3.3.1 (2006-01-15): unixFile can be moved from one thread to ** another as long as we are running on a system that supports threads ** overriding each others locks (which now the most common behavior) -** or if no locks are held. But the OsFile.pLock field needs to be +** or if no locks are held. But the unixFile.pLock field needs to be ** recomputed because its key includes the thread-id. See the ** transferOwnership() function below for additional information */ @@ -232,11 +231,11 @@ struct unixFile { ** locks to see if another thread has previously set a lock on that same ** inode. ** -** The OsFile structure for POSIX is no longer just an integer file +** The sqlite3_file structure for POSIX is no longer just an integer file ** descriptor. It is now a structure that holds the integer file ** descriptor and a pointer to a structure that describes the internal ** locks on the corresponding inode. There is one locking structure -** per inode, so if the same inode is opened twice, both OsFile structures +** per inode, so if the same inode is opened twice, both unixFile structures ** point to the same locking structure. The locking structure keeps ** a reference count (so we will know when to delete it) and a "cnt" ** field that tells us its internal lock status. cnt==0 means the @@ -255,11 +254,11 @@ struct unixFile { ** ** If you close a file descriptor that points to a file that has locks, ** all locks on that file that are owned by the current process are -** released. To work around this problem, each OsFile structure contains +** released. To work around this problem, each unixFile structure contains ** a pointer to an openCnt structure. There is one openCnt structure -** per open inode, which means that multiple OsFiles can point to a single -** openCnt. When an attempt is made to close an OsFile, if there are -** other OsFiles open on the same inode that are holding locks, the call +** per open inode, which means that multiple unixFile can point to a single +** openCnt. When an attempt is made to close an unixFile, if there are +** other unixFile open on the same inode that are holding locks, the call ** to close() the file descriptor is deferred until all of the locks clear. ** The openCnt structure keeps a list of file descriptors that need to ** be closed and that list is walked (and cleared) when the last lock @@ -319,9 +318,9 @@ struct lockKey { ** inode on each thread with a different process ID. (Threads have ** different process IDs on linux, but not on most other unixes.) ** -** A single inode can have multiple file descriptors, so each OsFile +** A single inode can have multiple file descriptors, so each unixFile ** structure contains a pointer to an instance of this object and this -** object keeps a count of the number of OsFiles pointing to it. +** object keeps a count of the number of unixFile pointing to it. */ struct lockInfo { struct lockKey key; /* The lookup key */ @@ -389,6 +388,9 @@ typedef enum { } sqlite3LockingStyle; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ +/* +** Helper functions to obtain and relinquish the global mutex. +*/ static void enterMutex(){ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); } @@ -567,8 +569,10 @@ static void releaseOpenCnt(struct openCnt *pOpen){ ** Tests a byte-range locking query to see if byte range locks are ** supported, if not we fall back to dotlockLockingStyle. */ -static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath, - int fd) { +static sqlite3LockingStyle sqlite3TestLockingStyle( + const char *filePath, + int fd +){ /* test byte-range lock using fcntl */ struct flock lockInfo; @@ -577,7 +581,7 @@ static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath, lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if (fcntl(fd, F_GETLK, &lockInfo) != -1) { + if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { return posixLockingStyle; } @@ -594,8 +598,10 @@ static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath, ** assignments are based on Darwin/OSX behavior and have not been tested on ** other systems. */ -static sqlite3LockingStyle sqlite3DetectLockingStyle(const char *filePath, - int fd) { +static sqlite3LockingStyle sqlite3DetectLockingStyle( + const char *filePath, + int fd +){ #ifdef SQLITE_FIXED_LOCKING_STYLE return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE; @@ -790,178 +796,6 @@ static int transferOwnership(unixFile *pFile){ # define transferOwnership(X) SQLITE_OK #endif -/* -** Delete the named file -*/ -int sqlite3UnixDelete(const char *zFilename){ - SimulateIOError(return SQLITE_IOERR_DELETE); - unlink(zFilename); - return SQLITE_OK; -} - -/* -** Return TRUE if the named file exists. -*/ -int sqlite3UnixFileExists(const char *zFilename){ - return access(zFilename, 0)==0; -} - -/* -** Attempt to open a file for both reading and writing. If that -** fails, try opening it read-only. If the file does not exist, -** try to create it. -** -** On success, a handle for the open file is written to *id -** and *pReadonly is set to 0 if the file was opened for reading and -** writing or 1 if the file was opened read-only. The function returns -** SQLITE_OK. -** -** On failure, the function returns SQLITE_CANTOPEN and leaves -** *id and *pReadonly unchanged. -*/ -#if 0 -int sqlite3UnixOpenReadWrite( - const char *zFilename, - sqlite3_file **pId, - int *pReadonly -){ - int h; - - assert( 0==*pId ); - h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, - SQLITE_DEFAULT_FILE_PERMISSIONS); - if( h<0 ){ -#ifdef EISDIR - if( errno==EISDIR ){ - return SQLITE_CANTOPEN; - } -#endif - h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); - if( h<0 ){ - return SQLITE_CANTOPEN; - } - *pReadonly = 1; - }else{ - *pReadonly = 0; - } - - return CRASH_TEST_OVERRIDE( - zFilename, pId, allocateUnixFile(h, pId, zFilename, 0) - ); -} - - -/* -** Attempt to open a new file for exclusive access by this process. -** The file will be opened for both reading and writing. To avoid -** a potential security problem, we do not allow the file to have -** previously existed. Nor do we allow the file to be a symbolic -** link. -** -** If delFlag is true, then make arrangements to automatically delete -** the file when it is closed. -** -** On success, write the file handle into *id and return SQLITE_OK. -** -** On failure, return SQLITE_CANTOPEN. -*/ -int sqlite3UnixOpenExclusive( - const char *zFilename, - sqlite3_file **pId, - int delFlag -){ - int h; - - assert( 0==*pId ); - h = open(zFilename, - O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, - delFlag ? 0600 : SQLITE_DEFAULT_FILE_PERMISSIONS); - if( h<0 ){ - return SQLITE_CANTOPEN; - } - return CRASH_TEST_OVERRIDE( - zFilename, pId, allocateUnixFile(h, pId, zFilename, delFlag) - ); -} - -/* -** Attempt to open a new file for read-only access. -** -** On success, write the file handle into *id and return SQLITE_OK. -** -** On failure, return SQLITE_CANTOPEN. -*/ -int sqlite3UnixOpenReadOnly(const char *zFilename, sqlite3_file **pId){ - int h; - - assert( 0==*pId ); - h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); - if( h<0 ){ - return SQLITE_CANTOPEN; - } - return CRASH_TEST_OVERRIDE( - zFilename, pId, allocateUnixFile(h, pId, zFilename, 0) - ); -} -#endif - -/* -** Attempt to open a file descriptor for the directory that contains a -** file. This file descriptor can be used to fsync() the directory -** in order to make sure the creation of a new file is actually written -** to disk. -** -** This routine is only meaningful for Unix. It is a no-op under -** windows since windows does not support hard links. -** -** If FULL_FSYNC is enabled, this function is not longer useful, -** a FULL_FSYNC sync applies to all pending disk operations. -** -** On success, a handle for a previously open file at *id is -** updated with the new directory file descriptor and SQLITE_OK is -** returned. -** -** On failure, the function returns SQLITE_CANTOPEN and leaves -** *id unchanged. -*/ -#if 0 -static int unixOpenDirectory( - OsFile *id, - const char *zDirname -){ - int h; - unixFile *pFile = (unixFile*)id; - assert( pFile!=0 ); - SET_THREADID(pFile); - assert( pFile->dirfd<0 ); - pFile->dirfd = h = open(zDirname, O_RDONLY|O_BINARY, 0); - if( h<0 ){ - return SQLITE_CANTOPEN; - } -#ifdef FD_CLOEXEC - fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC); -#endif - OSTRACE3("OPENDIR %-3d %s\n", h, zDirname); - return SQLITE_OK; -} -#endif - -/* -** Check that a given pathname is a directory and is writable -** -*/ -int sqlite3UnixIsDirWritable(char *zBuf){ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - struct stat buf; - if( zBuf==0 ) return 0; - if( zBuf[0]==0 ) return 0; - if( stat(zBuf, &buf) ) return 0; - if( !S_ISDIR(buf.st_mode) ) return 0; - if( access(zBuf, 07) ) return 0; -#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ - return 1; -} - /* ** Seek to the offset in id->offset then read cnt bytes into pBuf. ** Return the number of bytes actually read. Update the offset. @@ -1214,36 +1048,6 @@ static int unixSync(sqlite3_file *id, int flags){ return SQLITE_OK; } -/* -** Sync the directory zDirname. This is a no-op on operating systems other -** than UNIX. -** -** This is used to make sure the master journal file has truely been deleted -** before making changes to individual journals on a multi-database commit. -** The F_FULLFSYNC option is not needed here. -*/ -int sqlite3UnixSyncDirectory(const char *zDirname){ -#ifdef SQLITE_DISABLE_DIRSYNC - return SQLITE_OK; -#else - int fd; - int r; - fd = open(zDirname, O_RDONLY|O_BINARY, 0); - OSTRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname); - if( fd<0 ){ - return SQLITE_CANTOPEN; - } - r = fsync(fd); - close(fd); - SimulateIOError( r=1 ); - if( r ){ - return SQLITE_IOERR_DIR_FSYNC; - }else{ - return SQLITE_OK; - } -#endif -} - /* ** Truncate an open file to a specified size */ @@ -1388,7 +1192,7 @@ static int unixLock(sqlite3_file *id, int locktype){ locktypeName(pLock->locktype), pLock->cnt , getpid()); /* If there is already a lock of this type or more restrictive on the - ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** unixFile, do nothing. Don't use the end_lock: exit path, as ** enterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ @@ -1416,7 +1220,7 @@ static int unixLock(sqlite3_file *id, int locktype){ } pLock = pFile->pLock; - /* If some thread using this PID has a lock via a different OsFile* + /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ if( (pFile->locktype!=pLock->locktype && @@ -1689,13 +1493,19 @@ struct ByteRangeLockPB2 #define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) -/* return 0 on success, 1 on failure. To match the behavior of the - normal posix file locking (used in unixLock for example), we should - provide 'richer' return codes - specifically to differentiate between - 'file busy' and 'file system error' results */ -static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset, - unsigned long long length, int setLockFlag) -{ +/* +** Return 0 on success, 1 on failure. To match the behavior of the +** normal posix file locking (used in unixLock for example), we should +** provide 'richer' return codes - specifically to differentiate between +** 'file busy' and 'file system error' results. +*/ +static int _AFPFSSetLock( + const char *path, + int fd, + unsigned long long offset, + unsigned long long length, + int setLockFlag +){ struct ByteRangeLockPB2 pb; int err; @@ -1722,7 +1532,7 @@ static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset, ** non-zero. If the file is unlocked or holds only SHARED locks, then ** return zero. */ -static int afpUnixCheckReservedLock(OsFile *id){ +static int afpUnixCheckReservedLock(sqlite3_file *id){ int r = 0; unixFile *pFile = (unixFile*)id; @@ -1755,7 +1565,7 @@ static int afpUnixCheckReservedLock(OsFile *id){ /* AFP-style locking following the behavior of unixLock, see the unixLock ** function comments for details of lock management. */ -static int afpUnixLock(OsFile *id, int locktype) +static int afpUnixLock(sqlite3_file *id, int locktype) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; @@ -1766,7 +1576,7 @@ static int afpUnixLock(OsFile *id, int locktype) OSTRACE5("LOCK %d %s was %s pid=%d\n", pFile->h, locktypeName(locktype), locktypeName(pFile->locktype), getpid()); /* If there is already a lock of this type or more restrictive on the - ** OsFile, do nothing. Don't use the afp_end_lock: exit path, as + ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as ** enterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ @@ -1889,7 +1699,7 @@ afp_end_lock: ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int afpUnixUnlock(OsFile *id, int locktype) { +static int afpUnixUnlock(sqlite3_file *id, int locktype) { struct flock lock; int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; @@ -1957,26 +1767,24 @@ static int afpUnixUnlock(OsFile *id, int locktype) { /* ** Close a file & cleanup AFP specific locking context */ -static int afpUnixClose(OsFile **pId) { - unixFile *id = (unixFile*)*pId; - - if( !id ) return SQLITE_OK; +static int afpUnixClose(sqlite3_file *id) { + unixFile *pFile = (unixFile*)pId; + + if( !pFile ) return SQLITE_OK; afpUnixUnlock(*pId, NO_LOCK); /* free the AFP locking structure */ - if (id->lockingContext != NULL) { - if (((afpLockingContext *)id->lockingContext)->filePath != NULL) - sqlite3_free(((afpLockingContext*)id->lockingContext)->filePath); - sqlite3_free(id->lockingContext); + if (pFile->lockingContext != NULL) { + if (((afpLockingContext *)pFile->lockingContext)->filePath != NULL) + sqlite3_free(((afpLockingContext*)pFile->lockingContext)->filePath); + sqlite3_free(pFile->lockingContext); } - - if( id->dirfd>=0 ) close(id->dirfd); - id->dirfd = -1; - close(id->h); - id->isOpen = 0; - OSTRACE2("CLOSE %-3d\n", id->h); + + if( pFile->dirfd>=0 ) close(pFile->dirfd); + pFile->dirfd = -1; + close(pFile->h); + pFile->isOpen = 0; + OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); - sqlite3_free(id); - *pId = 0; return SQLITE_OK; } @@ -1988,7 +1796,7 @@ static int afpUnixClose(OsFile **pId) { */ typedef void flockLockingContext; -static int flockUnixCheckReservedLock(OsFile *id) { +static int flockUnixCheckReservedLock(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; if (pFile->locktype == RESERVED_LOCK) { @@ -2005,7 +1813,7 @@ static int flockUnixCheckReservedLock(OsFile *id) { } } -static int flockUnixLock(OsFile *id, int locktype) { +static int flockUnixLock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; /* if we already have a lock, it is exclusive. @@ -2027,7 +1835,7 @@ static int flockUnixLock(OsFile *id, int locktype) { } } -static int flockUnixUnlock(OsFile *id, int locktype) { +static int flockUnixUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; assert( locktype<=SHARED_LOCK ); @@ -2056,23 +1864,21 @@ static int flockUnixUnlock(OsFile *id, int locktype) { /* ** Close a file. */ -static int flockUnixClose(OsFile **pId) { - unixFile *id = (unixFile*)*pId; +static int flockUnixClose(sqlite3_file *pId) { + unixFile *pFile = (unixFile*)*pId; - if( !id ) return SQLITE_OK; + if( !pFile ) return SQLITE_OK; flockUnixUnlock(*pId, NO_LOCK); - if( id->dirfd>=0 ) close(id->dirfd); - id->dirfd = -1; + if( pFile->dirfd>=0 ) close(pFile->dirfd); + pFile->dirfd = -1; enterMutex(); - close(id->h); + close(pFile->h); leaveMutex(); - id->isOpen = 0; - OSTRACE2("CLOSE %-3d\n", id->h); + pFile->isOpen = 0; + OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); - sqlite3_free(id); - *pId = 0; return SQLITE_OK; } @@ -2088,7 +1894,7 @@ struct dotlockLockingContext { }; -static int dotlockUnixCheckReservedLock(OsFile *id) { +static int dotlockUnixCheckReservedLock(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; dotlockLockingContext *context = (dotlockLockingContext *) pFile->lockingContext; @@ -2106,7 +1912,7 @@ static int dotlockUnixCheckReservedLock(OsFile *id) { } } -static int dotlockUnixLock(OsFile *id, int locktype) { +static int dotlockUnixLock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; dotlockLockingContext *context = (dotlockLockingContext *) pFile->lockingContext; @@ -2140,7 +1946,7 @@ static int dotlockUnixLock(OsFile *id, int locktype) { return SQLITE_OK; } -static int dotlockUnixUnlock(OsFile *id, int locktype) { +static int dotlockUnixUnlock(sqlite3_file *id, int locktype) { unixFile *pFile = (unixFile*)id; dotlockLockingContext *context = (dotlockLockingContext *) pFile->lockingContext; @@ -2167,31 +1973,29 @@ static int dotlockUnixUnlock(OsFile *id, int locktype) { /* ** Close a file. */ -static int dotlockUnixClose(OsFile **pId) { - unixFile *id = (unixFile*)*pId; +static int dotlockUnixClose(sqlite3_file *id) { + unixFile *pFile = (unixFile*)id; - if( !id ) return SQLITE_OK; + if( !pFile ) return SQLITE_OK; dotlockUnixUnlock(*pId, NO_LOCK); /* free the dotlock locking structure */ - if (id->lockingContext != NULL) { - if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL) + if (pFile->lockingContext != NULL) { + if (((dotlockLockingContext *)pFile->lockingContext)->lockPath != NULL) sqlite3_free( ( (dotlockLockingContext *) - id->lockingContext)->lockPath); - sqlite3_free(id->lockingContext); + pFile->lockingContext)->lockPath); + sqlite3_free(pFile->lockingContext); } - if( id->dirfd>=0 ) close(id->dirfd); - id->dirfd = -1; + if( pFile->dirfd>=0 ) close(pFile->dirfd); + pFile->dirfd = -1; enterMutex(); - close(id->h); + close(pFile->h); leaveMutex(); - id->isOpen = 0; - OSTRACE2("CLOSE %-3d\n", id->h); + pFile->isOpen = 0; + OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); - sqlite3_free(id); - *pId = 0; return SQLITE_OK; } @@ -2203,59 +2007,57 @@ static int dotlockUnixClose(OsFile **pId) { */ typedef void nolockLockingContext; -static int nolockUnixCheckReservedLock(OsFile *id) { +static int nolockUnixCheckReservedLock(sqlite3_file *id) { return 0; } -static int nolockUnixLock(OsFile *id, int locktype) { +static int nolockUnixLock(sqlite3_file *id, int locktype) { return SQLITE_OK; } -static int nolockUnixUnlock(OsFile *id, int locktype) { +static int nolockUnixUnlock(sqlite3_file *id, int locktype) { return SQLITE_OK; } /* ** Close a file. */ -static int nolockUnixClose(OsFile **pId) { - unixFile *id = (unixFile*)*pId; +static int nolockUnixClose(sqlite3_file *id) { + unixFile *pFile = (unixFile*)id; - if( !id ) return SQLITE_OK; - if( id->dirfd>=0 ) close(id->dirfd); - id->dirfd = -1; + if( !pFile ) return SQLITE_OK; + if( pFile->dirfd>=0 ) close(pFile->dirfd); + pFile->dirfd = -1; enterMutex(); - close(id->h); + close(pFile->h); leaveMutex(); - id->isOpen = 0; - OSTRACE2("CLOSE %-3d\n", id->h); + pFile->isOpen = 0; + OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); - sqlite3_free(id); - *pId = 0; return SQLITE_OK; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ -#if 0 + /* -** Change the value of the fullsync flag in the given file descriptor. +** TODO: xBreakLock() for this vfs. */ -static void unixSetFullSync(OsFile *id, int v){ - ((unixFile*)id)->fullSync = v; +static int unixBreakLock(sqlite3_file *id){ + assert(!"TODO: unixBreakLock()"); + return 0; } /* -** Return the underlying file handle for an OsFile +** Return an integer that indices the type of lock currently held +** by this handle. (Used for testing and analysis only.) */ -static int unixFileHandle(OsFile *id){ - return ((unixFile*)id)->h; +static int unixLockState(sqlite3_file *id){ + return ((unixFile*)id)->locktype; } -#endif - /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be @@ -2277,21 +2079,8 @@ static int unixDeviceCharacteristics(sqlite3_file *id){ return 0; } -static int unixBreakLock(sqlite3_file *id){ - assert(!"TODO: unixBreakLock()"); - return 0; -} - /* -** Return an integer that indices the type of lock currently held -** by this handle. (Used for testing and analysis only.) -*/ -static int unixLockState(sqlite3_file *id){ - return ((unixFile*)id)->locktype; -} - -/* -** This vector defines all the methods that can operate on an OsFile +** This vector defines all the methods that can operate on an sqlite3_file ** for unix. */ static const sqlite3_io_methods sqlite3UnixIoMethod = { @@ -2313,91 +2102,87 @@ static const sqlite3_io_methods sqlite3UnixIoMethod = { #ifdef SQLITE_ENABLE_LOCKING_STYLE /* - ** This vector defines all the methods that can operate on an OsFile - ** for unix with AFP style file locking. - */ -static const IoMethod sqlite3AFPLockingUnixIoMethod = { - afpUnixClose, - unixOpenDirectory, - unixRead, - unixWrite, - unixSeek, - unixTruncate, - unixSync, - unixSetFullSync, - unixFileHandle, - unixFileSize, - afpUnixLock, - afpUnixUnlock, - unixLockState, - afpUnixCheckReservedLock, - unixSectorSize, -}; - -/* - ** This vector defines all the methods that can operate on an OsFile - ** for unix with flock() style file locking. - */ -static const IoMethod sqlite3FlockLockingUnixIoMethod = { - flockUnixClose, - unixOpenDirectory, - unixRead, - unixWrite, - unixSeek, - unixTruncate, - unixSync, - unixSetFullSync, - unixFileHandle, - unixFileSize, - flockUnixLock, - flockUnixUnlock, - unixLockState, - flockUnixCheckReservedLock, - unixSectorSize, -}; - -/* - ** This vector defines all the methods that can operate on an OsFile - ** for unix with dotlock style file locking. - */ -static const IoMethod sqlite3DotlockLockingUnixIoMethod = { - dotlockUnixClose, - unixOpenDirectory, - unixRead, - unixWrite, - unixSeek, - unixTruncate, - unixSync, - unixSetFullSync, - unixFileHandle, - unixFileSize, - dotlockUnixLock, - dotlockUnixUnlock, - unixLockState, - dotlockUnixCheckReservedLock, - unixSectorSize, -}; - -/* - ** This vector defines all the methods that can operate on an OsFile - ** for unix with dotlock style file locking. - */ -static const IoMethod sqlite3NolockLockingUnixIoMethod = { - nolockUnixClose, - unixOpenDirectory, +** This vector defines all the methods that can operate on an sqlite3_file +** for unix with AFP style file locking. +*/ +static const sqlite3_io_methods sqlite3AFPLockingUnixIoMethod = { + 1, /* iVersion */ + unixClose, + unixRead, + unixWrite, + unixTruncate, + unixSync, + unixFileSize, + afpUnixLock, + afpUnixUnlock, + afpUnixCheckReservedLock, + unixBreakLock, + unixLockState, + unixSectorSize, + unixDeviceCharacteristics +}; + +/* +** This vector defines all the methods that can operate on an sqlite3_file +** for unix with flock() style file locking. +*/ +static const sqlite3_io_methods sqlite3FlockLockingUnixIoMethod = { + 1, /* iVersion */ + flockUnixClose, + unixRead, + unixWrite, + unixTruncate, + unixSync, + unixFileSize, + flockUnixLock, + flockUnixUnlock, + flockUnixCheckReservedLock, + unixBreakLock, + unixLockState, + unixSectorSize, + unixDeviceCharacteristics +}; + +/* +** This vector defines all the methods that can operate on an sqlite3_file +** for unix with dotlock style file locking. +*/ +static const sqlite3_io_methods sqlite3DotlockLockingUnixIoMethod = { + 1, /* iVersion */ + dotlockUnixClose, + unixRead, + unixWrite, + unixTruncate, + unixSync, + unixFileSize, + dotlockUnixLock, + dotlockUnixUnlock, + dotlockUnixCheckReservedLock, + unixBreakLock, + unixLockState, + unixSectorSize, + unixDeviceCharacteristics +}; + +/* +** This vector defines all the methods that can operate on an sqlite3_file +** for unix with dotlock style file locking. +*/ +static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = { + 1, /* iVersion */ + nolockUnixClose, unixRead, unixWrite, - unixSeek, unixTruncate, unixSync, - unixSetFullSync, - unixFileHandle, unixFileSize, nolockUnixLock, nolockUnixUnlock, - unixLockState, nolockUnixCheckReservedLock, + unixBreakLock, + unixLockState, unixSectorSize, + unixDeviceCharacteristics }; #endif /* SQLITE_ENABLE_LOCKING_STYLE */ @@ -2409,27 +2194,26 @@ static const IoMethod sqlite3NolockLockingUnixIoMethod = { */ #ifdef SQLITE_ENABLE_LOCKING_STYLE /* - ** When locking extensions are enabled, the filepath and locking style - ** are needed to determine the unixFile pMethod to use for locking operations. - ** The locking-style specific lockingContext data structure is created - ** and assigned here also. - */ -static int allocateUnixFile( +** When locking extensions are enabled, the filepath and locking style +** are needed to determine the unixFile pMethod to use for locking operations. +** The locking-style specific lockingContext data structure is created +** and assigned here also. +*/ +static int fillInUnixFile( int h, /* Open file descriptor of file being opened */ - OsFile **pId, /* Write completed initialization here */ + int dirfd, /* Directory file descriptor */ + sqlite3_file *pId, /* Write completed initialization here */ const char *zFilename, /* Name of the file being opened */ - int delFlag /* Delete-on-or-before-close flag */ ){ sqlite3LockingStyle lockingStyle; - unixFile *pNew; - unixFile f; + unixFile *pNew = (unixFile *)pId; int rc; - memset(&f, 0, sizeof(f)); + memset(pNew, 0, sizeof(unixFile)); lockingStyle = sqlite3DetectLockingStyle(zFilename, h); if ( lockingStyle == posixLockingStyle ) { enterMutex(); - rc = findLockInfo(h, &f.pLock, &f.pOpen); + rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen); leaveMutex(); if( rc ){ close(h); @@ -2438,26 +2222,21 @@ static int allocateUnixFile( } } else { /* pLock and pOpen are only used for posix advisory locking */ - f.pLock = NULL; - f.pOpen = NULL; + pNew->pLock = NULL; + pNew->pOpen = NULL; } - if( delFlag ){ - unlink(zFilename); - } - f.dirfd = -1; - f.h = h; - SET_THREADID(&f); + pNew->dirfd = -1; + pNew->h = h; + SET_THREADID(pNew); pNew = sqlite3_malloc( sizeof(unixFile) ); if( pNew==0 ){ close(h); enterMutex(); - releaseLockInfo(f.pLock); - releaseOpenCnt(f.pOpen); + releaseLockInfo(pNew->pLock); + releaseOpenCnt(pNew->pOpen); leaveMutex(); - *pId = 0; return SQLITE_NOMEM; }else{ - *pNew = f; switch(lockingStyle) { case afpLockingStyle: { /* afp locking uses the file path so it needs to be included in @@ -2502,7 +2281,6 @@ static int allocateUnixFile( default: pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; } - *pId = (OsFile*)pNew; OpenCounter(+1); return SQLITE_OK; } @@ -2547,6 +2325,16 @@ static int fillInUnixFile( ** with other miscellanous aspects of the operating system interface ****************************************************************************/ +/* +** Open a file descriptor to the directory containing file zFilename. +** If successful, *pFd is set to the opened file descriptor and +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined +** value. +** +** If SQLITE_OK is returned, the caller is responsible for closing +** the file descriptor *pFd using close(). +*/ static int openDirectory(const char *zFilename, int *pFd){ char *zDirname; int ii; @@ -2575,6 +2363,8 @@ static int openDirectory(const char *zFilename, int *pFd){ } /* +** Open the file zPath. +** ** Previously, the SQLite OS layer used three functions in place of this ** one: **