From ed6cc47b18ff78d6628a7dcba9873b717ba02a1a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 8 Mar 2012 14:30:06 -0800 Subject: [PATCH] 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 Reviewed-by: Samuel Just --- configure.ac | 5 +++++ src/os/FileStore.cc | 41 +++++++++++++++++++++++++++++++++++++---- src/os/FileStore.h | 4 ++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 515243d24c026..814221459751f 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 acaeda8a13492..f56b59839bbf6 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 72bcaaad1b82a..a9e3f6cc8b424 100644 --- a/src/os/FileStore.h +++ b/src/os/FileStore.h @@ -37,6 +37,10 @@ using namespace std; #include 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 -- 2.39.5