]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental change to os_unix.c to delay creating a database file until it is first...
authordan <dan@noemail.net>
Mon, 10 Feb 2014 19:37:03 +0000 (19:37 +0000)
committerdan <dan@noemail.net>
Mon, 10 Feb 2014 19:37:03 +0000 (19:37 +0000)
FossilOrigin-Name: 538f7b25e436682adba10a158f082de24782cf00

manifest
manifest.uuid
src/os_unix.c
src/test2.c
test/permutations.test

index e73dfc19e13eb4ae8e534f33f18dbf9f74deee13..1b2f1a34d933eda171ac1b3ba0b95fbfb6f070a2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enable\sconstant\sexpression\sfactoring\seven\sif\sno\stables\sare\sread\sand\sno\ntransaction\sis\sstarted.
-D 2014-02-08T04:24:37.181
+C Experimental\schange\sto\sos_unix.c\sto\sdelay\screating\sa\sdatabase\sfile\suntil\sit\sis\sfirst\swritten.
+D 2014-02-10T19:37:03.413
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -205,7 +205,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
 F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
-F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5
+F src/os_unix.c dcb7dd4fb2ef823b534383bb7e58efdf8cb7d582
 F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b
 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
@@ -230,7 +230,7 @@ F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c 649d373f2a3cfbefe8e935a8dec83686616f9a85
 F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
-F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
+F src/test2.c 0f8bd858c127fd5236dd965d534622422fbe0b2f
 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
 F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
 F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
@@ -737,7 +737,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
-F test/permutations.test 40add071ba71aefe1c04f5845308cf46f7de8d04
+F test/permutations.test 64771d6c1cbe270acb788dfdc32ede157a627583
 F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 192dea97316144f15f6dd0eabff08a0bf9ef203e
-R e90c019788474c8101c0d70d2228b12b
-U drh
-Z 46adb7aa7b0c0d2f1d0d873b94d6c7bb
+P a45b87713c0afca2be2ace9500513620a024c0a2
+R 116d1a6917169d2dbbd8194f87400b30
+T *branch * deferred-open
+T *sym-deferred-open *
+T -sym-trunk *
+U dan
+Z 79711705a6aa2396617bcc4018494171
index c2f346156d98f602f7db2c2733942735469ef257..0ecd57ff12a4bb58598a1c6b98f63770e007d051 100644 (file)
@@ -1 +1 @@
-a45b87713c0afca2be2ace9500513620a024c0a2
\ No newline at end of file
+538f7b25e436682adba10a158f082de24782cf00
\ No newline at end of file
index deb9e51d076fccf8364a908134ad86dcd9818d9d..b133f9878fbc92af6158855c0c7e1a86ff838f29 100644 (file)
@@ -203,9 +203,7 @@ struct unixFile {
   int sectorSize;                     /* Device sector size */
   int deviceCharacteristics;          /* Precomputed device characteristics */
 #endif
-#if SQLITE_ENABLE_LOCKING_STYLE
   int openFlags;                      /* The flags specified at open() */
-#endif
 #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   unsigned fsFlags;                   /* cached details from statfs() */
 #endif
@@ -255,7 +253,8 @@ static int randomnessPid = 0;
 #define UNIXFILE_DELETE      0x20     /* Delete on close */
 #define UNIXFILE_URI         0x40     /* Filename might have query parameters */
 #define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
-#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() warnings have been issued */
+#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() has issued warnings */
+#define UNIXFILE_DEFERRED  0x0200     /* File has not yet been opened */
 
 /*
 ** Include code that is common to all os_*.c files
@@ -1357,9 +1356,14 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
 
+  assert( pFile );
   SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
 
-  assert( pFile );
+  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+    *pResOut = 0;
+    return SQLITE_OK;
+  }
+
   unixEnterMutex(); /* Because pFile->pInode is shared across threads */
 
   /* Check if a thread in this process holds such a lock */
@@ -1439,6 +1443,8 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
   return rc;
 }
 
