/ Check-in [95d0c58d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a bug causing the POWERSAFE_OVERWRITE device-characteristic flag to be set incorrectly if file opening is deferred.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | deferred-open
Files: files | file ages | folders
SHA1: 95d0c58d2791d81b432e7d263f3fc2f26858d395
User & Date: dan 2014-02-10 21:09:39
Context
2014-02-11
05:26
Merge latest trunk changes. check-in: 1f2e1b0c user: dan tags: deferred-open
2014-02-10
21:09
Fix a bug causing the POWERSAFE_OVERWRITE device-characteristic flag to be set incorrectly if file opening is deferred. check-in: 95d0c58d user: dan tags: deferred-open
19:37
Experimental change to os_unix.c to delay creating a database file until it is first written. check-in: 538f7b25 user: dan tags: deferred-open
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  1355   1355     int rc = SQLITE_OK;
  1356   1356     int reserved = 0;
  1357   1357     unixFile *pFile = (unixFile*)id;
  1358   1358   
  1359   1359     assert( pFile );
  1360   1360     SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
  1361   1361   
  1362         -  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
         1362  +  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
  1363   1363       *pResOut = 0;
  1364   1364       return SQLITE_OK;
  1365   1365     }
  1366   1366   
  1367   1367     unixEnterMutex(); /* Because pFile->pInode is shared across threads */
  1368   1368   
  1369   1369     /* Check if a thread in this process holds such a lock */
