@@ -41,16 +41,34 @@ pub enum SeekFrom {
4141 Current ( i64 ) ,
4242}
4343
44+ fn from_kernel_result < T > ( r : KernelResult < T > ) -> T
45+ where
46+ T : TryFrom < c_types:: c_int > ,
47+ T :: Error : core:: fmt:: Debug ,
48+ {
49+ match r {
50+ Ok ( v) => v,
51+ Err ( e) => T :: try_from ( e. to_kernel_errno ( ) ) . unwrap ( ) ,
52+ }
53+ }
54+
55+ macro_rules! from_kernel_result {
56+ ( $( $tt: tt) * ) => { {
57+ from_kernel_result( ( || {
58+ $( $tt) *
59+ } ) ( ) )
60+ } } ;
61+ }
62+
4463unsafe extern "C" fn open_callback < T : FileOperations > (
4564 _inode : * mut bindings:: inode ,
4665 file : * mut bindings:: file ,
4766) -> c_types:: c_int {
48- let f = match T :: open ( ) {
49- Ok ( f) => Box :: new ( f) ,
50- Err ( e) => return e. to_kernel_errno ( ) ,
51- } ;
52- ( * file) . private_data = Box :: into_raw ( f) as * mut c_types:: c_void ;
53- 0
67+ from_kernel_result ! {
68+ let f = Box :: new( T :: open( ) ?) ;
69+ ( * file) . private_data = Box :: into_raw( f) as * mut c_types:: c_void;
70+ Ok ( 0 )
71+ }
5472}
5573
5674unsafe extern "C" fn read_callback < T : FileOperations > (
@@ -59,25 +77,15 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
5977 len : c_types:: c_size_t ,
6078 offset : * mut bindings:: loff_t ,
6179) -> c_types:: c_ssize_t {
62- let mut data = match UserSlicePtr :: new ( buf as * mut c_types:: c_void , len) {
63- Ok ( ptr) => ptr. writer ( ) ,
64- Err ( e) => return e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
65- } ;
66- let f = & * ( ( * file) . private_data as * const T ) ;
67- // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
68- // See discussion in #113
69- let positive_offset = match ( * offset) . try_into ( ) {
70- Ok ( v) => v,
71- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
72- } ;
73- let read = T :: READ . unwrap ( ) ;
74- match read ( f, & File :: from_ptr ( file) , & mut data, positive_offset) {
75- Ok ( ( ) ) => {
76- let written = len - data. len ( ) ;
77- ( * offset) += bindings:: loff_t:: try_from ( written) . unwrap ( ) ;
78- written. try_into ( ) . unwrap ( )
79- }
80- Err ( e) => e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
80+ from_kernel_result ! {
81+ let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) ?. writer( ) ;
82+ let f = & * ( ( * file) . private_data as * const T ) ;
83+ // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
84+ // See discussion in #113
85+ T :: READ . unwrap( ) ( f, & File :: from_ptr( file) , & mut data, ( * offset) . try_into( ) ?) ?;
86+ let written = len - data. len( ) ;
87+ ( * offset) += bindings:: loff_t:: try_from( written) . unwrap( ) ;
88+ Ok ( written. try_into( ) . unwrap( ) )
8189 }
8290}
8391
@@ -87,25 +95,15 @@ unsafe extern "C" fn write_callback<T: FileOperations>(
8795 len : c_types:: c_size_t ,
8896 offset : * mut bindings:: loff_t ,
8997) -> c_types:: c_ssize_t {
90- let mut data = match UserSlicePtr :: new ( buf as * mut c_types:: c_void , len) {
91- Ok ( ptr) => ptr. reader ( ) ,
92- Err ( e) => return e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
93- } ;
94- let f = & * ( ( * file) . private_data as * const T ) ;
95- // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
96- // See discussion in #113
97- let positive_offset = match ( * offset) . try_into ( ) {
98- Ok ( v) => v,
99- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
100- } ;
101- let write = T :: WRITE . unwrap ( ) ;
102- match write ( f, & mut data, positive_offset) {
103- Ok ( ( ) ) => {
104- let read = len - data. len ( ) ;
105- ( * offset) += bindings:: loff_t:: try_from ( read) . unwrap ( ) ;
106- read. try_into ( ) . unwrap ( )
107- }
108- Err ( e) => e. to_kernel_errno ( ) . try_into ( ) . unwrap ( ) ,
98+ from_kernel_result ! {
99+ let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) ?. reader( ) ;
100+ let f = & * ( ( * file) . private_data as * const T ) ;
101+ // No FMODE_UNSIGNED_OFFSET support, so offset must be in [0, 2^63).
102+ // See discussion in #113
103+ T :: WRITE . unwrap( ) ( f, & mut data, ( * offset) . try_into( ) ?) ?;
104+ let read = len - data. len( ) ;
105+ ( * offset) += bindings:: loff_t:: try_from( read) . unwrap( ) ;
106+ Ok ( read. try_into( ) . unwrap( ) )
109107 }
110108}
111109
@@ -123,20 +121,16 @@ unsafe extern "C" fn llseek_callback<T: FileOperations>(
123121 offset : bindings:: loff_t ,
124122 whence : c_types:: c_int ,
125123) -> bindings:: loff_t {
126- let off = match whence as u32 {
127- bindings:: SEEK_SET => match offset. try_into ( ) {
128- Ok ( v) => SeekFrom :: Start ( v) ,
129- Err ( _) => return Error :: EINVAL . to_kernel_errno ( ) . into ( ) ,
130- } ,
131- bindings:: SEEK_CUR => SeekFrom :: Current ( offset) ,
132- bindings:: SEEK_END => SeekFrom :: End ( offset) ,
133- _ => return Error :: EINVAL . to_kernel_errno ( ) . into ( ) ,
134- } ;
135- let f = & * ( ( * file) . private_data as * const T ) ;
136- let seek = T :: SEEK . unwrap ( ) ;
137- match seek ( f, & File :: from_ptr ( file) , off) {
138- Ok ( off) => off as bindings:: loff_t ,
139- Err ( e) => e. to_kernel_errno ( ) . into ( ) ,
124+ from_kernel_result ! {
125+ let off = match whence as u32 {
126+ bindings:: SEEK_SET => SeekFrom :: Start ( offset. try_into( ) ?) ,
127+ bindings:: SEEK_CUR => SeekFrom :: Current ( offset) ,
128+ bindings:: SEEK_END => SeekFrom :: End ( offset) ,
129+ _ => return Err ( Error :: EINVAL ) ,
130+ } ;
131+ let f = & * ( ( * file) . private_data as * const T ) ;
132+ let off = T :: SEEK . unwrap( ) ( f, & File :: from_ptr( file) , off) ?;
133+ Ok ( off as bindings:: loff_t)
140134 }
141135}
142136
@@ -146,20 +140,13 @@ unsafe extern "C" fn fsync_callback<T: FileOperations>(
146140 end : bindings:: loff_t ,
147141 datasync : c_types:: c_int ,
148142) -> 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 ( ) ,
143+ from_kernel_result ! {
144+ let start = start. try_into( ) ?;
145+ let end = end. try_into( ) ?;
146+ let datasync = datasync != 0 ;
147+ let f = & * ( ( * file) . private_data as * const T ) ;
148+ let res = T :: FSYNC . unwrap( ) ( f, & File :: from_ptr( file) , start, end, datasync) ?;
149+ Ok ( res. try_into( ) . unwrap( ) )
163150 }
164151}
165152
0 commit comments