mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Enhance the unix VFS so that it keeps track of the size of unlinked files
internally and thus avoids the need to call fstat() on those files, since fstat() does not work reliably on unlinked files on some implementations of FuseFS. FossilOrigin-Name: c41df393c6afbfbfdc4d1b885024e083c6f6de1f
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Modify\sthe\s%nonassoc\sdirective\sin\slemon\sso\sthat\sit\sgenerates\sa\srun-time\nerror\srather\sthan\sa\sparsing\sconflict.\s\sThis\schanges\sis\sdue\sto\sa\sbug\sreport\non\sthe\smailing\slist.\s\sSQLite\sdoes\snot\suse\sthe\s%nonassoc\sdirective\sin\sits\ngrammar\sso\sthis\schange\sdoes\snot\saffect\sSQLite.
|
C Enhance\sthe\sunix\sVFS\sso\sthat\sit\skeeps\strack\sof\sthe\ssize\sof\sunlinked\sfiles\ninternally\sand\sthus\savoids\sthe\sneed\sto\scall\sfstat()\son\sthose\sfiles,\ssince\nfstat()\sdoes\snot\swork\sreliably\son\sunlinked\sfiles\son\ssome\simplementations\sof\nFuseFS.
|
||||||
D 2014-06-09T13:11:40.535
|
D 2014-06-09T20:06:01.535
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
|
F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -205,7 +205,7 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
|
|||||||
F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e
|
F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e
|
||||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||||
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
|
F src/os_unix.c e8c5f23bb6e9123b524cd0a87dd1e9263a4dd3be
|
||||||
F src/os_win.c 8dbf6c11780fe2eb96c1f289e664d0c7b2911d37
|
F src/os_win.c 8dbf6c11780fe2eb96c1f289e664d0c7b2911d37
|
||||||
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
|
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
|
||||||
F src/pager.c f6bb1fa6cdf2062f2d8aec3e64db302bca519ab8
|
F src/pager.c f6bb1fa6cdf2062f2d8aec3e64db302bca519ab8
|
||||||
@@ -1174,7 +1174,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 813469d98519b609669a004b7b604af78ef40c02
|
P 1925f3a0a2caa709569df015a8e0d26412f1a9ff
|
||||||
R 17b9b9add2b8e980cb35f959c7029199
|
R ce653ef517f5e803383e83307c89c5db
|
||||||
|
T *branch * omit-fstat-after-unlink
|
||||||
|
T *sym-omit-fstat-after-unlink *
|
||||||
|
T -sym-trunk *
|
||||||
U drh
|
U drh
|
||||||
Z c031771471155f639666c4eafbc642f6
|
Z c015ab13afaac99134c0355e5c3248ba
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1925f3a0a2caa709569df015a8e0d26412f1a9ff
|
c41df393c6afbfbfdc4d1b885024e083c6f6de1f
|
||||||
@@ -191,6 +191,7 @@ struct unixFile {
|
|||||||
UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
|
UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
|
||||||
const char *zPath; /* Name of the file */
|
const char *zPath; /* Name of the file */
|
||||||
unixShm *pShm; /* Shared memory segment information */
|
unixShm *pShm; /* Shared memory segment information */
|
||||||
|
sqlite3_int64 szFile; /* File size for UNIXFILE_DELETE files */
|
||||||
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
|
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
|
||||||
#if SQLITE_MAX_MMAP_SIZE>0
|
#if SQLITE_MAX_MMAP_SIZE>0
|
||||||
int nFetchOut; /* Number of outstanding xFetch refs */
|
int nFetchOut; /* Number of outstanding xFetch refs */
|
||||||
@@ -1321,9 +1322,11 @@ static int fileHasMoved(unixFile *pFile){
|
|||||||
static void verifyDbFile(unixFile *pFile){
|
static void verifyDbFile(unixFile *pFile){
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
int rc;
|
int rc;
|
||||||
if( pFile->ctrlFlags & UNIXFILE_WARNED ){
|
if( pFile->ctrlFlags & (UNIXFILE_WARNED|UNIXFILE_DELETE) ){
|
||||||
/* One or more of the following warnings have already been issued. Do not
|
/* UNIXFILE_WARNED means that one or more of the following warnings have
|
||||||
** repeat them so as not to clutter the error log */
|
** already been issued. Do not* repeat them so as not to clutter the error
|
||||||
|
** log. Do not investigate unlinked files since fstat() does not always
|
||||||
|
** work following an unlink(). */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rc = osFstat(pFile->h, &buf);
|
rc = osFstat(pFile->h, &buf);
|
||||||
@@ -1332,7 +1335,7 @@ static void verifyDbFile(unixFile *pFile){
|
|||||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
|
if( buf.st_nlink==0 ){
|
||||||
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
|
||||||
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
pFile->ctrlFlags |= UNIXFILE_WARNED;
|
||||||
return;
|
return;
|
||||||
@@ -3281,6 +3284,10 @@ static int unixWrite(
|
|||||||
assert( id );
|
assert( id );
|
||||||
assert( amt>0 );
|
assert( amt>0 );
|
||||||
|
|
||||||
|
/* Update the internally tracked file size. The internal file size is only
|
||||||
|
** accurate for unlinked files */
|
||||||
|
if( offset+amt>pFile->szFile ) pFile->szFile = offset+amt;
|
||||||
|
|
||||||
/* If this is a database file (not a journal, master-journal or temp
|
/* If this is a database file (not a journal, master-journal or temp
|
||||||
** file), the bytes in the locking range should never be read or written. */
|
** file), the bytes in the locking range should never be read or written. */
|
||||||
#if 0
|
#if 0
|
||||||
@@ -3621,6 +3628,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pFile->szFile = nByte;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3630,12 +3638,27 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
|
|||||||
*/
|
*/
|
||||||
static int unixFileSize(sqlite3_file *id, i64 *pSize){
|
static int unixFileSize(sqlite3_file *id, i64 *pSize){
|
||||||
int rc;
|
int rc;
|
||||||
|
unixFile *pFile = (unixFile*)id;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
assert( id );
|
assert( pFile );
|
||||||
rc = osFstat(((unixFile*)id)->h, &buf);
|
|
||||||
|
/* For files that have been unlinked, simply return the szFile which we keep
|
||||||
|
** track of internally. There is no need to fstat() as SQLite has exclusive
|
||||||
|
** access to the file and no other process can modify the file and thus change
|
||||||
|
** the file size without our knowing it. We do this because fstat() will
|
||||||
|
** fail on unlinked files on some (broken) unix filesystems.
|
||||||
|
*/
|
||||||
|
if( pFile->ctrlFlags & UNIXFILE_DELETE ){
|
||||||
|
*pSize = pFile->szFile;
|
||||||
|
/* The following assert() confirms that the internal filesize is correct */
|
||||||
|
assert( osFstat(pFile->h, &buf)!=0 || buf.st_size==pFile->szFile );
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = osFstat(pFile->h, &buf);
|
||||||
SimulateIOError( rc=1 );
|
SimulateIOError( rc=1 );
|
||||||
if( rc!=0 ){
|
if( rc!=0 ){
|
||||||
((unixFile*)id)->lastErrno = errno;
|
pFile->lastErrno = errno;
|
||||||
return SQLITE_IOERR_FSTAT;
|
return SQLITE_IOERR_FSTAT;
|
||||||
}
|
}
|
||||||
*pSize = buf.st_size;
|
*pSize = buf.st_size;
|
||||||
@@ -3671,6 +3694,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
|||||||
i64 nSize; /* Required file size */
|
i64 nSize; /* Required file size */
|
||||||
struct stat buf; /* Used to hold return values of fstat() */
|
struct stat buf; /* Used to hold return values of fstat() */
|
||||||
|
|
||||||
|
if( pFile->ctrlFlags & UNIXFILE_DELETE ) return SQLITE_OK;
|
||||||
if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
|
if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
|
||||||
|
|
||||||
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
|
nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
|
||||||
@@ -4219,6 +4243,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
|||||||
if( p==0 ) return SQLITE_NOMEM;
|
if( p==0 ) return SQLITE_NOMEM;
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
assert( pDbFd->pShm==0 );
|
assert( pDbFd->pShm==0 );
|
||||||
|
assert( (pDbFd->ctrlFlags & UNIXFILE_DELETE)==0 );
|
||||||
|
|
||||||
/* Check to see if a unixShmNode object already exists. Reuse an existing
|
/* Check to see if a unixShmNode object already exists. Reuse an existing
|
||||||
** one if present. Create a new one if necessary.
|
** one if present. Create a new one if necessary.
|
||||||
@@ -4765,6 +4790,7 @@ static void unixRemapfile(
|
|||||||
}
|
}
|
||||||
pFd->pMapRegion = (void *)pNew;
|
pFd->pMapRegion = (void *)pNew;
|
||||||
pFd->mmapSize = pFd->mmapSizeActual = nNew;
|
pFd->mmapSize = pFd->mmapSizeActual = nNew;
|
||||||
|
if( nNew>pFd->szFile ) pFd->szFile = nNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4791,12 +4817,10 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
|
|||||||
if( pFd->nFetchOut>0 ) return SQLITE_OK;
|
if( pFd->nFetchOut>0 ) return SQLITE_OK;
|
||||||
|
|
||||||
if( nMap<0 ){
|
if( nMap<0 ){
|
||||||
struct stat statbuf; /* Low-level file information */
|
rc = unixFileSize((sqlite3_file*)pFd, &nMap);
|
||||||
rc = osFstat(pFd->h, &statbuf);
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return SQLITE_IOERR_FSTAT;
|
return SQLITE_IOERR_FSTAT;
|
||||||
}
|
}
|
||||||
nMap = statbuf.st_size;
|
|
||||||
}
|
}
|
||||||
if( nMap>pFd->mmapSizeMax ){
|
if( nMap>pFd->mmapSizeMax ){
|
||||||
nMap = pFd->mmapSizeMax;
|
nMap = pFd->mmapSizeMax;
|
||||||
@@ -5770,6 +5794,7 @@ static int unixOpen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( isDelete ){
|
if( isDelete ){
|
||||||
|
p->szFile = 0;
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
zPath = zName;
|
zPath = zName;
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user