8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 08:43:03 +01:00

Fixed CORE-2422: Server doesn't switch between multiple entries configured in TempDirectories when some of them is out of free space.

Moved the common code to File.h.
This commit is contained in:
dimitr 2009-08-21 08:28:08 +00:00
parent 12a4f93f23
commit 21971f03a0
5 changed files with 54 additions and 38 deletions

View File

@ -23,6 +23,8 @@
#ifndef CLASSES_FILE_H
#define CLASSES_FILE_H
#include "../common/classes/array.h"
#if !defined(SOLARIS) && !defined(AIX)
typedef FB_UINT64 offset_t;
#endif
@ -42,6 +44,24 @@ public:
virtual offset_t getSize() const = 0;
};
class ZeroBuffer
{
static const size_t DEFAULT_SIZE = 1024 * 256;
public:
explicit ZeroBuffer(MemoryPool& p, size_t size = DEFAULT_SIZE)
: buffer(p)
{
memset(buffer.getBuffer(size), 0, size);
}
const char* getBuffer() const { return buffer.begin(); }
size_t getSize() const { return buffer.getCount(); }
private:
Firebird::Array<char> buffer;
};
} // namespace
#endif // CLASSES_FILE_H

View File

@ -46,6 +46,7 @@
#include "../jrd/gdsassert.h"
#include "../jrd/os/path_utils.h"
#include "../common/classes/init.h"
#include "../common/classes/TempFile.h"
@ -67,6 +68,10 @@ static const char* const NAME_PATTERN = "XXXXXX";
static const char* const NAME_LETTERS = "abcdefghijklmnopqrstuvwxyz0123456789";
static const size_t MAX_TRIES = 256;
// we need a class here only to return memory on shutdown and avoid
// false memory leak reports
static Firebird::InitInstance<ZeroBuffer> zeros;
//
// TempFile::getTempPath
//
@ -115,9 +120,8 @@ PathName TempFile::create(const PathName& prefix, const PathName& directory)
TempFile file(*getDefaultMemoryPool(), prefix, directory, false);
filename = file.getName();
}
catch (const Exception&) {
// do nothing
}
catch (const Exception&)
{} // do nothing
return filename;
}
@ -171,7 +175,7 @@ void TempFile::init(const PathName& directory, const PathName& prefix)
}
if (handle == INVALID_HANDLE_VALUE)
{
system_call_failed::raise("CreateFile");
system_error::raise("CreateFile");
}
#else
filename += prefix;
@ -182,7 +186,7 @@ void TempFile::init(const PathName& directory, const PathName& prefix)
#else
if (!mktemp(filename.begin()))
{
system_call_failed::raise("mktemp");
system_error::raise("mktemp");
}
do {
@ -192,7 +196,7 @@ void TempFile::init(const PathName& directory, const PathName& prefix)
if (handle == -1)
{
system_call_failed::raise("open");
system_error::raise("open");
}
if (doUnlink)
@ -241,13 +245,13 @@ void TempFile::seek(const offset_t offset)
SetFilePointer(handle, (LONG) liOffset.LowPart, &liOffset.HighPart, FILE_BEGIN);
if (seek_result == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
system_call_failed::raise("SetFilePointer");
system_error::raise("SetFilePointer");
}
#else
const off_t seek_result = ::lseek(handle, (off_t) offset, SEEK_SET);
if (seek_result == (off_t) -1)
{
system_call_failed::raise("lseek");
system_error::raise("lseek");
}
#endif
position = offset;
@ -263,7 +267,14 @@ void TempFile::seek(const offset_t offset)
void TempFile::extend(size_t delta)
{
seek(size + delta);
const char* const buffer = zeros().getBuffer();
const size_t bufferSize = zeros().getSize();
const size_t newSize = size + delta;
for (size_t offset = size; offset < newSize; offset += bufferSize)
{
const size_t length = MIN(newSize - size, bufferSize);
write(offset, buffer, length);
}
}
//
@ -280,13 +291,13 @@ size_t TempFile::read(offset_t offset, void* buffer, size_t length)
DWORD bytes = 0;
if (!ReadFile(handle, buffer, length, &bytes, NULL) || bytes != length)
{
system_call_failed::raise("ReadFile");
system_error::raise("ReadFile");
}
#else
const int bytes = ::read(handle, buffer, length);
if (bytes < 0 || size_t(bytes) != length)
{
system_call_failed::raise("read");
system_error::raise("read");
}
#endif
position += bytes;
@ -307,13 +318,13 @@ size_t TempFile::write(offset_t offset, const void* buffer, size_t length)
DWORD bytes = 0;
if (!WriteFile(handle, buffer, length, &bytes, NULL) || bytes != length)
{
system_call_failed::raise("WriteFile");
system_error::raise("WriteFile");
}
#else
const int bytes = ::write(handle, buffer, length);
if (bytes < 0 || size_t(bytes) != length)
{
system_call_failed::raise("write");
system_error::raise("write");
}
#endif
position += bytes;

View File

@ -33,6 +33,7 @@
#include "../jrd/thread_proto.h"
#include "../common/classes/rwlock.h"
#include "../common/classes/array.h"
#include "../common/classes/File.h"
namespace Jrd {
@ -122,25 +123,6 @@ const UCHAR PIOB_success = 2; /* I/O successfully completed */
const UCHAR PIOB_pending = 4; /* Asynchronous I/O not yet completed */
#endif
static const int ZERO_BUF_SIZE = 1024 * 128;
class HugeStaticBuffer
{
public:
explicit HugeStaticBuffer(MemoryPool& p)
: zeroArray(p),
zeroBuff(zeroArray.getBuffer(ZERO_BUF_SIZE))
{
memset(zeroBuff, 0, ZERO_BUF_SIZE);
}
const char* get() const { return zeroBuff; }
private:
Firebird::Array<char> zeroArray;
char* const zeroBuff;
};
} //namespace Jrd
#endif // JRD_PIO_H

View File

@ -510,7 +510,7 @@ void PIO_header(Database* dbb, SCHAR * address, int length)
// we need a class here only to return memory on shutdown and avoid
// false memory leak reports
static InitInstance<HugeStaticBuffer> zeros;
static Firebird::InitInstance<ZeroBuffer> zeros;
USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vector,
@ -526,6 +526,8 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
* Initialize tail of file with zeros
*
**************************************/
const char* const zero_buff = zeros().getBuffer();
const size_t zero_buff_size = zeros().getSize();
// Fake buffer, used in seek_file. Page space ID have no matter there
// as we already know file to work with
@ -553,7 +555,7 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
for (ULONG i = startPage; i < startPage + initBy; )
{
bdb.bdb_page = PageNumber(0, i);
USHORT write_pages = ZERO_BUF_SIZE / dbb->dbb_page_size;
USHORT write_pages = zero_buff_size / dbb->dbb_page_size;
if (write_pages > leftPages)
write_pages = leftPages;
@ -564,7 +566,7 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
{
if (!(file = seek_file(file, &bdb, &offset, status_vector)))
return false;
if ((written = pwrite(file->fil_desc, zeros().get(), to_write, LSEEK_OFFSET_CAST offset)) == to_write)
if ((written = pwrite(file->fil_desc, zero_buff, to_write, LSEEK_OFFSET_CAST offset)) == to_write)
break;
if (written == (SLONG) -1 && !SYSCALL_INTERRUPTED(errno))
return unix_error("write", file, isc_io_write_err, status_vector);

View File

@ -460,7 +460,7 @@ void PIO_header(Database* dbb, SCHAR* address, int length)
// we need a class here only to return memory on shutdown and avoid
// false memory leak reports
static Firebird::InitInstance<HugeStaticBuffer> zeros;
static Firebird::InitInstance<ZeroBuffer> zeros;
USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vector,
@ -476,7 +476,8 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
* Initialize tail of file with zeros
*
**************************************/
const char* const zero_buff = zeros().get();
const char* const zero_buff = zeros().getBuffer();
const size_t zero_buff_size = zeros().getSize();
Database::Checkout dcoHolder(dbb);
FileExtendLockGuard extLock(main_file->fil_ext_lock, false);
@ -505,7 +506,7 @@ USHORT PIO_init_data(Database* dbb, jrd_file* main_file, ISC_STATUS* status_vect
for (ULONG i = startPage; i < startPage + initBy; )
{
bdb.bdb_page = PageNumber(0, i);
USHORT write_pages = ZERO_BUF_SIZE / dbb->dbb_page_size;
USHORT write_pages = zero_buff_size / dbb->dbb_page_size;
if (write_pages > leftPages)
write_pages = leftPages;