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 |
Timelines: | family | ancestors | descendants | both | deferred-open |
Files: | files | file ages | folders |
SHA1: |
95d0c58d2791d81b432e7d263f3fc2f2 |
User & Date: | dan 2014-02-10 21:09:39.090 |
Context
2014-02-11
| ||
05:26 | Merge latest trunk changes. (check-in: 1f2e1b0c64 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: 95d0c58d27 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: 538f7b25e4 user: dan tags: deferred-open) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
1355 1356 1357 1358 1359 1360 1361 | int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; assert( pFile ); SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); | | | 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 | int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; assert( pFile ); SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); 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 */ |
︙ | ︙ | |||
1525 1526 1527 1528 1529 1530 1531 | */ if( pFile->eFileLock>=eFileLock ){ OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, azFileLock(eFileLock))); return SQLITE_OK; } | | | 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 | */ if( pFile->eFileLock>=eFileLock ){ OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, azFileLock(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 ){ |
︙ | ︙ | |||
1749 1750 1751 1752 1753 1754 1755 | getpid())); assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } unixEnterMutex(); | | | 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 | getpid())); assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } unixEnterMutex(); if( pFile->ctrlFlags & UNIXFILE_DEFERRED ) goto end_unlock; pInode = pFile->pInode; assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); #ifdef SQLITE_DEBUG /* When reducing a lock such that other processes can start |
︙ | ︙ | |||
3201 3202 3203 3204 3205 3206 3207 | #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #endif | | | 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 | #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #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); |
︙ | ︙ | |||
3674 3675 3676 3677 3678 3679 3680 | ** 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 ); | | | 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 | ** 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 ); 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); |
︙ | ︙ | |||
5886 5887 5888 5889 5890 5891 5892 | 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; | < > | | > > > > > > > > > > < > > > > | < > > | | 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 | 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; /* If all the flags in mask1 are set, and all the flags in mask2 are ** clear, the file does not exist but the directory does and is ** writable, then this is a deferred open. */ if( 0 && zPath && (flags & (mask1 | mask2))==mask1 ){ int posixrc; posixrc = osAccess(zPath, F_OK); if( posixrc && errno==ENOENT ){ char zDirname[MAX_PATHNAME+1]; int i; for(i=(int)strlen(zPath); i>1 && zPath[i]!='/'; i--); memcpy(zDirname, zPath, i); zDirname[i] = '\0'; posixrc = osAccess(zDirname, W_OK); if( posixrc==0 ){ 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; if( sqlite3_uri_boolean(((flags & UNIXFILE_URI) ? zPath : 0), "psow", SQLITE_POWERSAFE_OVERWRITE) ){ p->ctrlFlags |= UNIXFILE_PSOW; } p->openFlags = flags; p->zPath = zPath; if( pOutFlags ) *pOutFlags = flags; return SQLITE_OK; } } } return unixOpen(pVfs, zPath, pFile, flags, pOutFlags); } /* ** Delete the file at zPath. If the dirSync argument is true, fsync() ** the directory after deleting the file. */ static int unixDelete( |
︙ | ︙ |