@@ -15,6 +15,7 @@ use crate::c_types;
1515use crate :: error:: { Error , KernelResult } ;
1616use crate :: sync:: { Ref , RefCounted } ;
1717use crate :: user_ptr:: { UserSlicePtr , UserSlicePtrReader , UserSlicePtrWriter } ;
18+ pub use file_operations_struct:: build_file_operations;
1819
1920/// Wraps the kernel's `struct file`.
2021///
@@ -201,68 +202,82 @@ unsafe extern "C" fn fsync_callback<T: FileOperations>(
201202 }
202203}
203204
204- pub ( crate ) struct FileOperationsVtable < A , T > ( marker:: PhantomData < A > , marker:: PhantomData < T > ) ;
205-
206- impl < A : FileOpenAdapter , T : FileOpener < A :: Arg > > FileOperationsVtable < A , T > {
207- pub ( crate ) const VTABLE : bindings:: file_operations = bindings:: file_operations {
208- open : Some ( open_callback :: < A , T > ) ,
209- release : Some ( release_callback :: < T > ) ,
210- read : if T :: TO_USE . read {
211- Some ( read_callback :: < T > )
212- } else {
213- None
214- } ,
215- write : if T :: TO_USE . write {
216- Some ( write_callback :: < T > )
217- } else {
218- None
219- } ,
220- llseek : if T :: TO_USE . seek {
221- Some ( llseek_callback :: < T > )
222- } else {
223- None
224- } ,
225-
226- check_flags : None ,
227- compat_ioctl : if T :: TO_USE . compat_ioctl {
228- Some ( compat_ioctl_callback :: < T > )
229- } else {
230- None
231- } ,
232- copy_file_range : None ,
233- fallocate : None ,
234- fadvise : None ,
235- fasync : None ,
236- flock : None ,
237- flush : None ,
238- fsync : if T :: TO_USE . fsync {
239- Some ( fsync_callback :: < T > )
240- } else {
241- None
242- } ,
243- get_unmapped_area : None ,
244- iterate : None ,
245- iterate_shared : None ,
246- iopoll : None ,
247- lock : None ,
248- mmap : None ,
249- mmap_supported_flags : 0 ,
250- owner : ptr:: null_mut ( ) ,
251- poll : None ,
252- read_iter : None ,
253- remap_file_range : None ,
254- sendpage : None ,
255- setlease : None ,
256- show_fdinfo : None ,
257- splice_read : None ,
258- splice_write : None ,
259- unlocked_ioctl : if T :: TO_USE . ioctl {
260- Some ( unlocked_ioctl_callback :: < T > )
261- } else {
262- None
263- } ,
264- write_iter : None ,
265- } ;
205+ mod file_operations_struct {
206+ use super :: * ;
207+
208+ struct FileOperationsVtable < A , T > ( marker:: PhantomData < A > , marker:: PhantomData < T > ) ;
209+
210+ impl < A : FileOpenAdapter , T : FileOpener < A :: Arg > > FileOperationsVtable < A , T > {
211+ const VTABLE : bindings:: file_operations = bindings:: file_operations {
212+ open : Some ( open_callback :: < A , T > ) ,
213+ release : Some ( release_callback :: < T > ) ,
214+ read : if T :: TO_USE . read {
215+ Some ( read_callback :: < T > )
216+ } else {
217+ None
218+ } ,
219+ write : if T :: TO_USE . write {
220+ Some ( write_callback :: < T > )
221+ } else {
222+ None
223+ } ,
224+ llseek : if T :: TO_USE . seek {
225+ Some ( llseek_callback :: < T > )
226+ } else {
227+ None
228+ } ,
229+
230+ check_flags : None ,
231+ compat_ioctl : if T :: TO_USE . compat_ioctl {
232+ Some ( compat_ioctl_callback :: < T > )
233+ } else {
234+ None
235+ } ,
236+ copy_file_range : None ,
237+ fallocate : None ,
238+ fadvise : None ,
239+ fasync : None ,
240+ flock : None ,
241+ flush : None ,
242+ fsync : if T :: TO_USE . fsync {
243+ Some ( fsync_callback :: < T > )
244+ } else {
245+ None
246+ } ,
247+ get_unmapped_area : None ,
248+ iterate : None ,
249+ iterate_shared : None ,
250+ iopoll : None ,
251+ lock : None ,
252+ mmap : None ,
253+ mmap_supported_flags : 0 ,
254+ owner : ptr:: null_mut ( ) ,
255+ poll : None ,
256+ read_iter : None ,
257+ remap_file_range : None ,
258+ sendpage : None ,
259+ setlease : None ,
260+ show_fdinfo : None ,
261+ splice_read : None ,
262+ splice_write : None ,
263+ unlocked_ioctl : if T :: TO_USE . ioctl {
264+ Some ( unlocked_ioctl_callback :: < T > )
265+ } else {
266+ None
267+ } ,
268+ write_iter : None ,
269+ } ;
270+ }
271+
272+ /// Builds an instance of the [`struct file_operations`] for the given file adapter and opener.
273+ ///
274+ /// # Safety
275+ ///
276+ /// The caller must ensure that the adapter is compatible with the way the device is registered.
277+ pub const unsafe fn build_file_operations < A : FileOpenAdapter , T : FileOpener < A :: Arg > > (
278+ ) -> & ' static bindings:: file_operations {
279+ & FileOperationsVtable :: < A , T > :: VTABLE
280+ }
266281}
267282
268283/// Represents which fields of [`struct file_operations`] should be populated with pointers.
0 commit comments