mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-25 09:00:27 +00:00
local fs rename: if it fails with a cross device error try a copy
I don't want to add a new setting for this, at least until we get the first complain for a slow rename :) Fixes #440
This commit is contained in:
parent
3b46e6a6fb
commit
e1bf46c6a5
4 changed files with 32 additions and 9 deletions
|
@ -1,7 +0,0 @@
|
|||
package vfs
|
||||
|
||||
import "syscall"
|
||||
|
||||
func (fi FileInfo) getFileInfoSys() interface{} {
|
||||
return syscall.Win32FileAttributeData{}
|
||||
}
|
11
vfs/osfs.go
11
vfs/osfs.go
|
@ -11,6 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/eikenb/pipeat"
|
||||
fscopy "github.com/otiai10/copy"
|
||||
"github.com/pkg/sftp"
|
||||
"github.com/rs/xid"
|
||||
|
||||
|
@ -98,8 +99,14 @@ func (*OsFs) Create(name string, flag int) (File, *PipeWriter, func(), error) {
|
|||
}
|
||||
|
||||
// Rename renames (moves) source to target
|
||||
func (*OsFs) Rename(source, target string) error {
|
||||
return os.Rename(source, target)
|
||||
func (fs *OsFs) Rename(source, target string) error {
|
||||
err := os.Rename(source, target)
|
||||
if err != nil && isCrossDeviceError(err) {
|
||||
fsLog(fs, logger.LevelWarn, "cross device error detected while renaming %#v -> %#v. Trying a copy, this could take a long time",
|
||||
source, target)
|
||||
return fscopy.Copy(source, target)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove removes the named file or (empty) directory.
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
package vfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -27,3 +30,7 @@ func (fi FileInfo) getFileInfoSys() interface{} {
|
|||
Uid: uint32(defaultUID),
|
||||
Gid: uint32(defaultGID)}
|
||||
}
|
||||
|
||||
func isCrossDeviceError(err error) bool {
|
||||
return errors.Is(err, unix.EXDEV)
|
||||
}
|
16
vfs/sys_windows.go
Normal file
16
vfs/sys_windows.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package vfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func (fi FileInfo) getFileInfoSys() interface{} {
|
||||
return syscall.Win32FileAttributeData{}
|
||||
}
|
||||
|
||||
func isCrossDeviceError(err error) bool {
|
||||
return errors.Is(err, windows.ERROR_NOT_SAME_DEVICE)
|
||||
}
|
Loading…
Reference in a new issue