diff options
-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 |