@@ -96,6 +96,27 @@ impl Drop for Registration {
96
96
}
97
97
}
98
98
99
+ pub struct File {
100
+ ptr : * const bindings:: file ,
101
+ }
102
+
103
+ impl File {
104
+ unsafe fn from_ptr ( ptr : * const bindings:: file ) -> File {
105
+ File { ptr }
106
+ }
107
+
108
+ pub fn pos ( & self ) -> u64 {
109
+ unsafe { ( * self . ptr ) . f_pos as u64 }
110
+ }
111
+ }
112
+
113
+ // Matches std::io::SeekFrom in the Rust stdlib
114
+ pub enum SeekFrom {
115
+ Start ( u64 ) ,
116
+ End ( i64 ) ,
117
+ Current ( i64 ) ,
118
+ }
119
+
99
120
pub struct FileOperationsVtable ( bindings:: file_operations ) ;
100
121
101
122
unsafe extern "C" fn open_callback < T : FileOperations > (
@@ -141,12 +162,34 @@ unsafe extern "C" fn release_callback<T: FileOperations>(
141
162
0
142
163
}
143
164
165
+ unsafe extern "C" fn llseek_callback < T : FileOperations > (
166
+ file : * mut bindings:: file ,
167
+ offset : bindings:: loff_t ,
168
+ whence : c_types:: c_int ,
169
+ ) -> bindings:: loff_t {
170
+ let off = match whence as u32 {
171
+ bindings:: SEEK_SET => match offset. try_into ( ) {
172
+ Ok ( v) => SeekFrom :: Start ( v) ,
173
+ Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . into ( ) ,
174
+ } ,
175
+ bindings:: SEEK_CUR => SeekFrom :: Current ( offset) ,
176
+ bindings:: SEEK_END => SeekFrom :: End ( offset) ,
177
+ _ => return Error :: EINVAL . to_kernel_errno ( ) . into ( ) ,
178
+ } ;
179
+ let f = & * ( ( * file) . private_data as * const T ) ;
180
+ match f. seek ( & File :: from_ptr ( file) , off) {
181
+ Ok ( off) => off as bindings:: loff_t ,
182
+ Err ( e) => e. to_kernel_errno ( ) . into ( ) ,
183
+ }
184
+ }
185
+
144
186
impl FileOperationsVtable {
145
187
pub const fn new < T : FileOperations > ( ) -> FileOperationsVtable {
146
188
FileOperationsVtable ( bindings:: file_operations {
147
189
open : Some ( open_callback :: < T > ) ,
148
190
read : Some ( read_callback :: < T > ) ,
149
191
release : Some ( release_callback :: < T > ) ,
192
+ llseek : Some ( llseek_callback :: < T > ) ,
150
193
151
194
check_flags : None ,
152
195
#[ cfg( not( kernel_4_20_0_or_greater) ) ]
@@ -167,7 +210,6 @@ impl FileOperationsVtable {
167
210
iterate_shared : None ,
168
211
#[ cfg( kernel_5_1_0_or_greater) ]
169
212
iopoll : None ,
170
- llseek : None ,
171
213
lock : None ,
172
214
mmap : None ,
173
215
#[ cfg( kernel_4_15_0_or_greater) ]
@@ -194,5 +236,10 @@ pub trait FileOperations: Sync + Sized {
194
236
const VTABLE : FileOperationsVtable ;
195
237
196
238
fn open ( ) -> KernelResult < Self > ;
197
- fn read ( & self , buf : & mut UserSlicePtrWriter ) -> KernelResult < ( ) > ;
239
+ fn read ( & self , _buf : & mut UserSlicePtrWriter ) -> KernelResult < ( ) > {
240
+ Err ( Error :: EINVAL )
241
+ }
242
+ fn seek ( & self , _file : & File , _offset : SeekFrom ) -> KernelResult < u64 > {
243
+ Err ( Error :: ESPIPE )
244
+ }
198
245
}
0 commit comments