1
1
//! Linux `statx`.
2
2
3
- use crate :: fd:: { AsFd , BorrowedFd } ;
4
- use crate :: ffi:: CStr ;
3
+ use crate :: fd:: AsFd ;
5
4
use crate :: fs:: AtFlags ;
6
5
use crate :: { backend, io, path} ;
7
- use core:: sync:: atomic:: { AtomicU8 , Ordering } ;
8
6
9
7
pub use backend:: fs:: types:: { Statx , StatxFlags , StatxTimestamp } ;
10
8
9
+ #[ cfg( feature = "linux_4_11" ) ]
10
+ use backend:: fs:: syscalls:: statx as _statx;
11
+ #[ cfg( not( feature = "linux_4_11" ) ) ]
12
+ use compat:: statx as _statx;
13
+
11
14
/// `statx(dirfd, path, flags, mask, statxbuf)`
12
15
///
13
16
/// This function returns [`io::Errno::NOSYS`] if `statx` is not available on
@@ -29,63 +32,74 @@ pub fn statx<P: path::Arg, Fd: AsFd>(
29
32
path. into_with_c_str ( |path| _statx ( dirfd. as_fd ( ) , path, flags, mask) )
30
33
}
31
34
32
- // Linux kernel prior to 4.11 old versions of Docker don't support `statx`. We
33
- // store the availability in a global to avoid unnecessary syscalls.
34
- //
35
- // 0: Unknown
36
- // 1: Not available
37
- // 2: Available
38
- static STATX_STATE : AtomicU8 = AtomicU8 :: new ( 0 ) ;
35
+ # [ cfg ( not ( feature = "linux_4_11" ) ) ]
36
+ mod compat {
37
+ use crate :: fd :: BorrowedFd ;
38
+ use crate :: ffi :: CStr ;
39
+ use crate :: fs :: AtFlags ;
40
+ use crate :: { backend , io } ;
41
+ use core :: sync :: atomic :: { AtomicU8 , Ordering } ;
39
42
40
- #[ inline]
41
- fn _statx (
42
- dirfd : BorrowedFd < ' _ > ,
43
- path : & CStr ,
44
- flags : AtFlags ,
45
- mask : StatxFlags ,
46
- ) -> io:: Result < Statx > {
47
- match STATX_STATE . load ( Ordering :: Relaxed ) {
48
- 0 => statx_init ( dirfd, path, flags, mask) ,
49
- 1 => Err ( io:: Errno :: NOSYS ) ,
50
- _ => backend:: fs:: syscalls:: statx ( dirfd, path, flags, mask) ,
43
+ use backend:: fs:: types:: { Statx , StatxFlags } ;
44
+
45
+ // Linux kernel prior to 4.11 old versions of Docker don't support `statx`. We
46
+ // store the availability in a global to avoid unnecessary syscalls.
47
+ //
48
+ // 0: Unknown
49
+ // 1: Not available
50
+ // 2: Available
51
+ static STATX_STATE : AtomicU8 = AtomicU8 :: new ( 0 ) ;
52
+
53
+ #[ inline]
54
+ pub fn statx (
55
+ dirfd : BorrowedFd < ' _ > ,
56
+ path : & CStr ,
57
+ flags : AtFlags ,
58
+ mask : StatxFlags ,
59
+ ) -> io:: Result < Statx > {
60
+ match STATX_STATE . load ( Ordering :: Relaxed ) {
61
+ 0 => statx_init ( dirfd, path, flags, mask) ,
62
+ 1 => Err ( io:: Errno :: NOSYS ) ,
63
+ _ => backend:: fs:: syscalls:: statx ( dirfd, path, flags, mask) ,
64
+ }
51
65
}
52
- }
53
66
54
- /// The first `statx` call. We don't know if `statx` is available yet.
55
- fn statx_init (
56
- dirfd : BorrowedFd < ' _ > ,
57
- path : & CStr ,
58
- flags : AtFlags ,
59
- mask : StatxFlags ,
60
- ) -> io:: Result < Statx > {
61
- match backend:: fs:: syscalls:: statx ( dirfd, path, flags, mask) {
62
- Err ( io:: Errno :: NOSYS ) => statx_error_nosys ( ) ,
63
- Err ( io:: Errno :: PERM ) => statx_error_perm ( ) ,
64
- result => {
65
- STATX_STATE . store ( 2 , Ordering :: Relaxed ) ;
66
- result
67
+ /// The first `statx` call. We don't know if `statx` is available yet.
68
+ fn statx_init (
69
+ dirfd : BorrowedFd < ' _ > ,
70
+ path : & CStr ,
71
+ flags : AtFlags ,
72
+ mask : StatxFlags ,
73
+ ) -> io:: Result < Statx > {
74
+ match backend:: fs:: syscalls:: statx ( dirfd, path, flags, mask) {
75
+ Err ( io:: Errno :: NOSYS ) => statx_error_nosys ( ) ,
76
+ Err ( io:: Errno :: PERM ) => statx_error_perm ( ) ,
77
+ result => {
78
+ STATX_STATE . store ( 2 , Ordering :: Relaxed ) ;
79
+ result
80
+ }
67
81
}
68
82
}
69
- }
70
83
71
- /// The first `statx` call failed with `NOSYS` (or something we're treating
72
- /// like `NOSYS`).
73
- #[ cold]
74
- fn statx_error_nosys ( ) -> io:: Result < Statx > {
75
- STATX_STATE . store ( 1 , Ordering :: Relaxed ) ;
76
- Err ( io:: Errno :: NOSYS )
77
- }
84
+ /// The first `statx` call failed with `NOSYS` (or something we're treating
85
+ /// like `NOSYS`).
86
+ #[ cold]
87
+ fn statx_error_nosys ( ) -> io:: Result < Statx > {
88
+ STATX_STATE . store ( 1 , Ordering :: Relaxed ) ;
89
+ Err ( io:: Errno :: NOSYS )
90
+ }
78
91
79
- /// The first `statx` call failed with `PERM`.
80
- #[ cold]
81
- fn statx_error_perm ( ) -> io:: Result < Statx > {
82
- // Some old versions of Docker have `statx` fail with `PERM` when it isn't
83
- // recognized. Check whether `statx` really is available, and if so, fail
84
- // with `PERM`, and if not, treat it like `NOSYS`.
85
- if backend:: fs:: syscalls:: is_statx_available ( ) {
86
- STATX_STATE . store ( 2 , Ordering :: Relaxed ) ;
87
- Err ( io:: Errno :: PERM )
88
- } else {
89
- statx_error_nosys ( )
92
+ /// The first `statx` call failed with `PERM`.
93
+ #[ cold]
94
+ fn statx_error_perm ( ) -> io:: Result < Statx > {
95
+ // Some old versions of Docker have `statx` fail with `PERM` when it isn't
96
+ // recognized. Check whether `statx` really is available, and if so, fail
97
+ // with `PERM`, and if not, treat it like `NOSYS`.
98
+ if backend:: fs:: syscalls:: is_statx_available ( ) {
99
+ STATX_STATE . store ( 2 , Ordering :: Relaxed ) ;
100
+ Err ( io:: Errno :: PERM )
101
+ } else {
102
+ statx_error_nosys ( )
103
+ }
90
104
}
91
105
}
0 commit comments