-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstore_linux.go
More file actions
62 lines (54 loc) · 1.5 KB
/
store_linux.go
File metadata and controls
62 lines (54 loc) · 1.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Copyright 2023 Arista Networks, Inc. All rights reserved.
//
// Use of this source code is governed by the MIT license that can be found
// in the LICENSE file.
//
//go:build linux
// +build linux
package store
import (
"errors"
"fmt"
"os"
"golang.org/x/sys/unix"
)
// lstatIno tries to use statx with STATX_INO (which is less IO demanding than
// regular stat), falling back to lstat/fstat if the syscall isn't implemented,
// for instance if the kernel is too old.
func lstatIno(f *os.File, path string) (uint64, error) {
dirfd := unix.AT_FDCWD
if f != nil {
dirfd = int(f.Fd())
}
var statx unix.Statx_t
err := unix.Statx(dirfd, path, unix.AT_EMPTY_PATH|unix.AT_SYMLINK_NOFOLLOW, unix.STATX_INO, &statx)
switch {
case err == nil:
return statx.Ino, nil
case errors.Is(err, unix.ENOSYS):
// Fallback to Lstat or Fstat if ENOSYS
var stat unix.Stat_t
if path == "" {
if err := unix.Fstat(dirfd, &stat); err != nil {
return 0, &os.PathError{Op: "fstat", Path: fmt.Sprintf("fd:%d", dirfd), Err: err}
}
} else {
if err := unix.Lstat(path, &stat); err != nil {
return 0, &os.PathError{Op: "stat", Path: path, Err: err}
}
}
return stat.Ino, nil
default:
name := path
if name == "" {
name = fmt.Sprintf("fd:%d", dirfd)
}
return 0, &os.PathError{Op: "statx", Path: name, Err: err}
}
}
func openShared(path string, flag int, mode os.FileMode) (*os.File, error) {
return os.OpenFile(path, flag, mode)
}
func rename(f OSFile, to string) error {
return os.Rename(f.Name(), to)
}