+static int unixOpen(sqlite3_vfs*, const char*, sqlite3_file*, int, int *);
+
 /*
 ** Lock the file with the lock specified by parameter eFileLock - one
 ** of the following:
@@ -1523,6 +1529,27 @@ static int unixLock(sqlite3_file *id, int eFileLock){
     return SQLITE_OK;
   }
 
+  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+    int eOrigLock = pFile->eFileLock;
+    if( eFileLock==SHARED_LOCK ){
+      int statrc;
+      struct stat sBuf;
+      memset(&sBuf, 0, sizeof(sBuf));
+      statrc = osStat(pFile->zPath, &sBuf);
+      if( statrc && errno==ENOENT ){
+        pFile->eFileLock = SHARED_LOCK;
+        return SQLITE_OK;
+      }
+    }
+
+    rc = unixOpen(pFile->pVfs, pFile->zPath, id, pFile->openFlags, 0);
+    if( rc==SQLITE_OK && eOrigLock ){
+      rc = unixLock(id, eOrigLock);
+    }
+    if( rc!=SQLITE_OK ) return rc;
+  }
+  assert( (pFile->ctrlFlags & UNIXFILE_DEFERRED)==0 );
+
   /* Make sure the locking sequence is correct.
   **  (1) We never move from unlocked to anything higher than shared lock.
   **  (2) SQLite never explicitly requests a pendig lock.
@@ -1726,6 +1753,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
     return SQLITE_OK;
   }
   unixEnterMutex();
+  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ) goto end_unlock;
   pInode = pFile->pInode;
   assert( pInode->nShared!=0 );
   if( pFile->eFileLock>SHARED_LOCK ){
@@ -1933,18 +1961,22 @@ static int unixClose(sqlite3_file *id){
   unixEnterMutex();
 
   /* unixFile.pInode is always valid here. Otherwise, a different close
-  ** routine (e.g. nolockClose()) would be called instead.
-  */
-  assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
-  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
-    /* If there are outstanding locks, do not actually close the file just
-    ** yet because that would clear those locks.  Instead, add the file
-    ** descriptor to pInode->pUnused list.  It will be automatically closed 
-    ** when the last lock is cleared.
-    */
-    setPendingFd(pFile);
+  ** routine (e.g. nolockClose()) would be called instead.  */
+  assert( pFile->pInode==0 
+       || pFile->pInode->nLock>0 
+       || pFile->pInode->bProcessLock==0 
+  );
+  if( pFile->pInode ){
+    if( pFile->pInode->nLock ){
+      /* If there are outstanding locks, do not actually close the file just
+      ** yet because that would clear those locks.  Instead, add the file
+      ** descriptor to pInode->pUnused list.  It will be automatically closed 
+      ** when the last lock is cleared.
+      */
+      setPendingFd(pFile);
+    }
+    releaseInodeInfo(pFile);
   }
-  releaseInodeInfo(pFile);
   rc = closeUnixFile(id);
   unixLeaveMutex();
   return rc;
@@ -3173,6 +3205,23 @@ static int unixRead(
   );
 #endif
 
+  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+    int rc;
+    struct stat sBuf;
+    memset(&sBuf, 0, sizeof(sBuf));
+    rc = osStat(pFile->zPath, &sBuf);
+    if( rc!=0 ){
+      memset(pBuf, 0, amt);
+      rc = (errno==ENOENT ? SQLITE_IOERR_SHORT_READ : SQLITE_IOERR_FSTAT);
+    }else{
+      rc = unixOpen(pFile->pVfs, pFile->zPath, id, pFile->openFlags, 0);
+    }
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+  }
+  assert( (pFile->ctrlFlags & UNIXFILE_DEFERRED)==0 );
+
 #if SQLITE_MAX_MMAP_SIZE>0
   /* Deal with as much of this read request as possible by transfering
   ** data from the memory mapping using memcpy().  */
