@@ -140,6 +140,29 @@ unsafe extern "C" fn llseek_callback<T: FileOperations>(
140
140
}
141
141
}
142
142
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
+
143
166
pub ( crate ) struct FileOperationsVtable < T > ( marker:: PhantomData < T > ) ;
144
167
145
168
impl < T : FileOperations > FileOperationsVtable < T > {
@@ -170,7 +193,11 @@ impl<T: FileOperations> FileOperationsVtable<T> {
170
193
fasync : None ,
171
194
flock : None ,
172
195
flush : None ,
173
- fsync : None ,
196
+ fsync : if let Some ( _) = T :: FSYNC {
197
+ Some ( fsync_callback :: < T > )
198
+ } else {
199
+ None
200
+ } ,
174
201
get_unmapped_area : None ,
175
202
iterate : None ,
176
203
iterate_shared : None ,
@@ -195,6 +222,7 @@ impl<T: FileOperations> FileOperationsVtable<T> {
195
222
pub type ReadFn < T > = Option < fn ( & T , & File , & mut UserSlicePtrWriter , u64 ) -> KernelResult < ( ) > > ;
196
223
pub type WriteFn < T > = Option < fn ( & T , & mut UserSlicePtrReader , u64 ) -> KernelResult < ( ) > > ;
197
224
pub type SeekFn < T > = Option < fn ( & T , & File , SeekFrom ) -> KernelResult < u64 > > ;
225
+ pub type FSync < T > = Option < fn ( & T , & File , u64 , u64 , bool ) -> KernelResult < u32 > > ;
198
226
199
227
/// `FileOperations` corresponds to the kernel's `struct file_operations`. You
200
228
/// implement this trait whenever you'd create a `struct file_operations`.
@@ -216,4 +244,8 @@ pub trait FileOperations: Sync + Sized {
216
244
/// Changes the position of the file. Corresponds to the `llseek` function
217
245
/// pointer in `struct file_operations`.
218
246
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 ;
219
251
}
0 commit comments