all: Add copy-on-write filesystem support (fixes #4271) (#6746)

This commit is contained in:
Audrius Butkevicius
2020-06-18 08:15:47 +02:00
committed by GitHub
parent 273cc9cef8
commit 4812fd3ec1
26 changed files with 858 additions and 84 deletions
+10 -7
View File
@@ -8,7 +8,6 @@
package osutil
import (
"io"
"path/filepath"
"runtime"
"strings"
@@ -24,7 +23,7 @@ var renameLock = sync.NewMutex()
// RenameOrCopy renames a file, leaving source file intact in case of failure.
// Tries hard to succeed on various systems by temporarily tweaking directory
// permissions and removing the destination file when necessary.
func RenameOrCopy(src, dst fs.Filesystem, from, to string) error {
func RenameOrCopy(method fs.CopyRangeMethod, src, dst fs.Filesystem, from, to string) error {
renameLock.Lock()
defer renameLock.Unlock()
@@ -59,7 +58,7 @@ func RenameOrCopy(src, dst fs.Filesystem, from, to string) error {
}
}
err := copyFileContents(src, dst, from, to)
err := copyFileContents(method, src, dst, from, to)
if err != nil {
_ = dst.Remove(to)
return err
@@ -74,9 +73,9 @@ func RenameOrCopy(src, dst fs.Filesystem, from, to string) error {
// Copy copies the file content from source to destination.
// Tries hard to succeed on various systems by temporarily tweaking directory
// permissions and removing the destination file when necessary.
func Copy(src, dst fs.Filesystem, from, to string) (err error) {
func Copy(method fs.CopyRangeMethod, src, dst fs.Filesystem, from, to string) (err error) {
return withPreparedTarget(dst, from, to, func() error {
return copyFileContents(src, dst, from, to)
return copyFileContents(method, src, dst, from, to)
})
}
@@ -107,7 +106,7 @@ func withPreparedTarget(filesystem fs.Filesystem, from, to string, f func() erro
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all its contents will be replaced by the contents
// of the source file.
func copyFileContents(srcFs, dstFs fs.Filesystem, src, dst string) (err error) {
func copyFileContents(method fs.CopyRangeMethod, srcFs, dstFs fs.Filesystem, src, dst string) (err error) {
in, err := srcFs.Open(src)
if err != nil {
return
@@ -123,7 +122,11 @@ func copyFileContents(srcFs, dstFs fs.Filesystem, src, dst string) (err error) {
err = cerr
}
}()
_, err = io.Copy(out, in)
inFi, err := in.Stat()
if err != nil {
return
}
err = fs.CopyRange(method, in, out, 0, 0, inFi.Size())
return
}
+1 -1
View File
@@ -139,7 +139,7 @@ func TestRenameOrCopy(t *testing.T) {
content = string(buf)
}
err := osutil.RenameOrCopy(test.src, test.dst, test.file, "new")
err := osutil.RenameOrCopy(fs.CopyRangeMethodStandard, test.src, test.dst, test.file, "new")
if err != nil {
t.Fatal(err)
}