summaryrefslogtreecommitdiff
path: root/src/block/block_write.c
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2016-05-05 15:38:12 +1000
committerMichael Cahill <michael.cahill@mongodb.com>2016-05-05 15:38:12 +1000
commit636a7b25ef3eca6b98009330f4d35337d4f35717 (patch)
tree7cc2e03ad96e206cbe73343feef10197023a37da /src/block/block_write.c
parenteaa7b5f0fcc62f356c33a2c56f45b609a73ca5dd (diff)
parent75c22bc0c662622c14e5c47d99ff262cede2c6bf (diff)
downloadmongo-636a7b25ef3eca6b98009330f4d35337d4f35717.tar.gz
Merge branch 'develop' into mongodb-3.4mongodb-3.3.6
Diffstat (limited to 'src/block/block_write.c')
-rw-r--r--src/block/block_write.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/src/block/block_write.c b/src/block/block_write.c
index 134272b52f9..4f1224f3c13 100644
--- a/src/block/block_write.c
+++ b/src/block/block_write.c
@@ -15,6 +15,24 @@
int
__wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len)
{
+ /*
+ * Backups are done by copying files outside of WiredTiger, potentially
+ * by system utilities. We cannot truncate the file during the backup
+ * window, we might surprise an application.
+ *
+ * Stop block truncation. This affects files that aren't involved in the
+ * backup (for example, doing incremental backups, which only copies log
+ * files, or targeted backups, stops all truncation). We may want a more
+ * targeted solution at some point.
+ */
+ if (S2C(session)->hot_backup)
+ return (EBUSY);
+
+ /*
+ * 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.
+ */
WT_RET(__wt_ftruncate(session, block->fh, len));
block->size = block->extend_size = len;
@@ -30,27 +48,28 @@ int
__wt_block_discard(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t added_size)
{
WT_DECL_RET;
+ WT_FILE_HANDLE *handle;
+ /* The file may not support this call. */
+ handle = block->fh->handle;
+ if (handle->fadvise == NULL)
+ return (0);
+
+ /* The call may not be configured. */
if (block->os_cache_max == 0)
return (0);
/*
* We're racing on the addition, but I'm not willing to serialize on it
- * in the standard read path with more evidence it's needed.
+ * in the standard read path without evidence it's needed.
*/
if ((block->os_cache += added_size) <= block->os_cache_max)
return (0);
block->os_cache = 0;
- WT_ERR(block->fh->fh_advise(session,
- block->fh, (wt_off_t)0, (wt_off_t)0, POSIX_FADV_DONTNEED));
- return (0);
-
-err: /* Ignore ENOTSUP, but don't try again. */
- if (ret != ENOTSUP)
- return (ret);
- block->os_cache_max = 0;
- return (0);
+ ret = handle->fadvise(handle, (WT_SESSION *)session,
+ (wt_off_t)0, (wt_off_t)0, WT_FILE_HANDLE_DONTNEED);
+ return (ret == EBUSY || ret == ENOTSUP ? 0 : ret);
}
/*
@@ -62,6 +81,7 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block,
WT_FH *fh, wt_off_t offset, size_t align_size, bool *release_lockp)
{
WT_DECL_RET;
+ WT_FILE_HANDLE *handle;
bool locked;
/*
@@ -107,7 +127,8 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block,
* based on the filesystem type, fall back to ftruncate in that case,
* and remember that ftruncate requires locking.
*/
- if (fh->fallocate_available != WT_FALLOCATE_NOT_AVAILABLE) {
+ handle = fh->handle;
+ if (handle->fallocate != NULL || handle->fallocate_nolock != NULL) {
/*
* Release any locally acquired lock if not needed to extend the
* file, extending the file may require updating on-disk file's
@@ -115,7 +136,7 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block,
* configure for file extension on systems that require locking
* over the extend call.)
*/
- if (!fh->fallocate_requires_locking && *release_lockp) {
+ if (handle->fallocate_nolock != NULL && *release_lockp) {
*release_lockp = locked = false;
__wt_spin_unlock(session, &block->live_lock);
}
@@ -131,8 +152,7 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block,
if ((ret = __wt_fallocate(
session, fh, block->size, block->extend_len * 2)) == 0)
return (0);
- if (ret != ENOTSUP)
- return (ret);
+ WT_RET_ERROR_OK(ret, ENOTSUP);
}
/*
@@ -155,9 +175,8 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block,
* 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.
*/
- if ((ret = __wt_ftruncate(session, fh, block->extend_size)) == EBUSY)
- ret = 0;
- return (ret);
+ WT_RET_BUSY_OK(__wt_ftruncate(session, fh, block->extend_size));
+ return (0);
}
/*