@@ -3625,10 +3674,19 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
 ** Determine the current size of a file in bytes
 */
 static int unixFileSize(sqlite3_file *id, i64 *pSize){
+  unixFile *pFile = (unixFile*)id;
   int rc;
   struct stat buf;
   assert( id );
-  rc = osFstat(((unixFile*)id)->h, &buf);
+  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+    rc = osStat(pFile->zPath, &buf);
+    if( rc && errno==ENOENT ){
+      rc = 0;
+      buf.st_size = 0;
+    }
+  }else{
+    rc = osFstat(pFile->h, &buf);
+  }
   SimulateIOError( rc=1 );
   if( rc!=0 ){
     ((unixFile*)id)->lastErrno = errno;
@@ -3644,7 +3702,6 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
   */
   if( *pSize==1 ) *pSize = 0;
 
-
   return SQLITE_OK;
 }
 
@@ -5176,7 +5233,7 @@ static int fillInUnixFile(
   pNew->h = h;
   pNew->pVfs = pVfs;
   pNew->zPath = zFilename;
-  pNew->ctrlFlags = (u8)ctrlFlags;
+  pNew->ctrlFlags = (unsigned short)ctrlFlags;
 #if SQLITE_MAX_MMAP_SIZE>0
   pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
 #endif
@@ -5822,6 +5879,37 @@ open_finished:
   return rc;
 }
 
+static int unixOpenDeferred(
+  sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
+  const char *zPath,           /* Pathname of file to be opened */
+  sqlite3_file *pFile,         /* The file descriptor to be filled in */
+  int flags,                   /* Input flags to control the opening */
+  int *pOutFlags               /* Output flags returned to SQLite core */
+){
+  const int mask1 = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE
+                  | SQLITE_OPEN_CREATE;
+  const int mask2 = SQLITE_OPEN_READONLY  | SQLITE_OPEN_DELETEONCLOSE
+                  | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_AUTOPROXY;
+  int rc = SQLITE_OK;          /* Return code */
+
+  /* If all the flags in mask1 are set, and all the flags in mask2 are
+  ** clear, then this will be a deferred open.  */
+  if( zPath && (flags & (mask1 | mask2))==mask1 ){
+    unixFile *p = (unixFile*)pFile;
+    memset(p, 0, sizeof(unixFile));
+
+    p->pMethod = (**(finder_type*)pVfs->pAppData)(0, 0);
+    p->pVfs = pVfs;
+    p->h = -1;
+    p->ctrlFlags = UNIXFILE_DEFERRED;
+    p->openFlags = flags;
+    p->zPath = zPath;
+    if( pOutFlags ) *pOutFlags = flags;
+  }else{
+    rc = unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
+  }
+  return rc;
+}
 
 /*
 ** Delete the file at zPath. If the dirSync argument is true, fsync()
@@ -7376,7 +7464,7 @@ int sqlite3_os_init(void){
     0,                    /* pNext */                       \
     VFSNAME,              /* zName */                       \
     (void*)&FINDER,       /* pAppData */                    \
-    unixOpen,             /* xOpen */                       \
+    unixOpenDeferred,     /* xOpen */                       \
     unixDelete,           /* xDelete */                     \
     unixAccess,           /* xAccess */                     \
     unixFullPathname,     /* xFullPathname */               \
index d130e9d01b7024a5ec6d730592ee4d1fb02cfdb4..a68293280e5b25fb3a72f75f3de370a16c459f2d 100644 (file)
@@ -534,7 +534,10 @@ static int fake_big_file(
   }
   offset = n;
   offset *= 1024*1024;
+  sqlite3OsLock(fd, SHARED_LOCK);
+  sqlite3OsLock(fd, EXCLUSIVE_LOCK);
   rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
+  sqlite3OsUnlock(fd, NO_LOCK);
   sqlite3OsCloseFree(fd);
   sqlite3_free(zFile);
   if( rc ){
index 7f1485f8315fc1b13f6414322a155b9bc99f5fda..ad087c94763dfba6aeba2f83cf19cdf922c217a6 100644 (file)
@@ -135,7 +135,8 @@ test_suite "veryquick" -prefix "" -description {
   This test suite is the same as the "quick" tests, except that some files
   that test malloc and IO errors are omitted.
 } -files [
-  test_set $allquicktests -exclude *malloc* *ioerr* *fault*
+  test_set $allquicktests -exclude *malloc* *ioerr* *fault* \
+    *multiplex* *quota* walbak.test
 ]
 
 test_suite "mmap" -prefix "mm-" -description {