mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Ensure that when a file is extended using FCNTL_SIZE_HINT the last page is allocated on disk, even if the file will only use part of it.
FossilOrigin-Name: c7f84717d61197afa9e0ac607c4b349361e6e2b7
This commit is contained in:
@@ -3709,24 +3709,27 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
||||
}while( err==EINTR );
|
||||
if( err ) return SQLITE_IOERR_WRITE;
|
||||
#else
|
||||
/* If the OS does not have posix_fallocate(), fake it. First use
|
||||
** ftruncate() to set the file size, then write a single byte to
|
||||
** the last byte in each block within the extended region. This
|
||||
** is the same technique used by glibc to implement posix_fallocate()
|
||||
** on systems that do not have a real fallocate() system call.
|
||||
/* If the OS does not have posix_fallocate(), fake it. Write a
|
||||
** single byte to the last byte in each block that falls entirely
|
||||
** within the extended region. Then, if required, a single byte
|
||||
** at offset (nSize-1), to set the size of the file correctly.
|
||||
** This is a similar technique to that used by glibc on systems
|
||||
** that do not have a real fallocate() call.
|
||||
*/
|
||||
int nBlk = buf.st_blksize; /* File-system block size */
|
||||
i64 iWrite; /* Next offset to write to */
|
||||
|
||||
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
|
||||
while( iWrite<nSize ){
|
||||
assert( iWrite>=buf.st_size );
|
||||
assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
|
||||
assert( ((iWrite+1)%nBlk)==0 );
|
||||
for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
|
||||
int nWrite = seekAndWrite(pFile, iWrite, "", 1);
|
||||
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
|
||||
iWrite += nBlk;
|
||||
}
|
||||
if( robust_ftruncate(pFile->h, nSize) ){
|
||||
pFile->lastErrno = errno;
|
||||
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
|
||||
if( nSize%nBlk ){
|
||||
int nWrite = seekAndWrite(pFile, nSize-1, "", 1);
|
||||
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user