Skip to content

Commit 3f4b77d

Browse files
committed
pkg/fileutils: add ReflinkOrCopy()
Add a function to copy via reflink if possible or fall back to the normal io.Copy(). c/image uses this function internally[1] however I like to export this and use it in podman and I think this package here in c/storage is the most logical location for it. Note compared to the c/image version I am calling unix.IoctlFileClone() directly instead of the raw syscall function. [1] https://github.com/containers/image/tree/main/internal/reflink Signed-off-by: Paul Holzinger <[email protected]>
1 parent 5a2ca6a commit 3f4b77d

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

pkg/fileutils/reflink_linux.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package fileutils
2+
3+
import (
4+
"io"
5+
"os"
6+
7+
"golang.org/x/sys/unix"
8+
)
9+
10+
// ReflinkOrCopy attempts to reflink the source to the destination fd.
11+
// If reflinking fails or is unsupported, it falls back to io.Copy().
12+
func ReflinkOrCopy(src, dst *os.File) error {
13+
err := unix.IoctlFileClone(int(dst.Fd()), int(src.Fd()))
14+
if err == nil {
15+
return nil
16+
}
17+
18+
_, err = io.Copy(dst, src)
19+
return err
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build !linux
2+
3+
package fileutils
4+
5+
import (
6+
"io"
7+
"os"
8+
)
9+
10+
// ReflinkOrCopy attempts to reflink the source to the destination fd.
11+
// If reflinking fails or is unsupported, it falls back to io.Copy().
12+
func ReflinkOrCopy(src, dst *os.File) error {
13+
_, err := io.Copy(dst, src)
14+
return err
15+
}

0 commit comments

Comments
 (0)