diff --git a/utils.go b/utils.go index 57737f7b25..44573927a1 100644 --- a/utils.go +++ b/utils.go @@ -1,9 +1,33 @@ package docker +/* +#include +#include +#include + +// 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 ( "fmt" + "io" "io/ioutil" + "os" "strings" + "syscall" ) // 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 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 +}