Re: [RFC PATCH 01/19] rust: fs: add registration/unregistration of file systems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 18 Oct 2023 at 12:38, Benno Lossin <benno.lossin@xxxxxxxxx> wrote:
> On 18.10.23 14:25, Wedson Almeida Filho wrote:
> > +/// A registration of a file system.
> > +#[pin_data(PinnedDrop)]
> > +pub struct Registration {
> > +    #[pin]
> > +    fs: Opaque<bindings::file_system_type>,
> > +    #[pin]
> > +    _pin: PhantomPinned,
>
> Note that since commit 0b4e3b6f6b79 ("rust: types: make `Opaque` be
> `!Unpin`") you do not need an extra pinned `PhantomPinned` in your struct
> (if you already have a pinned `Opaque`), since `Opaque` already is
> `!Unpin`.

Will remove in v2.

> > +impl Registration {
> > +    /// Creates the initialiser of a new file system registration.
> > +    pub fn new<T: FileSystem + ?Sized>(module: &'static ThisModule) -> impl PinInit<Self, Error> {
>
> I am a bit curious why you specify `?Sized` here, is it common
> for types that implement `FileSystem` to not be `Sized`?
>
> Or do you want to use `dyn FileSystem`?

No reason beyond `Sized` being a restriction I don't need.

For something I was doing early on in binder, I ended up having to
change a bunch of generic type decls to allow !Sized, so here I'm
doing it preemptively as I don't lose anything.

> > +        try_pin_init!(Self {
> > +            _pin: PhantomPinned,
> > +            fs <- Opaque::try_ffi_init(|fs_ptr: *mut bindings::file_system_type| {
> > +                // SAFETY: `try_ffi_init` guarantees that `fs_ptr` is valid for write.
> > +                unsafe { fs_ptr.write(bindings::file_system_type::default()) };
> > +
> > +                // SAFETY: `try_ffi_init` guarantees that `fs_ptr` is valid for write, and it has
> > +                // just been initialised above, so it's also valid for read.
> > +                let fs = unsafe { &mut *fs_ptr };
> > +                fs.owner = module.0;
> > +                fs.name = T::NAME.as_char_ptr();
> > +                fs.init_fs_context = Some(Self::init_fs_context_callback);
> > +                fs.kill_sb = Some(Self::kill_sb_callback);
> > +                fs.fs_flags = 0;
> > +
> > +                // SAFETY: Pointers stored in `fs` are static so will live for as long as the
> > +                // registration is active (it is undone in `drop`).
> > +                to_result(unsafe { bindings::register_filesystem(fs_ptr) })
> > +            }),
> > +        })
> > +    }
> > +
> > +    unsafe extern "C" fn init_fs_context_callback(
> > +        _fc_ptr: *mut bindings::fs_context,
> > +    ) -> core::ffi::c_int {
> > +        from_result(|| Err(ENOTSUPP))
> > +    }
> > +
> > +    unsafe extern "C" fn kill_sb_callback(_sb_ptr: *mut bindings::super_block) {}
> > +}
> > +
> > +#[pinned_drop]
> > +impl PinnedDrop for Registration {
> > +    fn drop(self: Pin<&mut Self>) {
> > +        // SAFETY: If an instance of `Self` has been successfully created, a call to
> > +        // `register_filesystem` has necessarily succeeded. So it's ok to call
> > +        // `unregister_filesystem` on the previously registered fs.
>
> I would simply add an invariant on `Registration` that `self.fs` is
> registered, then you do not need such a lengthy explanation here.

Since this is the only place I need this explanation, I prefer to
leave it here because it's exactly where I need it.

Thanks,
-Wedson




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux