On Fri, Mar 6, 2026 at 11:28 AM Sami Tolvanen <[email protected]> wrote:
>
> On Thu, Feb 26, 2026 at 03:47:28PM -0800, Matthew Wood wrote:
> > +/// Set a string module parameter from a string.
> > +///
> > +/// Similar to [`set_param`] but for [`StringParam`].
> > +///
> > +/// # Safety
> > +///
> > +/// Same requirements as [`set_param`].
> > +unsafe extern "C" fn set_string_param(
> > +    val: *const c_char,
> > +    param: *const bindings::kernel_param,
> > +) -> c_int {
> > +    if val.is_null() {
> > +        crate::pr_warn!("Null pointer passed to 
> > `module_param::set_string_param`");
> > +        return EINVAL.to_errno();
> > +    }
> > +
> > +    crate::error::from_result(|| {
> > +        // SAFETY: val points to a valid C string from the kernel.
> > +        let cstr_param = unsafe { StringParam::from_ptr(val) };
> > +
> > +        // SAFETY: By function safety requirements, param.arg points to 
> > our SetOnce<StringParam>.
> > +        let container = unsafe { 
> > &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<StringParam>>()) };
>
> I do realize this matches set_param, and there's a good chance I
> missed something when reading the macros, but doesn't arg actually
> point to ModuleParamAccess<T> here? Since the struct is not repr(C),
> isn't the compiler technically speaking allowed to reorder the
> fields, which means SetOnce<T> might not actually be at offset 0?
>

Hi Sami,

I appreciate the review! This does seem to be an oversight, I'll try
to figure out the
correct implementation. I agree, `repr(C)` is likely needed here.

> > +
> > +        container
> > +            .populate(cstr_param)
> > +            .then_some(0)
> > +            .ok_or(kernel::error::code::EEXIST)
>
> Does this mean the behavior for Rust modules differs from C modules if
> the user specifies multiple instances of the same parameter? I believe
> we just use the last value of the parameter instead of failing in C.
>
> Sami

Yes, I'll fix that, the implementations should match.

Regards,
Mat

Reply via email to