Skip to content

Commit

Permalink
fix: move cross device
Browse files Browse the repository at this point in the history
  • Loading branch information
alanshaw committed Nov 12, 2024
1 parent 5c37ba4 commit c89dc24
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion pkg/store/blobstore/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"os"
"path"
"strings"

"github.com/multiformats/go-multibase"
"github.com/multiformats/go-multihash"
Expand Down Expand Up @@ -160,7 +161,7 @@ func (b *FsBlobstore) Put(ctx context.Context, digest multihash.Multihash, size
_ = f.Close()
closed = true

err = os.Rename(tmpname, name)
err = move(tmpname, name)
if err != nil {
return fmt.Errorf("moving file: %w", err)
}
Expand All @@ -169,6 +170,47 @@ func (b *FsBlobstore) Put(ctx context.Context, digest multihash.Multihash, size
return nil
}

func move(source, destination string) error {
err := os.Rename(source, destination)
if err != nil && strings.Contains(err.Error(), "invalid cross-device link") {
return moveCrossDevice(source, destination)
}
return err
}

func moveCrossDevice(source, destination string) error {
src, err := os.Open(source)
if err != nil {
return fmt.Errorf("opening source: %w", err)
}
dst, err := os.Create(destination)
if err != nil {
src.Close()
return fmt.Errorf("creating destination: %w", err)
}
_, err = io.Copy(dst, src)
src.Close()
dst.Close()
if err != nil {
return fmt.Errorf("copying file: %w", err)
}
fi, err := os.Stat(source)
if err != nil {
os.Remove(destination)
return fmt.Errorf("getting file stats: %w", err)
}
err = os.Chmod(destination, fi.Mode())
if err != nil {
os.Remove(destination)
return fmt.Errorf("changing file mode: %w", err)
}
err = os.Remove(source)
if err != nil {
return fmt.Errorf("removing source: %w", err)
}
return nil
}

var _ Blobstore = (*FsBlobstore)(nil)
var _ FileSystemer = (*FsBlobstore)(nil)

Expand Down

0 comments on commit c89dc24

Please sign in to comment.