]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
filestore: use FL_ALLOC_PUNCH_HOLE to zero, when available
authorSage Weil <sage@newdream.net>
Thu, 8 Mar 2012 22:30:06 +0000 (14:30 -0800)
committerSage Weil <sage@newdream.net>
Thu, 8 Mar 2012 22:30:06 +0000 (14:30 -0800)
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>
configure.ac
src/os/FileStore.cc
src/os/FileStore.h

index 515243d24c02661a3c50b5ba21e8098baed3b87b..814221459751f2c07706d4597d65e2282a13c087 100644 (file)
@@ -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
index acaeda8a13492ae72460d0aa88ea24fd5964c1f6..f56b59839bbf6dbf587cd6e053e1dd0f167f5558 100644 (file)
@@ -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)
index 72bcaaad1b82a119c2141f11f3d16e47ca8f5508..a9e3f6cc8b42475d7b3d88a35152310afd7663eb 100644 (file)
@@ -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