summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2017-08-23 13:02:57 +0200
committerJeremy Allison <jra@samba.org>2017-08-24 05:38:49 +0200
commita475e1c4b0009987a818faa953d1be3ee9b68894 (patch)
treeeadb700ebafde41dcd93ca8a9c11a9c0dcc36152
parenta05debc113847ca3fd46ea63ec05a3fa357aa8e5 (diff)
downloadsamba-a475e1c4b0009987a818faa953d1be3ee9b68894.tar.gz
tdb: Use posix_fallocate
This should be significantly faster than pwriting. openbsd doesn't have posix_fallocate, so we do need the fallback. Also, it might have weird failure modes, so we keep the old code in place except for posix_fallocate returning success or ENOSPC. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Thu Aug 24 05:38:49 CEST 2017 on sn-devel-144
-rw-r--r--lib/tdb/common/io.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c
index ff3f2197ed2..15ba5b7d497 100644
--- a/lib/tdb/common/io.c
+++ b/lib/tdb/common/io.c
@@ -96,6 +96,24 @@ static int tdb_ftruncate(struct tdb_context *tdb, off_t length)
return ret;
}
+#if HAVE_POSIX_FALLOCATE
+static int tdb_posix_fallocate(struct tdb_context *tdb, off_t offset,
+ off_t len)
+{
+ ssize_t ret;
+
+ if (!tdb_adjust_offset(tdb, &offset)) {
+ return -1;
+ }
+
+ do {
+ ret = posix_fallocate(tdb->fd, offset, len);
+ } while ((ret == -1) && (errno == EINTR));
+
+ return ret;
+}
+#endif
+
static int tdb_fstat(struct tdb_context *tdb, struct stat *buf)
{
int ret;
@@ -395,6 +413,34 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
return -1;
}
+#if HAVE_POSIX_FALLOCATE
+ ret = tdb_posix_fallocate(tdb, size, addition);
+ if (ret == 0) {
+ return 0;
+ }
+ if (ret == ENOSPC) {
+ /*
+ * The Linux glibc (at least as of 2.24) fallback if
+ * the file system does not support fallocate does not
+ * reset the file size back to where it was. Also, to
+ * me it is unclear from the posix spec of
+ * posix_fallocate whether this is allowed or
+ * not. Better be safe than sorry and "goto fail" but
+ * "return -1" here, leaving the EOF pointer too
+ * large.
+ */
+ goto fail;
+ }
+
+ /*
+ * Retry the "old" way. Possibly unnecessary, but looking at
+ * our configure script there seem to be weird failure modes
+ * for posix_fallocate. See commit 3264a98ff16de, which
+ * probably refers to
+ * https://sourceware.org/bugzilla/show_bug.cgi?id=1083.
+ */
+#endif
+
ret = tdb_ftruncate(tdb, new_size);
if (ret == -1) {
char b = 0;