|
From: <hv...@us...> - 2014-05-29 07:44:30
|
Revision: 59642
http://sourceforge.net/p/firebird/code/59642
Author: hvlad
Date: 2014-05-29 07:44:26 +0000 (Thu, 29 May 2014)
Log Message:
-----------
Implement support for fallocate() call on Linux.
Implement improvement CORE-4443 : Use fast file grow on those Linux systems which supports it
Modified Paths:
--------------
firebird/branches/B2_5_Release/configure.in
firebird/branches/B2_5_Release/src/jrd/os/pio.h
firebird/branches/B2_5_Release/src/jrd/os/posix/unix.cpp
firebird/branches/B2_5_Release/src/jrd/pag.cpp
firebird/branches/B2_5_Release/src/jrd/pag.h
Modified: firebird/branches/B2_5_Release/configure.in
===================================================================
--- firebird/branches/B2_5_Release/configure.in 2014-05-29 07:19:29 UTC (rev 59641)
+++ firebird/branches/B2_5_Release/configure.in 2014-05-29 07:44:26 UTC (rev 59642)
@@ -699,6 +699,7 @@
AC_CHECK_HEADERS(atomic_ops.h)
AC_CHECK_HEADERS(utime.h)
AC_CHECK_HEADERS(poll.h)
+AC_CHECK_HEADERS(linux/falloc.h)
dnl Check for libraries
AC_SEARCH_LIBS(dlopen, dl)
Modified: firebird/branches/B2_5_Release/src/jrd/os/pio.h
===================================================================
--- firebird/branches/B2_5_Release/src/jrd/os/pio.h 2014-05-29 07:19:29 UTC (rev 59641)
+++ firebird/branches/B2_5_Release/src/jrd/os/pio.h 2014-05-29 07:44:26 UTC (rev 59642)
@@ -93,6 +93,7 @@
const USHORT FIL_force_write = 1;
const USHORT FIL_no_fs_cache = 2; // not using file system cache
const USHORT FIL_readonly = 4; // file opened in readonly mode
+const USHORT FIL_no_fast_extend = 8; // file not supports fast extending
// Physical IO trace events
Modified: firebird/branches/B2_5_Release/src/jrd/os/posix/unix.cpp
===================================================================
--- firebird/branches/B2_5_Release/src/jrd/os/posix/unix.cpp 2014-05-29 07:19:29 UTC (rev 59641)
+++ firebird/branches/B2_5_Release/src/jrd/os/posix/unix.cpp 2014-05-29 07:44:26 UTC (rev 59642)
@@ -46,6 +46,9 @@
#ifdef HAVE_AIO_H
#include <aio.h>
#endif
+#ifdef HAVE_LINUX_FALLOC_H
+#include <linux/falloc.h>
+#endif
#include "../jrd/jrd.h"
#include "../jrd/os/pio.h"
@@ -281,7 +284,7 @@
}
-void PIO_extend(Database* dbb, jrd_file* /*main_file*/, const ULONG /*extPages*/, const USHORT /*pageSize*/)
+void PIO_extend(Database* dbb, jrd_file* main_file, const ULONG extPages, const USHORT pageSize)
{
/**************************************
*
@@ -293,6 +296,56 @@
* Extend file by extPages pages of pageSize size.
*
**************************************/
+
+#ifdef HAVE_LINUX_FALLOC_H
+ ULONG leftPages = extPages;
+ for (jrd_file* file = main_file; file && leftPages; file = file->fil_next)
+ {
+ const ULONG filePages = PIO_get_number_of_pages(file, pageSize);
+ const ULONG fileMaxPages = (file->fil_max_page == MAX_ULONG) ?
+ MAX_ULONG : file->fil_max_page - file->fil_min_page + 1;
+ if (filePages < fileMaxPages)
+ {
+ if (file->fil_flags & FIL_no_fast_extend)
+ return;
+
+ const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages);
+
+ int r;
+ for (r = 0; r < IO_RETRY; r++)
+ {
+ int err = fallocate(file->fil_desc, 0, filePages * pageSize, extendBy * pageSize);
+ if (err == 0)
+ break;
+
+ err = errno;
+ if (SYSCALL_INTERRUPTED(err))
+ continue;
+
+ if (err == EOPNOTSUPP || err == ENOSYS)
+ file->fil_flags |= FIL_no_fast_extend;
+ else
+ unix_error("fallocate", file, isc_io_write_err);
+ return;
+ }
+
+ if (r == IO_RETRY)
+ {
+#ifdef DEV_BUILD
+ fprintf(stderr, "PIO_extend: retry count exceeded\n");
+ fflush(stderr);
+#endif
+ unix_error("fallocate_retry", file, isc_io_write_err);
+ return;
+ }
+
+ leftPages -= extendBy;
+ }
+ }
+#else
+ main_file->fil_flags |= FIL_no_fast_extend;
+#endif // HAVE_LINUX_FALLOC_H
+
// not implemented
return;
}
Modified: firebird/branches/B2_5_Release/src/jrd/pag.cpp
===================================================================
--- firebird/branches/B2_5_Release/src/jrd/pag.cpp 2014-05-29 07:19:29 UTC (rev 59641)
+++ firebird/branches/B2_5_Release/src/jrd/pag.cpp 2014-05-29 07:44:26 UTC (rev 59642)
@@ -918,7 +918,7 @@
// At this point we ensure database has at least "initialized" pages
// allocated. To avoid file growth by few pages when all this space
// will be used, extend file up to initialized + next_init_pages now
- pageSpace->extend(tdbb, initialized + next_init_pages);
+ pageSpace->extend(tdbb, initialized + next_init_pages, false);
}
break; // Found a page and successfully fake-ed it
@@ -2383,7 +2383,7 @@
return pgSpace->maxAlloc(dbb->dbb_page_size);
}
-bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum)
+bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum, const bool forceSize)
{
/**************************************
*
@@ -2395,10 +2395,14 @@
* If "DatabaseGrowthIncrement" is less than MIN_EXTEND_BYTES then don't
* extend file(s)
*
+ * If forceSize is true, extend file up to pageNum pages (despite of value
+ * of "DatabaseGrowthIncrement") and don't make attempts to extend by less
+ * pages.
+ *
**************************************/
const int MAX_EXTEND_BYTES = Config::getDatabaseGrowthIncrement();
- if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES)
+ if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES && !forceSize)
return true;
Database* dbb = tdbb->getDatabase();
@@ -2415,6 +2419,7 @@
while (true)
{
+ const ULONG oldMaxPageNumber = maxPageNumber;
try
{
PIO_extend(dbb, file, extPages, dbb->dbb_page_size);
@@ -2422,10 +2427,16 @@
}
catch (const status_exception&)
{
- if (extPages > reqPages)
+ if (extPages > reqPages && !forceSize)
{
+ fb_utils::init_status(tdbb->tdbb_status_vector);
+
+ // if file was extended, return, else try to extend by less pages
+
+ if (oldMaxPageNumber < maxAlloc(dbb->dbb_page_size))
+ return true;
+
extPages = MAX(reqPages, extPages / 2);
- fb_utils::init_status(tdbb->tdbb_status_vector);
}
else
{
Modified: firebird/branches/B2_5_Release/src/jrd/pag.h
===================================================================
--- firebird/branches/B2_5_Release/src/jrd/pag.h 2014-05-29 07:19:29 UTC (rev 59641)
+++ firebird/branches/B2_5_Release/src/jrd/pag.h 2014-05-29 07:44:26 UTC (rev 59642)
@@ -103,7 +103,7 @@
static ULONG maxAlloc(const Database* dbb);
// extend page space
- bool extend(thread_db*, const ULONG);
+ bool extend(thread_db*, const ULONG, const bool);
private:
ULONG maxPageNumber;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|