mirror of
https://github.com/restic/restic.git
synced 2025-12-11 18:47:50 +00:00
fs: Refactor UtimesNano replacements
Previously, nodeRestoreTimestamps would do something like
if node.Type == restic.NodeTypeSymlink {
return nodeRestoreSymlinkTimestamps(...)
}
return syscall.UtimesNano(...)
where nodeRestoreSymlinkTimestamps was either a no-op or a
reimplementation of syscall.UtimesNano that handles symlinks, with some
repeated converting between timestamp types. The Linux implementation
was a bit clumsy, requiring three syscalls to set the timestamps.
In this new setup, there is a function utimesNano that has three
implementations:
* on Linux, it's a modified syscall.UtimesNano that uses
AT_SYMLINK_NOFOLLOW and AT_FDCWD so it can handle any type in a single
call;
* on other Unix platforms, it just calls the syscall function after
skipping symlinks;
* on Windows, it's the modified UtimesNano that was previously called
nodeRestoreSymlinkTimestamps, except with different arguments.
This commit is contained in:
@@ -292,18 +292,11 @@ func nodeRestoreMetadata(node *restic.Node, path string, warn func(msg string))
|
||||
}
|
||||
|
||||
func nodeRestoreTimestamps(node *restic.Node, path string) error {
|
||||
var utimes = [...]syscall.Timespec{
|
||||
syscall.NsecToTimespec(node.AccessTime.UnixNano()),
|
||||
syscall.NsecToTimespec(node.ModTime.UnixNano()),
|
||||
}
|
||||
atime := node.AccessTime.UnixNano()
|
||||
mtime := node.ModTime.UnixNano()
|
||||
|
||||
if node.Type == restic.NodeTypeSymlink {
|
||||
return nodeRestoreSymlinkTimestamps(path, utimes)
|
||||
if err := utimesNano(fixpath(path), atime, mtime, node.Type); err != nil {
|
||||
return &os.PathError{Op: "UtimesNano", Path: path, Err: err}
|
||||
}
|
||||
|
||||
if err := syscall.UtimesNano(fixpath(path), utimes[:]); err != nil {
|
||||
return errors.Wrap(err, "UtimesNano")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user