@@ -41,16 +41,34 @@ pub enum SeekFrom {
41
41
Current ( i64 ) ,
42
42
}
43
43
44
+ fn from_kernel_result < T > ( r : KernelResult < T > ) -> T
45
+ where
46
+ T : TryFrom < c_types:: c_int > ,
47
+ T :: Error : core:: fmt:: Debug ,
48
+ {
49
+ match r {
50
+ Ok ( v) => v,
51
+ Err ( e) => T :: try_from ( e. to_kernel_errno ( ) ) . unwrap ( ) ,
52
+ }
53
+ }
54
+
55
+ macro_rules! from_kernel_result {
56
+ ( $( $tt: tt) * ) => { {
57
+ from_kernel_result( ( || {
58
+ $( $tt) *
59
+ } ) ( ) )
60
+ } } ;
61
+ }
62
+
44
63
unsafe extern "C" fn open_callback < T : FileOperations > (
45
64
_inode : * mut bindings:: inode ,
46
65
file : * mut bindings:: file ,
47
66
) -> c_types:: c_int {
48
- let f = match T :: open ( ) {
49
- Ok ( f) => Box :: new ( f) ,
50
- Err ( e) => return e. to_kernel_errno ( ) ,
51
- } ;
52
- ( * file) . private_data = Box :: into_raw ( f) as * mut c_types:: c_void ;
53
- 0
67
+ from_kernel_result ! {
68
+ let f = Box :: new( T :: open( ) ?) ;
69
+ ( * file) . private_data = Box :: into_raw( f) as * mut c_types:: c_void;
70
+ Ok ( 0 )
71
+ }
54
72
}
55
73
56
74
unsafe extern "C" fn read_callback < T : FileOperations > (
@@ -59,25 +77,15 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
59
77
len : c_types:: c_size_t ,
60
78
offset : * mut bindings:: loff_t ,
61
79
) -> c_types:: c_ssize_t {
62
- let mut data = match UserSlicePtr :: new ( buf as * mut c_types:: c_void , len) {
63
- Ok ( ptr) => ptr. writer ( ) ,
64
- Err ( e) => return e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
65
- } ;
66
- let f = & * ( ( * file) . private_data as * const T ) ;
67
- // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
68
- // See discussion in #113
69
- let positive_offset = match ( * offset) . try_into ( ) {
70
- Ok ( v) => v,
71
- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
72
- } ;
73
- let read = T :: READ . unwrap ( ) ;
74
- match read ( f, & File :: from_ptr ( file) , & mut data, positive_offset) {
75
- Ok ( ( ) ) => {
76
- let written = len - data. len ( ) ;
77
- ( * offset) += bindings:: loff_t:: try_from ( written) . unwrap ( ) ;
78
- written. try_into ( ) . unwrap ( )
79
- }
80
- Err ( e) => e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
80
+ from_kernel_result ! {
81
+ let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) ?. writer( ) ;
82
+ let f = & * ( ( * file) . private_data as * const T ) ;
83
+ // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
84
+ // See discussion in #113
85
+ T :: READ . unwrap( ) ( f, & File :: from_ptr( file) , & mut data, ( * offset) . try_into( ) ?) ?;
86
+ let written = len - data. len( ) ;
87
+ ( * offset) += bindings:: loff_t:: try_from( written) . unwrap( ) ;
88
+ Ok ( written. try_into( ) . unwrap( ) )
81
89
}
82
90
}
83
91
@@ -87,25 +95,15 @@ unsafe extern "C" fn write_callback<T: FileOperations>(
87
95
len : c_types:: c_size_t ,
88
96
offset : * mut bindings:: loff_t ,
89
97
) -> c_types:: c_ssize_t {
90
- let mut data = match UserSlicePtr :: new ( buf as * mut c_types:: c_void , len) {
91
- Ok ( ptr) => ptr. reader ( ) ,
92
- Err ( e) => return e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
93
- } ;
94
- let f = & * ( ( * file) . private_data as * const T ) ;
95
- // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
96
- // See discussion in #113
97
- let positive_offset = match ( * offset) . try_into ( ) {
98
- Ok ( v) => v,
99
- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
100
- } ;
101
- let write = T :: WRITE . unwrap ( ) ;
102
- match write ( f, & mut data, positive_offset) {
103
- Ok ( ( ) ) => {
104
- let read = len - data. len ( ) ;
105
- ( * offset) += bindings:: loff_t:: try_from ( read) . unwrap ( ) ;
106
- read. try_into ( ) . unwrap ( )
107
- }
108
- Err ( e) => e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
98
+ from_kernel_result ! {
99
+ let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) ?. reader( ) ;
100
+ let f = & * ( ( * file) . private_data as * const T ) ;
101
+ // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
102
+ // See discussion in #113
103
+ T :: WRITE . unwrap( ) ( f, & mut data, ( * offset) . try_into( ) ?) ?;
104
+ let read = len - data. len( ) ;
105
+ ( * offset) += bindings:: loff_t:: try_from( read) . unwrap( ) ;
106
+ Ok ( read. try_into( ) . unwrap( ) )
109
107
}
110
108
}
111
109
@@ -123,20 +121,16 @@ unsafe extern "C" fn llseek_callback<T: FileOperations>(
123
121
offset : bindings:: loff_t ,
124
122
whence : c_types:: c_int ,
125
123
) -> bindings:: loff_t {
126
- let off = match whence as u32 {
127
- bindings:: SEEK_SET => match offset. try_into ( ) {
128
- Ok ( v) => SeekFrom :: Start ( v) ,
129
- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . into ( ) ,
130
- } ,
131
- bindings:: SEEK_CUR => SeekFrom :: Current ( offset) ,
132
- bindings:: SEEK_END => SeekFrom :: End ( offset) ,
133
- _ => return Error :: EINVAL . to_kernel_errno ( ) . into ( ) ,
134
- } ;
135
- let f = & * ( ( * file) . private_data as * const T ) ;
136
- let seek = T :: SEEK . unwrap ( ) ;
137
- match seek ( f, & File :: from_ptr ( file) , off) {
138
- Ok ( off) => off as bindings:: loff_t ,
139
- Err ( e) => e. to_kernel_errno ( ) . into ( ) ,
124
+ from_kernel_result ! {
125
+ let off = match whence as u32 {
126
+ bindings:: SEEK_SET => SeekFrom :: Start ( offset. try_into( ) ?) ,
127
+ bindings:: SEEK_CUR => SeekFrom :: Current ( offset) ,
128
+ bindings:: SEEK_END => SeekFrom :: End ( offset) ,
129
+ _ => return Err ( Error :: EINVAL ) ,
130
+ } ;
131
+ let f = & * ( ( * file) . private_data as * const T ) ;
132
+ let off = T :: SEEK . unwrap( ) ( f, & File :: from_ptr( file) , off) ?;
133
+ Ok ( off as bindings:: loff_t)
140
134
}
141
135
}
142
136
@@ -146,20 +140,13 @@ unsafe extern "C" fn fsync_callback<T: FileOperations>(
146
140
end : bindings:: loff_t ,
147
141
datasync : c_types:: c_int ,
148
142
) -> c_types:: c_int {
149
- let start = match start. try_into ( ) {
150
- Ok ( v) => v,
151
- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) ,
152
- } ;
153
- let end = match end. try_into ( ) {
154
- Ok ( v) => v,
155
- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) ,
156
- } ;
157
- let datasync = datasync != 0 ;
158
- let fsync = T :: FSYNC . unwrap ( ) ;
159
- let f = & * ( ( * file) . private_data as * const T ) ;
160
- match fsync ( f, & File :: from_ptr ( file) , start, end, datasync) {
161
- Ok ( result) => result. try_into ( ) . unwrap ( ) ,
162
- Err ( e) => e. to_kernel_errno ( ) ,
143
+ from_kernel_result ! {
144
+ let start = start. try_into( ) ?;
145
+ let end = end. try_into( ) ?;
146
+ let datasync = datasync != 0 ;
147
+ let f = & * ( ( * file) . private_data as * const T ) ;
148
+ let res = T :: FSYNC . unwrap( ) ( f, & File :: from_ptr( file) , start, end, datasync) ?;
149
+ Ok ( res. try_into( ) . unwrap( ) )
163
150
}
164
151
}
165
152
0 commit comments