]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/fs: add zero / hole punch support
authorSage Weil <sage@redhat.com>
Fri, 10 Apr 2015 23:55:05 +0000 (16:55 -0700)
committerSage Weil <sage@redhat.com>
Wed, 19 Aug 2015 21:03:56 +0000 (17:03 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/fs/FS.cc
src/os/fs/FS.h

index e64e324155a326fdc2bf041d3266ea581db86b5f..03c9a11835e06b25d93781ae4f1538cd55cfbe27 100644 (file)
 #include <sys/stat.h>
 #include <fcntl.h>
 
+// from include/linux/falloc.h:
+#ifndef FALLOC_FL_PUNCH_HOLE
+# define FALLOC_FL_PUNCH_HOLE 0x2
+#endif
+
 #include "FS.h"
 
 #include "XFS.h"
@@ -103,3 +108,38 @@ int FS::copy_file_range(int to_fd, uint64_t to_offset,
 {
   assert(0 == "write me");
 }
+
+int FS::zero(int fd, uint64_t offset, uint64_t length)
+{
+  int r;
+
+#ifdef CEPH_HAVE_FALLOCATE
+# if !defined(DARWIN) && !defined(__FreeBSD__)
+  // first try fallocate
+  r = fallocate(fd, FALLOC_FL_PUNCH_HOLE, offset, length);
+  if (r < 0) {
+    r = -errno;
+  }
+  if (r != -EOPNOTSUPP) {
+    goto out;  // a real error
+  }
+# endif
+#endif
+
+  {
+    // fall back to writing zeros
+    bufferlist bl;
+    bufferptr bp(length);
+    bp.zero();
+    bl.append(bp);
+    int r = ::lseek64(fd, offset, SEEK_SET);
+    if (r < 0) {
+      r = -errno;
+      goto out;
+    }
+    r = bl.write_fd(fd);
+  }
+
+ out:
+  return r;
+}
index 6a02b2721142d2e1e1e2da9747008f87ca50752f..a9d8100fafcc81585a0d8a553b0913f88e0e1cef 100644 (file)
@@ -38,6 +38,7 @@ public:
   virtual int copy_file_range(int to_fd, uint64_t to_offset,
                              int from_fd,
                              uint64_t from_offset, uint64_t from_len);
+  virtual int zero(int fd, uint64_t offset, uint64_t length);
 };
 
 #endif