| // +build amd64 |
| |
| package docker |
| |
| // FIXME: This could be easily rewritten in pure Go |
| |
| /* |
| #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 ( |
| "io" |
| "os" |
| "syscall" |
| ) |
| |
| // FIXME: Move this to btrfs package? |
| |
| 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 |
| // FIXME: Check the return of Copy and compare with dstFile.Stat().Size |
| _, err = io.Copy(dstFile, srcFile) |
| return err |
| } |