@@ -96,6 +96,27 @@ impl Drop for Registration {
9696 }
9797}
9898
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+
99120pub struct FileOperationsVtable ( bindings:: file_operations ) ;
100121
101122unsafe extern "C" fn open_callback < T : FileOperations > (
@@ -141,12 +162,34 @@ unsafe extern "C" fn release_callback<T: FileOperations>(
141162 0
142163}
143164
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+
144186impl FileOperationsVtable {
145187 pub const fn new < T : FileOperations > ( ) -> FileOperationsVtable {
146188 FileOperationsVtable ( bindings:: file_operations {
147189 open : Some ( open_callback :: < T > ) ,
148190 read : Some ( read_callback :: < T > ) ,
149191 release : Some ( release_callback :: < T > ) ,
192+ llseek : Some ( llseek_callback :: < T > ) ,
150193
151194 check_flags : None ,
152195 #[ cfg( not( kernel_4_20_0_or_greater) ) ]
@@ -167,7 +210,6 @@ impl FileOperationsVtable {
167210 iterate_shared : None ,
168211 #[ cfg( kernel_5_1_0_or_greater) ]
169212 iopoll : None ,
170- llseek : None ,
171213 lock : None ,
172214 mmap : None ,
173215 #[ cfg( kernel_4_15_0_or_greater) ]
@@ -194,5 +236,10 @@ pub trait FileOperations: Sync + Sized {
194236 const VTABLE : FileOperationsVtable ;
195237
196238 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+ }
198245}
0 commit comments