@@ -14,6 +14,7 @@ use crate::{
1414 bindings, c_types,
1515 error:: { Error , KernelResult } ,
1616 io_buffer:: { IoBufferReader , IoBufferWriter } ,
17+ iov_iter:: IovIter ,
1718 sync:: { CondVar , Ref , RefCounted } ,
1819 user_ptr:: { UserSlicePtr , UserSlicePtrReader , UserSlicePtrWriter } ,
1920} ;
@@ -157,6 +158,21 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
157158 }
158159}
159160
161+ unsafe extern "C" fn read_iter_callback < T : FileOperations > (
162+ iocb : * mut bindings:: kiocb ,
163+ raw_iter : * mut bindings:: iov_iter ,
164+ ) -> isize {
165+ from_kernel_result ! {
166+ let mut iter = IovIter :: from_ptr( raw_iter) ;
167+ let file = ( * iocb) . ki_filp;
168+ let offset = ( * iocb) . ki_pos;
169+ let f = & * ( ( * file) . private_data as * const T ) ;
170+ let read = f. read( & File :: from_ptr( file) , & mut iter, offset. try_into( ) ?) ?;
171+ ( * iocb) . ki_pos += bindings:: loff_t:: try_from( read) . unwrap( ) ;
172+ Ok ( read as _)
173+ }
174+ }
175+
160176unsafe extern "C" fn write_callback < T : FileOperations > (
161177 file : * mut bindings:: file ,
162178 buf : * const c_types:: c_char ,
@@ -174,6 +190,21 @@ unsafe extern "C" fn write_callback<T: FileOperations>(
174190 }
175191}
176192
193+ unsafe extern "C" fn write_iter_callback < T : FileOperations > (
194+ iocb : * mut bindings:: kiocb ,
195+ raw_iter : * mut bindings:: iov_iter ,
196+ ) -> isize {
197+ from_kernel_result ! {
198+ let mut iter = IovIter :: from_ptr( raw_iter) ;
199+ let file = ( * iocb) . ki_filp;
200+ let offset = ( * iocb) . ki_pos;
201+ let f = & * ( ( * file) . private_data as * const T ) ;
202+ let written = f. write( & File :: from_ptr( file) , & mut iter, offset. try_into( ) ?) ?;
203+ ( * iocb) . ki_pos += bindings:: loff_t:: try_from( written) . unwrap( ) ;
204+ Ok ( written as _)
205+ }
206+ }
207+
177208unsafe extern "C" fn release_callback < T : FileOperations > (
178209 _inode : * mut bindings:: inode ,
179210 file : * mut bindings:: file ,
@@ -323,7 +354,11 @@ impl<A: FileOpenAdapter, T: FileOpener<A::Arg>> FileOperationsVtable<A, T> {
323354 } else {
324355 None
325356 } ,
326- read_iter : None ,
357+ read_iter : if T :: TO_USE . read_iter {
358+ Some ( read_iter_callback :: < T > )
359+ } else {
360+ None
361+ } ,
327362 remap_file_range : None ,
328363 sendpage : None ,
329364 setlease : None ,
@@ -335,7 +370,11 @@ impl<A: FileOpenAdapter, T: FileOpener<A::Arg>> FileOperationsVtable<A, T> {
335370 } else {
336371 None
337372 } ,
338- write_iter : None ,
373+ write_iter : if T :: TO_USE . write_iter {
374+ Some ( write_iter_callback :: < T > )
375+ } else {
376+ None
377+ } ,
339378 } ;
340379
341380 /// Builds an instance of [`struct file_operations`].
@@ -353,9 +392,15 @@ pub struct ToUse {
353392 /// The `read` field of [`struct file_operations`].
354393 pub read : bool ,
355394
395+ /// The `read_iter` field of [`struct file_operations`].
396+ pub read_iter : bool ,
397+
356398 /// The `write` field of [`struct file_operations`].
357399 pub write : bool ,
358400
401+ /// The `write_iter` field of [`struct file_operations`].
402+ pub write_iter : bool ,
403+
359404 /// The `llseek` field of [`struct file_operations`].
360405 pub seek : bool ,
361406
@@ -379,7 +424,9 @@ pub struct ToUse {
379424/// be set to null pointers.
380425pub const USE_NONE : ToUse = ToUse {
381426 read : false ,
427+ read_iter : false ,
382428 write : false ,
429+ write_iter : false ,
383430 seek : false ,
384431 ioctl : false ,
385432 compat_ioctl : false ,
0 commit comments