................................................................................
  1525   1525     */
  1526   1526     if( pFile->eFileLock>=eFileLock ){
  1527   1527       OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
  1528   1528               azFileLock(eFileLock)));
  1529   1529       return SQLITE_OK;
  1530   1530     }
  1531   1531   
  1532         -  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
         1532  +  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
  1533   1533       int eOrigLock = pFile->eFileLock;
  1534   1534       if( eFileLock==SHARED_LOCK ){
  1535   1535         int statrc;
  1536   1536         struct stat sBuf;
  1537   1537         memset(&sBuf, 0, sizeof(sBuf));
  1538   1538         statrc = osStat(pFile->zPath, &sBuf);
  1539   1539         if( statrc && errno==ENOENT ){
................................................................................
  1749   1749         getpid()));
  1750   1750   
  1751   1751     assert( eFileLock<=SHARED_LOCK );
  1752   1752     if( pFile->eFileLock<=eFileLock ){
  1753   1753       return SQLITE_OK;
  1754   1754     }
  1755   1755     unixEnterMutex();
  1756         -  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ) goto end_unlock;
         1756  +  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ) goto end_unlock;
  1757   1757     pInode = pFile->pInode;
  1758   1758     assert( pInode->nShared!=0 );
  1759   1759     if( pFile->eFileLock>SHARED_LOCK ){
  1760   1760       assert( pInode->eFileLock==pFile->eFileLock );
  1761   1761   
  1762   1762   #ifdef SQLITE_DEBUG
  1763   1763       /* When reducing a lock such that other processes can start
................................................................................
  3201   3201   #if 0
  3202   3202     assert( pFile->pUnused==0
  3203   3203          || offset>=PENDING_BYTE+512
  3204   3204          || offset+amt<=PENDING_BYTE 
  3205   3205     );
  3206   3206   #endif
  3207   3207   
  3208         -  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
         3208  +  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
  3209   3209       int rc;
  3210   3210       struct stat sBuf;
  3211   3211       memset(&sBuf, 0, sizeof(sBuf));
  3212   3212       rc = osStat(pFile->zPath, &sBuf);
  3213   3213       if( rc!=0 ){
  3214   3214         memset(pBuf, 0, amt);
  3215   3215         rc = (errno==ENOENT ? SQLITE_IOERR_SHORT_READ : SQLITE_IOERR_FSTAT);
................................................................................
  3674   3674   ** Determine the current size of a file in bytes
  3675   3675   */
  3676   3676   static int unixFileSize(sqlite3_file *id, i64 *pSize){
  3677   3677     unixFile *pFile = (unixFile*)id;
  3678   3678     int rc;
  3679   3679     struct stat buf;
  3680   3680     assert( id );
  3681         -  if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
         3681  +  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
  3682   3682       rc = osStat(pFile->zPath, &buf);
  3683   3683       if( rc && errno==ENOENT ){
  3684   3684         rc = 0;
  3685   3685         buf.st_size = 0;
  3686   3686       }
  3687   3687     }else{
  3688   3688       rc = osFstat(pFile->h, &buf);
................................................................................
  5886   5886     int flags,                   /* Input flags to control the opening */
  5887   5887     int *pOutFlags               /* Output flags returned to SQLite core */
  5888   5888   ){
  5889   5889     const int mask1 = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE
  5890   5890                     | SQLITE_OPEN_CREATE;
  5891   5891     const int mask2 = SQLITE_OPEN_READONLY  | SQLITE_OPEN_DELETEONCLOSE
  5892   5892                     | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_AUTOPROXY;
  5893         -  int rc = SQLITE_OK;          /* Return code */
  5894   5893   
  5895   5894     /* If all the flags in mask1 are set, and all the flags in mask2 are
  5896         -  ** clear, then this will be a deferred open.  */
  5897         -  if( zPath && (flags & (mask1 | mask2))==mask1 ){
  5898         -    unixFile *p = (unixFile*)pFile;
  5899         -    memset(p, 0, sizeof(unixFile));
  5900         -
  5901         -    p->pMethod = (**(finder_type*)pVfs->pAppData)(0, 0);
  5902         -    p->pVfs = pVfs;
  5903         -    p->h = -1;
  5904         -    p->ctrlFlags = UNIXFILE_DEFERRED;
  5905         -    p->openFlags = flags;
  5906         -    p->zPath = zPath;
  5907         -    if( pOutFlags ) *pOutFlags = flags;
  5908         -  }else{
  5909         -    rc = unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
  5910         -  }
  5911         -  return rc;
         5895  +  ** clear, the file does not exist but the directory does and is
         5896  +  ** writable, then this is a deferred open.  */
         5897  +  if( 0 && zPath && (flags & (mask1 | mask2))==mask1 ){
         5898  +    int posixrc;
         5899  +    posixrc = osAccess(zPath, F_OK);
         5900  +    if( posixrc && errno==ENOENT ){
         5901  +      char zDirname[MAX_PATHNAME+1];
         5902  +      int i;
         5903  +      for(i=(int)strlen(zPath); i>1 && zPath[i]!='/'; i--);
         5904  +      memcpy(zDirname, zPath, i);
         5905  +      zDirname[i] = '\0';
         5906  +      posixrc = osAccess(zDirname, W_OK);
         5907  +      if( posixrc==0 ){
         5908  +        unixFile *p = (unixFile*)pFile;
         5909  +        memset(p, 0, sizeof(unixFile));
         5910  +        p->pMethod = (**(finder_type*)pVfs->pAppData)(0, 0);
         5911  +        p->pVfs = pVfs;
         5912  +        p->h = -1;
         5913  +        p->ctrlFlags = UNIXFILE_DEFERRED;
         5914  +        if( sqlite3_uri_boolean(((flags & UNIXFILE_URI) ? zPath : 0),
         5915  +                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
         5916  +          p->ctrlFlags |= UNIXFILE_PSOW;
         5917  +        }
         5918  +        p->openFlags = flags;
         5919  +        p->zPath = zPath;
         5920  +        if( pOutFlags ) *pOutFlags = flags;
         5921  +        return SQLITE_OK;
         5922  +      }
         5923  +    }
         5924  +  }
         5925  +  return unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
  5912   5926   }
  5913   5927   
  5914   5928   /*
  5915   5929   ** Delete the file at zPath. If the dirSync argument is true, fsync()
  5916   5930   ** the directory after deleting the file.
  5917   5931   */
  5918   5932   static int unixDelete(