@@ -140,6 +140,29 @@ unsafe extern "C" fn llseek_callback<T: FileOperations>(
140140 }
141141}
142142
143+ unsafe extern "C" fn fsync_callback < T : FileOperations > (
144+ file : * mut bindings:: file ,
145+ start : bindings:: loff_t ,
146+ end : bindings:: loff_t ,
147+ datasync : c_types:: c_int ,
148+ ) -> 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 ( ) ,
163+ }
164+ }
165+
143166pub ( crate ) struct FileOperationsVtable < T > ( marker:: PhantomData < T > ) ;
144167
145168impl < T : FileOperations > FileOperationsVtable < T > {
@@ -170,7 +193,11 @@ impl<T: FileOperations> FileOperationsVtable<T> {
170193 fasync : None ,
171194 flock : None ,
172195 flush : None ,
173- fsync : None ,
196+ fsync : if let Some ( _) = T :: FSYNC {
197+ Some ( fsync_callback :: < T > )
198+ } else {
199+ None
200+ } ,
174201 get_unmapped_area : None ,
175202 iterate : None ,
176203 iterate_shared : None ,
@@ -195,6 +222,7 @@ impl<T: FileOperations> FileOperationsVtable<T> {
195222pub type ReadFn < T > = Option < fn ( & T , & File , & mut UserSlicePtrWriter , u64 ) -> KernelResult < ( ) > > ;
196223pub type WriteFn < T > = Option < fn ( & T , & mut UserSlicePtrReader , u64 ) -> KernelResult < ( ) > > ;
197224pub type SeekFn < T > = Option < fn ( & T , & File , SeekFrom ) -> KernelResult < u64 > > ;
225+ pub type FSync < T > = Option < fn ( & T , & File , u64 , u64 , bool ) -> KernelResult < u32 > > ;
198226
199227/// `FileOperations` corresponds to the kernel's `struct file_operations`. You
200228/// implement this trait whenever you'd create a `struct file_operations`.
@@ -216,4 +244,8 @@ pub trait FileOperations: Sync + Sized {
216244 /// Changes the position of the file. Corresponds to the `llseek` function
217245 /// pointer in `struct file_operations`.
218246 const SEEK : SeekFn < Self > = None ;
247+
248+ /// Syncs pending changes to this file. Corresponds to the `fsync` function
249+ /// pointer in the `struct file_operations`.
250+ const FSYNC : FSync < Self > = None ;
219251}
0 commit comments