diff options
author | Sage Weil <sage@newdream.net> | 2012-03-08 14:30:06 -0800 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2012-03-08 14:30:06 -0800 |
commit | ed6cc47b18ff78d6628a7dcba9873b717ba02a1a (patch) | |
tree | 2124a06d91d785e8539453edf7fad9a58d971a5f | |
parent | 1468d95101adfad44247016a1399aab6b86708d2 (diff) | |
download | ceph-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.ac | 5 | ||||
-rw-r--r-- | src/os/FileStore.cc | 41 | ||||
-rw-r--r-- | src/os/FileStore.h | 4 |
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 |