summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2012-03-08 14:30:06 -0800
committerSage Weil <sage@newdream.net>2012-03-08 14:30:06 -0800
commited6cc47b18ff78d6628a7dcba9873b717ba02a1a (patch)
tree2124a06d91d785e8539453edf7fad9a58d971a5f
parent1468d95101adfad44247016a1399aab6b86708d2 (diff)
downloadceph-ed6cc47b18ff78d6628a7dcba9873b717ba02a1a.tar.gz
filestore: use FL_ALLOC_PUNCH_HOLE to zero, when available
First try the FL_ALLOC_PUNCH_HOLE fallocate() flag. If we get EOPNOTSUPP, fall back to writing zeros. Check for fallocate(2) with configure. Also, avoid this if we are not Linux, since I'm not sure about the hard-coded FL_ALLOC_PUNCH_HOLE being correct on other platforms. Signed-off-by: Sage Weil <sage@newdream.net> Reviewed-by: Samuel Just <samuel.just@dreamhost.com>
-rw-r--r--configure.ac5
-rw-r--r--src/os/FileStore.cc41
-rw-r--r--src/os/FileStore.h4
3 files changed, 46 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 515243d24c0..81422145975 100644
--- a/configure.ac
+++ b/configure.ac
@@ -339,6 +339,11 @@ AC_CHECK_FUNC([sync_file_range],
[AC_DEFINE([HAVE_SYNC_FILE_RANGE], [], [sync_file_range(2) is supported])],
[])
+# fallocate
+AC_CHECK_FUNC([fallocate],
+ [AC_DEFINE([HAVE_FALLOCATE], [], [fallocate(2) is supported])],
+ [])
+
# Checks for typedefs, structures, and compiler characteristics.
#AC_HEADER_STDBOOL
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc
index acaeda8a134..f56b59839bb 100644
--- a/src/os/FileStore.cc
+++ b/src/os/FileStore.cc
@@ -2887,11 +2887,44 @@ int FileStore::_write(coll_t cid, const hobject_t& oid,
int FileStore::_zero(coll_t cid, const hobject_t& oid, uint64_t offset, size_t len)
{
+ dout(15) << "zero " << cid << "/" << oid << " " << offset << "~" << len << dendl;
+ int ret = 0;
+
+#ifdef HAVE_FALLOCATE
+# if !defined(DARWIN) && !defined(__FreeBSD__)
+ // first try to punch a hole.
+ int fd = lfn_open(cid, oid, O_RDONLY);
+ if (fd < 0) {
+ ret = -errno;
+ goto out;
+ }
+
+ // first try fallocate
+ ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE, offset, len);
+ if (ret < 0)
+ ret = -errno;
+ TEMP_FAILURE_RETRY(::close(fd));
+
+ if (ret == 0)
+ goto out; // yay!
+ if (ret != -EOPNOTSUPP)
+ goto out; // some other error
+# endif
+#endif
+
+ // lame, kernel is old and doesn't support it.
// write zeros.. yuck!
- bufferptr bp(len);
- bufferlist bl;
- bl.push_back(bp);
- return _write(cid, oid, offset, len, bl);
+ dout(20) << "zero FALLOC_FL_PUNCH_HOLE not supported, falling back to writing zeros" << dendl;
+ {
+ bufferptr bp(len);
+ bufferlist bl;
+ bl.push_back(bp);
+ ret = _write(cid, oid, offset, len, bl);
+ }
+
+ out:
+ dout(20) << "zero " << cid << "/" << oid << " " << offset << "~" << len << " = " << ret << dendl;
+ return ret;
}
int FileStore::_clone(coll_t cid, const hobject_t& oldoid, const hobject_t& newoid)
diff --git a/src/os/FileStore.h b/src/os/FileStore.h
index 72bcaaad1b8..a9e3f6cc8b4 100644
--- a/src/os/FileStore.h
+++ b/src/os/FileStore.h
@@ -37,6 +37,10 @@ using namespace std;
#include <ext/hash_map>
using namespace __gnu_cxx;
+// from include/linux/falloc.h:
+#ifndef FALLOC_FL_PUNCH_HOLE
+# define FALLOC_FL_PUNCH_HOLE 0x2
+#endif
class FileStore : public JournalingObjectStore,
public md_config_obs_t