From f2a613a41d6ad7b5a1b66087e386380d38e50599 Mon Sep 17 00:00:00 2001 From: Ramon Fernandez Date: Fri, 26 Aug 2016 18:28:48 -0400 Subject: Import wiredtiger: 2566118fc68b0124187e806bed52eb7cdbcb1be0 from branch mongodb-3.4 ref: 34182ad..2566118fc6 for: 3.3.12 WT-2631 nullptr is passed for parameters marked with attribute non-null WT-2638 ftruncate may not be supported WT-2645 wt dump: push the complexity of collecting metadata into a dump cursor WT-2678 The metadata should not imply that an empty value is true WT-2695 Integrate s390x accelerated crc32c support WT-2719 add fuzz testing for WiredTiger options and reconfiguration. WT-2734 Improve documentation of eviction behavior WT-2766 Don't count eviction of lookaside file pages for the purpose of checking stuck cache WT-2783 wtperf multi-btree.wtperf dumps core on Mac WT-2787 Include src/include/wiredtiger_ext.h is problematic WT-2795 Update documentation around read-only configuration WT-2807 Switch Jenkins performance tests to tcmalloc WT-2813 small cache usage stuck even with large cache WT-2814 Enhance wtperf to support single-op truncate mode WT-2816 Improve WiredTiger eviction performance WT-2817 Investigate performance regression in develop, add workload to wtperf/runners WT-2818 The page visibility check when queuing pages for eviction is overly restrictive WT-2820 add gcc warn_unused_result attribute WT-2822 panic mutex and other functions that cannot fail WT-2823 support file handles without a truncate method WT-2826 clang38 false positive on uninitialized variable. WT-2827 checkpoint log_size configuration improvements WT-2828 Make long wtperf tests reflect mongoDB usage WT-2829 Switch automated testing to use enable-strict configure option WT-2832 Python test uses hard-coded temporary directory WT-2834 Join cursor: discrepancy with bloom filters WT-2835 WT_CONNECTION.leak-memory can skip memory map and cache cleanup WT-2838 Don't free session handles on close if leak memory is configured WT-2839 lint: Ignoring return value of function WT-2840 clang analysis: garbage values WT-2841 Jenkins Valgrind runner is reporting errors in test wt2719_reconfig WT-2843 Fix a bug in recovery if there is no filesystem truncate support WT-2846 Several bugs related to reconfiguring eviction server at runtime WT-2847 Merge fair locks into read/write locks. WT-2850 clang 4.1 attribute warnings when building WT-2853 Multi threaded reader writer example shows temporary slowdown or lockup WT-2857 POSIX ftruncate calls should be #ifdef'd HAVE_FTRUNCATE WT-2862 Fix lint error in test case for forced eviction with multiple cursors WT-2863 Support UTF-8 paths on Windows --- src/third_party/wiredtiger/src/block/block_write.c | 115 +++++++++------------ 1 file changed, 50 insertions(+), 65 deletions(-) (limited to 'src/third_party/wiredtiger/src/block/block_write.c') diff --git a/src/third_party/wiredtiger/src/block/block_write.c b/src/third_party/wiredtiger/src/block/block_write.c index 30d06e6259a..d926a8b7c2d 100644 --- a/src/third_party/wiredtiger/src/block/block_write.c +++ b/src/third_party/wiredtiger/src/block/block_write.c @@ -15,6 +15,20 @@ int __wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len) { + WT_DECL_RET; + + __wt_verbose(session, + WT_VERB_BLOCK, "truncate file to %" PRIuMAX, (uintmax_t)len); + + /* + * Truncate requires serialization, we depend on our caller for that. + * + * Truncation isn't a requirement of the block manager, it's only used + * to conserve disk space. Regardless of the underlying file system + * call's result, the in-memory understanding of the file size changes. + */ + block->size = block->extend_size = len; + /* * Backups are done by copying files outside of WiredTiger, potentially * by system utilities. We cannot truncate the file during the backup @@ -26,18 +40,16 @@ __wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len) * targeted solution at some point. */ if (S2C(session)->hot_backup) - return (EBUSY); + return (0); /* - * Additionally, the truncate might fail if there's a file mapping (if - * there's an open checkpoint on the file), in which case the underlying - * function returns EBUSY. + * The truncate may fail temporarily or permanently (for example, there + * may be a file mapping if there's an open checkpoint on the file on a + * POSIX system, in which case the underlying function returns EBUSY). + * It's OK, we don't have to be able to truncate files. */ - WT_RET(__wt_ftruncate(session, block->fh, len)); - - block->size = block->extend_size = len; - - return (0); + ret = __wt_ftruncate(session, block->fh, len); + return (ret == EBUSY || ret == ENOTSUP ? 0 : ret); } /* @@ -82,22 +94,18 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block, { WT_DECL_RET; WT_FILE_HANDLE *handle; - bool locked; /* * The locking in this function is messy: by definition, the live system * is locked when we're called, but that lock may have been acquired by * our caller or our caller's caller. If our caller's lock, release_lock - * comes in set, indicating this function can unlock it before returning - * (either before extending the file or afterward, depending on the call - * used). If it is our caller's caller, then release_lock comes in not - * set, indicating it cannot be released here. + * comes in set and this function can unlock it before returning (so it + * isn't held while extending the file). If it is our caller's caller, + * then release_lock comes in not set, indicating it cannot be released + * here. * - * If we unlock here, we clear release_lock. But if we then find out we - * need a lock after all, we re-acquire the lock and set release_lock so - * our caller knows to release it. + * If we unlock here, we clear release_lock. */ - locked = true; /* If not configured to extend the file, we're done. */ if (block->extend_len == 0) @@ -122,62 +130,39 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block, * used to extend the file initialize the extended space. If a writing * thread races with the extending thread, the extending thread might * overwrite already written data, and that would be very, very bad. - * - * Some variants of the system call to extend the file fail at run-time - * based on the filesystem type, fall back to ftruncate in that case, - * and remember that ftruncate requires locking. */ handle = fh->handle; - if (handle->fh_allocate != NULL || - handle->fh_allocate_nolock != NULL) { - /* - * Release any locally acquired lock if not needed to extend the - * file, extending the file may require updating on-disk file's - * metadata, which can be slow. (It may be a bad idea to - * configure for file extension on systems that require locking - * over the extend call.) - */ - if (handle->fh_allocate_nolock != NULL && *release_lockp) { - *release_lockp = locked = false; - __wt_spin_unlock(session, &block->live_lock); - } - - /* - * Extend the file: there's a race between setting the value of - * extend_size and doing the extension, but it should err on the - * side of extend_size being smaller than the actual file size, - * and that's OK, we simply may do another extension sooner than - * otherwise. - */ - block->extend_size = block->size + block->extend_len * 2; - if ((ret = __wt_fallocate( - session, fh, block->size, block->extend_len * 2)) == 0) - return (0); - WT_RET_ERROR_OK(ret, ENOTSUP); - } + if (handle->fh_extend == NULL && handle->fh_extend_nolock == NULL) + return (0); /* - * We may have a caller lock or a locally acquired lock, but we need a - * lock to call ftruncate. + * Set the extend_size before releasing the lock, I don't want to read + * and manipulate multiple values without holding a lock. + * + * There's a race between the calculation and doing the extension, but + * it should err on the side of extend_size being smaller than the + * actual file size, and that's OK, we simply may do another extension + * sooner than otherwise. */ - if (!locked) { - __wt_spin_lock(session, &block->live_lock); - *release_lockp = true; - } + block->extend_size = block->size + block->extend_len * 2; /* - * The underlying truncate call initializes allocated space, reset the - * extend length after locking so we don't overwrite already-written - * blocks. + * Release any locally acquired lock if not needed to extend the file, + * extending the file may require updating on-disk file's metadata, + * which can be slow. (It may be a bad idea to configure for file + * extension on systems that require locking over the extend call.) */ - block->extend_size = block->size + block->extend_len * 2; + if (handle->fh_extend_nolock != NULL && *release_lockp) { + *release_lockp = false; + __wt_spin_unlock(session, &block->live_lock); + } /* - * The truncate might fail if there's a mapped file (in other words, if - * there's an open checkpoint on the file), that's OK. + * The extend might fail (for example, the file is mapped into memory), + * or discover file extension isn't supported; both are OK. */ - WT_RET_BUSY_OK(__wt_ftruncate(session, fh, block->extend_size)); - return (0); + ret = __wt_fextend(session, fh, block->extend_size); + return (ret == EBUSY || ret == ENOTSUP ? 0 : ret); } /* @@ -378,9 +363,9 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_STAT_FAST_CONN_INCRV( session, block_byte_write_checkpoint, align_size); - WT_RET(__wt_verbose(session, WT_VERB_WRITE, + __wt_verbose(session, WT_VERB_WRITE, "off %" PRIuMAX ", size %" PRIuMAX ", cksum %" PRIu32, - (uintmax_t)offset, (uintmax_t)align_size, cksum)); + (uintmax_t)offset, (uintmax_t)align_size, cksum); *offsetp = offset; *sizep = WT_STORE_SIZE(align_size); -- cgit v1.2.1