summaryrefslogtreecommitdiff
path: root/src/block
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2016-08-08 21:36:16 -0400
committerAlex Gorrod <alexander.gorrod@mongodb.com>2016-08-09 11:36:16 +1000
commit6d629337a23d466291952c65ea755855d185e9e6 (patch)
tree8d0ac4bdb9c7064e3aac2214d253626e0923de53 /src/block
parent7bd3f98212a6b74fd3aa6d7253759832002cfd88 (diff)
downloadmongo-6d629337a23d466291952c65ea755855d185e9e6.tar.gz
WT-2638 Change custom file system API to make truncate support clearer (#2908)
Replace the WT_FILE_HANDLE fh_allocate, fh_allocate_nolock and fh_truncate methods, with fh_extend, fh_extend_nolock, fh_truncate. This simplifies file extension because the WiredTiger layer no longer has to know ftruncate can extend files (if fallocate isn't available), and fall back to that method as needed, nor does WiredTiger have to know ftruncate requires locking.
Diffstat (limited to 'src/block')
-rw-r--r--src/block/block_map.c2
-rw-r--r--src/block/block_write.c81
2 files changed, 28 insertions, 55 deletions
diff --git a/src/block/block_map.c b/src/block/block_map.c
index d2c70fb4c49..b7afa61cc55 100644
--- a/src/block/block_map.c
+++ b/src/block/block_map.c
@@ -56,7 +56,7 @@ __wt_block_map(WT_SESSION_IMPL *session, WT_BLOCK *block,
*/
ret = handle->fh_map(handle,
(WT_SESSION *)session, mapped_regionp, lengthp, mapped_cookiep);
- if (ret == ENOTSUP) {
+ if (ret == EBUSY || ret == ENOTSUP) {
*(void **)mapped_regionp = NULL;
ret = 0;
}
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);
}
/*