浏览代码

Add CopyFile that can use btrfs reflinks if availible

Alexander Larsson 12 年之前
父节点
当前提交
cda8754013
共有 1 个文件被更改,包括 43 次插入0 次删除
  1. 43 0
      utils.go

+ 43 - 0
utils.go

@@ -1,9 +1,33 @@
 package docker
 package docker
 
 
+/*
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#include <errno.h>
+
+// See linux.git/fs/btrfs/ioctl.h
+#define BTRFS_IOCTL_MAGIC 0x94
+#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
+
+int
+btrfs_reflink(int fd_out, int fd_in)
+{
+  int res;
+  res = ioctl(fd_out, BTRFS_IOC_CLONE, fd_in);
+  if (res < 0)
+    return errno;
+  return 0;
+}
+
+*/
+import "C"
 import (
 import (
 	"fmt"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"io/ioutil"
+	"os"
 	"strings"
 	"strings"
+	"syscall"
 )
 )
 
 
 // Compare two Config struct. Do not compare the "Image" nor "Hostname" fields
 // Compare two Config struct. Do not compare the "Image" nor "Hostname" fields
@@ -182,3 +206,22 @@ func RootIsShared() bool {
 	// No idea, probably safe to assume so
 	// No idea, probably safe to assume so
 	return true
 	return true
 }
 }
+
+func BtrfsReflink(fd_out, fd_in uintptr) error {
+	res := C.btrfs_reflink(C.int(fd_out), C.int(fd_in))
+	if res != 0 {
+		return syscall.Errno(res)
+	}
+	return nil
+}
+
+func CopyFile(dstFile, srcFile *os.File) error {
+	err := BtrfsReflink(dstFile.Fd(), srcFile.Fd())
+	if err == nil {
+		return nil
+	}
+
+	// Fall back to normal copy
+	_, err = io.Copy(dstFile, srcFile)
+	return err
+}