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. |