]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Update the locking-style code in os_unix.c. The updates are as yet untested. (CVS...
authordanielk1977 <danielk1977@noemail.net>
Mon, 20 Aug 2007 06:44:22 +0000 (06:44 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 20 Aug 2007 06:44:22 +0000 (06:44 +0000)
FossilOrigin-Name: 41f2175b1ed7eccf271b687ee5c3ea262a0cd096

manifest
manifest.uuid
src/os_unix.c

index 0640fb4c1f69b8adbf32069abd195444a0e256b1..013fe39644fd3e1fc3db56072dbce5606dd99682 100644 (file)
--- 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
index 31b1e741287ffd6301d74cbb7ed870d1c03bf7c1..bfaf77d55e08148a8571e8c1d3e346e9f038037a 100644 (file)
@@ -1 +1 @@
-cb24cda179c2b526c5ac48be75e372d2b9db808c
\ No newline at end of file
+41f2175b1ed7eccf271b687ee5c3ea262a0cd096
\ No newline at end of file
index 15bf9d221486863490637344ca1cbaa30ddd161e..f1575562ed6620aa71f06a1dfc9a5109b7073eb3 100644 (file)
@@ -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 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 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 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 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 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 OsFile
- ** for unix with dotlock style file locking.
- */
-static const IoMethod sqlite3NolockLockingUnixIoMethod = {
+** 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,
-  unixOpenDirectory,
   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;
-  }
-  if( delFlag ){
-    unlink(zFilename);
+    pNew->pLock = NULL;
+    pNew->pOpen = NULL;
   }
-  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:
 **