From: <hv...@us...> - 2014-06-10 09:01:01
|
Revision: 59679 http://sourceforge.net/p/firebird/code/59679 Author: hvlad Date: 2014-06-10 09:00:58 +0000 (Tue, 10 Jun 2014) Log Message: ----------- Front ported support for fallocate() call on Linux. Front ported improvement CORE-4443 : Use fast file grow on those Linux systems which supports it Modified Paths: -------------- firebird/trunk/configure.ac firebird/trunk/src/jrd/os/pio.h firebird/trunk/src/jrd/os/posix/unix.cpp firebird/trunk/src/jrd/pag.cpp firebird/trunk/src/jrd/pag.h Modified: firebird/trunk/configure.ac =================================================================== --- firebird/trunk/configure.ac 2014-06-10 07:13:34 UTC (rev 59678) +++ firebird/trunk/configure.ac 2014-06-10 09:00:58 UTC (rev 59679) @@ -690,6 +690,7 @@ AC_CHECK_HEADERS(langinfo.h) AC_CHECK_HEADERS(iconv.h) AC_CHECK_HEADERS(libio.h) +AC_CHECK_HEADERS(linux/falloc.h) dnl check for ICU presence AC_CHECK_HEADER(unicode/ucnv.h,,AC_MSG_ERROR(ICU support not found - please install development ICU package)) Modified: firebird/trunk/src/jrd/os/pio.h =================================================================== --- firebird/trunk/src/jrd/os/pio.h 2014-06-10 07:13:34 UTC (rev 59678) +++ firebird/trunk/src/jrd/os/pio.h 2014-06-10 09:00:58 UTC (rev 59679) @@ -94,6 +94,7 @@ 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_sh_write = 8; // file opened in shared write mode +const USHORT FIL_no_fast_extend = 16; // file not supports fast extending // Physical IO trace events Modified: firebird/trunk/src/jrd/os/posix/unix.cpp =================================================================== --- firebird/trunk/src/jrd/os/posix/unix.cpp 2014-06-10 07:13:34 UTC (rev 59678) +++ firebird/trunk/src/jrd/os/posix/unix.cpp 2014-06-10 09:00:58 UTC (rev 59679) @@ -45,6 +45,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" @@ -291,7 +294,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) { /************************************** * @@ -303,6 +306,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/trunk/src/jrd/pag.cpp =================================================================== --- firebird/trunk/src/jrd/pag.cpp 2014-06-10 07:13:34 UTC (rev 59678) +++ firebird/trunk/src/jrd/pag.cpp 2014-06-10 09:00:58 UTC (rev 59679) @@ -640,7 +640,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 @@ -2039,7 +2039,7 @@ return pgSpace->lastUsedPage(); } -bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum) +bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum, const bool forceSize) { /************************************** * @@ -2051,12 +2051,16 @@ * 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. + * **************************************/ fb_assert(dbb == tdbb->getDatabase()); const int MAX_EXTEND_BYTES = dbb->dbb_config->getDatabaseGrowthIncrement(); - if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES) + if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES && !forceSize) return true; if (pageNum >= maxAlloc()) @@ -2071,6 +2075,7 @@ while (true) { + const ULONG oldMaxPageNumber = maxPageNumber; try { PIO_extend(dbb, file, extPages, dbb->dbb_page_size); @@ -2078,10 +2083,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()) + return true; + extPages = MAX(reqPages, extPages / 2); - fb_utils::init_status(tdbb->tdbb_status_vector); } else { Modified: firebird/trunk/src/jrd/pag.h =================================================================== --- firebird/trunk/src/jrd/pag.h 2014-06-10 07:13:34 UTC (rev 59678) +++ firebird/trunk/src/jrd/pag.h 2014-06-10 09:00:58 UTC (rev 59679) @@ -120,7 +120,7 @@ static ULONG lastUsedPage(const Database* dbb); // extend page space - bool extend(thread_db*, const ULONG); + bool extend(thread_db*, const ULONG, const bool); // get SCN's page number ULONG getSCNPageNum(ULONG sequence); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |