summaryrefslogtreecommitdiff
path: root/src/block/block_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/block/block_write.c')
-rw-r--r--src/block/block_write.c81
1 files changed, 27 insertions, 54 deletions
diff --git a/src/block/block_write.c b/src/block/block_write.c
index 30d06e6259a..7e5b027ce2b 100644
--- a/src/block/block_write.c
+++ b/src/block/block_write.c
@@ -82,22 +82,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 +118,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);
}
/*