Skip to content

Commit d765c5e

Browse files
author
Roni Nevalainen
committed
Initialize field owner in file_operations
Initialized the field `owner` in struct `file_operations`. It's used to increment the module ref count when a file is opened, to prevent the module from being unloaded. Fixes the issue #214 Signed-off-by: Roni Nevalainen <[email protected]>
1 parent d4bf48b commit d765c5e

File tree

3 files changed

+71
-72
lines changed

3 files changed

+71
-72
lines changed

rust/kernel/chrdev.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<const N: usize> Registration<{ N }> {
116116
cdev,
117117
// SAFETY: The adapter doesn't retrieve any state yet, so it's compatible with any
118118
// registration.
119-
file_operations::FileOperationsVtable::<Self, T>::build(),
119+
&file_operations::FileOperationsVtable::<Self, T>::build(&mut bindings::__this_module),
120120
);
121121
(*cdev).owner = this.this_module.0;
122122
let rc = bindings::cdev_add(cdev, inner.dev + inner.used as bindings::dev_t, 1);

rust/kernel/file_operations.rs

Lines changed: 69 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -268,81 +268,80 @@ unsafe extern "C" fn poll_callback<T: FileOperations>(
268268
pub(crate) struct FileOperationsVtable<A, T>(marker::PhantomData<A>, marker::PhantomData<T>);
269269

270270
impl<A: FileOpenAdapter, T: FileOpener<A::Arg>> FileOperationsVtable<A, T> {
271-
const VTABLE: bindings::file_operations = bindings::file_operations {
272-
open: Some(open_callback::<A, T>),
273-
release: Some(release_callback::<T>),
274-
read: if T::TO_USE.read {
275-
Some(read_callback::<T>)
276-
} else {
277-
None
278-
},
279-
write: if T::TO_USE.write {
280-
Some(write_callback::<T>)
281-
} else {
282-
None
283-
},
284-
llseek: if T::TO_USE.seek {
285-
Some(llseek_callback::<T>)
286-
} else {
287-
None
288-
},
289-
290-
check_flags: None,
291-
compat_ioctl: if T::TO_USE.compat_ioctl {
292-
Some(compat_ioctl_callback::<T>)
293-
} else {
294-
None
295-
},
296-
copy_file_range: None,
297-
fallocate: None,
298-
fadvise: None,
299-
fasync: None,
300-
flock: None,
301-
flush: None,
302-
fsync: if T::TO_USE.fsync {
303-
Some(fsync_callback::<T>)
304-
} else {
305-
None
306-
},
307-
get_unmapped_area: None,
308-
iterate: None,
309-
iterate_shared: None,
310-
iopoll: None,
311-
lock: None,
312-
mmap: if T::TO_USE.mmap {
313-
Some(mmap_callback::<T>)
314-
} else {
315-
None
316-
},
317-
mmap_supported_flags: 0,
318-
owner: ptr::null_mut(),
319-
poll: if T::TO_USE.poll {
320-
Some(poll_callback::<T>)
321-
} else {
322-
None
323-
},
324-
read_iter: None,
325-
remap_file_range: None,
326-
sendpage: None,
327-
setlease: None,
328-
show_fdinfo: None,
329-
splice_read: None,
330-
splice_write: None,
331-
unlocked_ioctl: if T::TO_USE.ioctl {
332-
Some(unlocked_ioctl_callback::<T>)
333-
} else {
334-
None
335-
},
336-
write_iter: None,
337-
};
338-
339271
/// Builds an instance of [`struct file_operations`].
340272
///
341273
/// # Safety
342274
///
343275
/// The caller must ensure that the adapter is compatible with the way the device is registered.
344-
pub(crate) const unsafe fn build() -> &'static bindings::file_operations {
345-
&Self::VTABLE
276+
/// The called must ensure that the `module` argument passed equals to the right `THIS_MODULE`.
277+
pub(crate) unsafe fn build(module: *mut bindings::module) -> bindings::file_operations {
278+
bindings::file_operations {
279+
open: Some(open_callback::<A, T>),
280+
release: Some(release_callback::<T>),
281+
read: if T::TO_USE.read {
282+
Some(read_callback::<T>)
283+
} else {
284+
None
285+
},
286+
write: if T::TO_USE.write {
287+
Some(write_callback::<T>)
288+
} else {
289+
None
290+
},
291+
llseek: if T::TO_USE.seek {
292+
Some(llseek_callback::<T>)
293+
} else {
294+
None
295+
},
296+
297+
check_flags: None,
298+
compat_ioctl: if T::TO_USE.compat_ioctl {
299+
Some(compat_ioctl_callback::<T>)
300+
} else {
301+
None
302+
},
303+
copy_file_range: None,
304+
fallocate: None,
305+
fadvise: None,
306+
fasync: None,
307+
flock: None,
308+
flush: None,
309+
fsync: if T::TO_USE.fsync {
310+
Some(fsync_callback::<T>)
311+
} else {
312+
None
313+
},
314+
get_unmapped_area: None,
315+
iterate: None,
316+
iterate_shared: None,
317+
iopoll: None,
318+
lock: None,
319+
mmap: if T::TO_USE.mmap {
320+
Some(mmap_callback::<T>)
321+
} else {
322+
None
323+
},
324+
mmap_supported_flags: 0,
325+
owner: module,
326+
poll: if T::TO_USE.poll {
327+
Some(poll_callback::<T>)
328+
} else {
329+
None
330+
},
331+
read_iter: None,
332+
remap_file_range: None,
333+
sendpage: None,
334+
setlease: None,
335+
show_fdinfo: None,
336+
splice_read: None,
337+
splice_write: None,
338+
unlocked_ioctl: if T::TO_USE.ioctl {
339+
Some(unlocked_ioctl_callback::<T>)
340+
} else {
341+
None
342+
},
343+
write_iter: None,
344+
}
346345
}
347346
}
348347

rust/kernel/miscdev.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<T: Sync> Registration<T> {
6767
}
6868

6969
// SAFETY: The adapter is compatible with `misc_register`.
70-
this.mdev.fops = unsafe { FileOperationsVtable::<Self, F>::build() };
70+
this.mdev.fops = unsafe { &FileOperationsVtable::<Self, F>::build(&mut bindings::__this_module) };
7171
this.mdev.name = name.as_ptr() as *const c_types::c_char;
7272
this.mdev.minor = minor.unwrap_or(bindings::MISC_DYNAMIC_MINOR as i32);
7373

0 commit comments

Comments
 (0)