// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2025 Google LLC.

//! DebugFS Abstraction
//!
//! C header: [`include/linux/debugfs.h`](srctree/include/linux/debugfs.h)

// When DebugFS is disabled, many parameters are dead. Linting for this isn't helpful.
#![cfg_attr(not(CONFIG_DEBUG_FS), allow(unused_variables))]

#[cfg(CONFIG_DEBUG_FS)]
use crate::sync::Arc;
use crate::{
    fmt,
    prelude::*,
    str::CStr,
    uaccess::UserSliceReader, //
};

#[cfg(CONFIG_DEBUG_FS)]
use core::mem::ManuallyDrop;
use core::{
    marker::{
        PhantomData,
        PhantomPinned, //
    },
    ops::Deref,
};

mod traits;
pub use traits::{
    BinaryReader,
    BinaryReaderMut,
    BinaryWriter,
    Reader,
    Writer, //
};

mod callback_adapters;
use callback_adapters::{
    FormatAdapter,
    NoWriter,
    WritableAdapter, //
};

mod file_ops;
use file_ops::{
    BinaryReadFile,
    BinaryReadWriteFile,
    BinaryWriteFile,
    FileOps,
    ReadFile,
    ReadWriteFile,
    WriteFile, //
};

#[cfg(CONFIG_DEBUG_FS)]
mod entry;
#[cfg(CONFIG_DEBUG_FS)]
use entry::Entry;

/// Owning handle to a DebugFS directory.
///
/// The directory in the filesystem represented by [`Dir`] will be removed when handle has been
/// dropped *and* all children have been removed.
// If we have a parent, we hold a reference to it in the `Entry`. This prevents the `dentry`
// we point to from being cleaned up if our parent `Dir`/`Entry` is dropped before us.
//
// The `None` option indicates that the `Arc` could not be allocated, so our children would not be
// able to refer to us. In this case, we need to silently fail. All future child directories/files
// will silently fail as well.
#[derive(Clone)]
pub struct Dir(#[cfg(CONFIG_DEBUG_FS)] Option<Arc<Entry<'static>>>);

impl Dir {
    /// Create a new directory in DebugFS. If `parent` is [`None`], it will be created at the root.
    fn create(name: &CStr, parent: Option<&Dir>) -> Self {
        #[cfg(CONFIG_DEBUG_FS)]
        {
            let parent_entry = match parent {
                // If the parent couldn't be allocated, just early-return
                Some(Dir(None)) => return Self(None),
                Some(Dir(Some(entry))) => Some(entry.clone()),
                None => None,
            };
            Self(
                // If Arc creation fails, the `Entry` will be dropped, so the directory will be
                // cleaned up.
                Arc::new(Entry::dynamic_dir(name, parent_entry), GFP_KERNEL).ok(),
            )
        }
        #[cfg(not(CONFIG_DEBUG_FS))]
        Self()
    }

    /// Creates a DebugFS file which will own the data produced by the initializer provided in
    /// `data`.
    fn create_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
        file_ops: &'static FileOps<T>,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Sync + 'static,
    {
        let scope = Scope::<T>::new(data, move |data| {
            #[cfg(CONFIG_DEBUG_FS)]
            if let Some(parent) = &self.0 {
                // SAFETY: Because data derives from a scope, and our entry will be dropped before
                // the data is dropped, it is guaranteed to outlive the entry we return.
                unsafe { Entry::dynamic_file(name, parent.clone(), data, file_ops) }
            } else {
                Entry::empty()
            }
        });
        try_pin_init! {
            File {
                scope <- scope
            } ? E
        }
    }

    /// Create a new directory in DebugFS at the root.
    ///
    /// # Examples
    ///
    /// ```
    /// # use kernel::debugfs::Dir;
    /// let debugfs = Dir::new(c"parent");
    /// ```
    pub fn new(name: &CStr) -> Self {
        Dir::create(name, None)
    }

    /// Creates a subdirectory within this directory.
    ///
    /// # Examples
    ///
    /// ```
    /// # use kernel::debugfs::Dir;
    /// let parent = Dir::new(c"parent");
    /// let child = parent.subdir(c"child");
    /// ```
    pub fn subdir(&self, name: &CStr) -> Self {
        Dir::create(name, Some(self))
    }

    /// Creates a read-only file in this directory.
    ///
    /// The file's contents are produced by invoking [`Writer::write`] on the value initialized by
    /// `data`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use kernel::debugfs::Dir;
    /// # use kernel::prelude::*;
    /// # let dir = Dir::new(c"my_debugfs_dir");
    /// let file = KBox::pin_init(dir.read_only_file(c"foo", 200), GFP_KERNEL)?;
    /// // "my_debugfs_dir/foo" now contains the number 200.
    /// // The file is removed when `file` is dropped.
    /// # Ok::<(), Error>(())
    /// ```
    pub fn read_only_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Writer + Send + Sync + 'static,
    {
        let file_ops = &<T as ReadFile<_>>::FILE_OPS;
        self.create_file(name, data, file_ops)
    }

    /// Creates a read-only binary file in this directory.
    ///
    /// The file's contents are produced by invoking [`BinaryWriter::write_to_slice`] on the value
    /// initialized by `data`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use kernel::debugfs::Dir;
    /// # use kernel::prelude::*;
    /// # let dir = Dir::new(c"my_debugfs_dir");
    /// let file = KBox::pin_init(dir.read_binary_file(c"foo", [0x1, 0x2]), GFP_KERNEL)?;
    /// # Ok::<(), Error>(())
    /// ```
    pub fn read_binary_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: BinaryWriter + Send + Sync + 'static,
    {
        self.create_file(name, data, &T::FILE_OPS)
    }

    /// Creates a read-only file in this directory, with contents from a callback.
    ///
    /// `f` must be a function item or a non-capturing closure.
    /// This is statically asserted and not a safety requirement.
    ///
    /// # Examples
    ///
    /// ```
    /// # use kernel::{
    /// #     debugfs::Dir,
    /// #     prelude::*,
    /// #     sync::atomic::{
    /// #         Atomic,
    /// #         Relaxed,
    /// #     },
    /// # };
    /// # let dir = Dir::new(c"foo");
    /// let file = KBox::pin_init(
    ///     dir.read_callback_file(c"bar",
    ///     Atomic::<u32>::new(3),
    ///     &|val, f| {
    ///       let out = val.load(Relaxed);
    ///       writeln!(f, "{out:#010x}")
    ///     }),
    ///     GFP_KERNEL)?;
    /// // Reading "foo/bar" will show "0x00000003".
    /// file.store(10, Relaxed);
    /// // Reading "foo/bar" will now show "0x0000000a".
    /// # Ok::<(), Error>(())
    /// ```
    pub fn read_callback_file<'a, T, E: 'a, F>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
        _f: &'static F,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Send + Sync + 'static,
        F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync,
    {
        let file_ops = <FormatAdapter<T, F>>::FILE_OPS.adapt();
        self.create_file(name, data, file_ops)
    }

    /// Creates a read-write file in this directory.
    ///
    /// Reading the file uses the [`Writer`] implementation.
    /// Writing to the file uses the [`Reader`] implementation.
    pub fn read_write_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Writer + Reader + Send + Sync + 'static,
    {
        let file_ops = &<T as ReadWriteFile<_>>::FILE_OPS;
        self.create_file(name, data, file_ops)
    }

    /// Creates a read-write binary file in this directory.
    ///
    /// Reading the file uses the [`BinaryWriter`] implementation.
    /// Writing to the file uses the [`BinaryReader`] implementation.
    pub fn read_write_binary_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: BinaryWriter + BinaryReader + Send + Sync + 'static,
    {
        let file_ops = &<T as BinaryReadWriteFile<_>>::FILE_OPS;
        self.create_file(name, data, file_ops)
    }

    /// Creates a read-write file in this directory, with logic from callbacks.
    ///
    /// Reading from the file is handled by `f`. Writing to the file is handled by `w`.
    ///
    /// `f` and `w` must be function items or non-capturing closures.
    /// This is statically asserted and not a safety requirement.
    pub fn read_write_callback_file<'a, T, E: 'a, F, W>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
        _f: &'static F,
        _w: &'static W,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Send + Sync + 'static,
        F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync,
        W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync,
    {
        let file_ops =
            <WritableAdapter<FormatAdapter<T, F>, W> as file_ops::ReadWriteFile<_>>::FILE_OPS
                .adapt()
                .adapt();
        self.create_file(name, data, file_ops)
    }

    /// Creates a write-only file in this directory.
    ///
    /// The file owns its backing data. Writing to the file uses the [`Reader`]
    /// implementation.
    ///
    /// The file is removed when the returned [`File`] is dropped.
    pub fn write_only_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Reader + Send + Sync + 'static,
    {
        self.create_file(name, data, &T::FILE_OPS)
    }

    /// Creates a write-only binary file in this directory.
    ///
    /// The file owns its backing data. Writing to the file uses the [`BinaryReader`]
    /// implementation.
    ///
    /// The file is removed when the returned [`File`] is dropped.
    pub fn write_binary_file<'a, T, E: 'a>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: BinaryReader + Send + Sync + 'static,
    {
        self.create_file(name, data, &T::FILE_OPS)
    }

    /// Creates a write-only file in this directory, with write logic from a callback.
    ///
    /// `w` must be a function item or a non-capturing closure.
    /// This is statically asserted and not a safety requirement.
    pub fn write_callback_file<'a, T, E: 'a, W>(
        &'a self,
        name: &'a CStr,
        data: impl PinInit<T, E> + 'a,
        _w: &'static W,
    ) -> impl PinInit<File<T>, E> + 'a
    where
        T: Send + Sync + 'static,
        W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync,
    {
        let file_ops = <WritableAdapter<NoWriter<T>, W> as WriteFile<_>>::FILE_OPS
            .adapt()
            .adapt();
        self.create_file(name, data, file_ops)
    }

    // While this function is safe, it is intentionally not public because it's a bit of a
    // footgun.
    //
    // Unless you also extract the `entry` later and schedule it for `Drop` at the appropriate
    // time, a `ScopedDir` with a `Dir` parent will never be deleted.
    fn scoped_dir<'data>(&self, name: &CStr) -> ScopedDir<'data, 'static> {
        #[cfg(CONFIG_DEBUG_FS)]
        {
            let parent_entry = match &self.0 {
                None => return ScopedDir::empty(),
                Some(entry) => entry.clone(),
            };
            ScopedDir {
                entry: ManuallyDrop::new(Entry::dynamic_dir(name, Some(parent_entry))),
                _phantom: PhantomData,
            }
        }
        #[cfg(not(CONFIG_DEBUG_FS))]
        ScopedDir::empty()
    }

    /// Creates a new scope, which is a directory associated with some data `T`.
    ///
    /// The created directory will be a subdirectory of `self`. The `init` closure is called to
    /// populate the directory with files and subdirectories. These files can reference the data
    /// stored in the scope.
    ///
    /// The entire directory tree created within the scope will be removed when the returned
    /// `Scope` handle is dropped.
    pub fn scope<'a, T: 'a, E: 'a, F>(
        &'a self,
        data: impl PinInit<T, E> + 'a,
        name: &'a CStr,
        init: F,
    ) -> impl PinInit<Scope<T>, E> + 'a
    where
        F: for<'data, 'dir> FnOnce(&'data T, &'dir ScopedDir<'data, 'dir>) + 'a,
    {
        Scope::new(data, |data| {
            let scoped = self.scoped_dir(name);
            init(data, &scoped);
            scoped.into_entry()
        })
    }
}

#[pin_data]
/// Handle to a DebugFS scope, which ensures that attached `data` will outlive the DebugFS entry
/// without moving.
///
/// This is internally used to back [`File`], and used in the API to represent the attachment
/// of a directory lifetime to a data structure which may be jointly accessed by a number of
/// different files.
///
/// When dropped, a `Scope` will remove all directories and files in the filesystem backed by the
/// attached data structure prior to releasing the attached data.
pub struct Scope<T> {
    // This order is load-bearing for drops - `_entry` must be dropped before `data`.
    #[cfg(CONFIG_DEBUG_FS)]
    _entry: Entry<'static>,
    #[pin]
    data: T,
    // Even if `T` is `Unpin`, we still can't allow it to be moved.
    #[pin]
    _pin: PhantomPinned,
}

#[pin_data]
/// Handle to a DebugFS file, owning its backing data.
///
/// When dropped, the DebugFS file will be removed and the attached data will be dropped.
pub struct File<T> {
    #[pin]
    scope: Scope<T>,
}

#[cfg(not(CONFIG_DEBUG_FS))]
impl<'b, T: 'b> Scope<T> {
    fn new<E: 'b, F>(data: impl PinInit<T, E> + 'b, init: F) -> impl PinInit<Self, E> + 'b
    where
        F: for<'a> FnOnce(&'a T) + 'b,
    {
        try_pin_init! {
            Self {
                data <- data,
                _pin: PhantomPinned
            } ? E
        }
        .pin_chain(|scope| {
            init(&scope.data);
            Ok(())
        })
    }
}

#[cfg(CONFIG_DEBUG_FS)]
impl<'b, T: 'b> Scope<T> {
    fn entry_mut(self: Pin<&mut Self>) -> &mut Entry<'static> {
        // SAFETY: _entry is not structurally pinned.
        unsafe { &mut Pin::into_inner_unchecked(self)._entry }
    }

    fn new<E: 'b, F>(data: impl PinInit<T, E> + 'b, init: F) -> impl PinInit<Self, E> + 'b
    where
        F: for<'a> FnOnce(&'a T) -> Entry<'static> + 'b,
    {
        try_pin_init! {
            Self {
                _entry: Entry::empty(),
                data <- data,
                _pin: PhantomPinned
            } ? E
        }
        .pin_chain(|scope| {
            *scope.entry_mut() = init(&scope.data);
            Ok(())
        })
    }
}

impl<'a, T: 'a> Scope<T> {
    /// Creates a new scope, which is a directory at the root of the debugfs filesystem,
    /// associated with some data `T`.
    ///
    /// The `init` closure is called to populate the directory with files and subdirectories. These
    /// files can reference the data stored in the scope.
    ///
    /// The entire directory tree created within the scope will be removed when the returned
    /// `Scope` handle is dropped.
    pub fn dir<E: 'a, F>(
        data: impl PinInit<T, E> + 'a,
        name: &'a CStr,
        init: F,
    ) -> impl PinInit<Self, E> + 'a
    where
        F: for<'data, 'dir> FnOnce(&'data T, &'dir ScopedDir<'data, 'dir>) + 'a,
    {
        Scope::new(data, |data| {
            let scoped = ScopedDir::new(name);
            init(data, &scoped);
            scoped.into_entry()
        })
    }
}

impl<T> Deref for Scope<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.data
    }
}

impl<T> Deref for File<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.scope
    }
}

/// A handle to a directory which will live at most `'dir`, accessing data that will live for at
/// least `'data`.
///
/// Dropping a ScopedDir will not delete or clean it up, this is expected to occur through dropping
/// the `Scope` that created it.
pub struct ScopedDir<'data, 'dir> {
    #[cfg(CONFIG_DEBUG_FS)]
    entry: ManuallyDrop<Entry<'dir>>,
    _phantom: PhantomData<fn(&'data ()) -> &'dir ()>,
}

impl<'data, 'dir> ScopedDir<'data, 'dir> {
    /// Creates a subdirectory inside this `ScopedDir`.
    ///
    /// The returned directory handle cannot outlive this one.
    pub fn dir<'dir2>(&'dir2 self, name: &CStr) -> ScopedDir<'data, 'dir2> {
        #[cfg(not(CONFIG_DEBUG_FS))]
        let _ = name;
        ScopedDir {
            #[cfg(CONFIG_DEBUG_FS)]
            entry: ManuallyDrop::new(Entry::dir(name, Some(&*self.entry))),
            _phantom: PhantomData,
        }
    }

    fn create_file<T: Sync>(&self, name: &CStr, data: &'data T, vtable: &'static FileOps<T>) {
        #[cfg(CONFIG_DEBUG_FS)]
        core::mem::forget(Entry::file(name, &self.entry, data, vtable));
    }

    /// Creates a read-only file in this directory.
    ///
    /// The file's contents are produced by invoking [`Writer::write`].
    ///
    /// This function does not produce an owning handle to the file. The created
    /// file is removed when the [`Scope`] that this directory belongs
    /// to is dropped.
    pub fn read_only_file<T: Writer + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) {
        self.create_file(name, data, &T::FILE_OPS)
    }

    /// Creates a read-only binary file in this directory.
    ///
    /// The file's contents are produced by invoking [`BinaryWriter::write_to_slice`].
    ///
    /// This function does not produce an owning handle to the file. The created file is removed
    /// when the [`Scope`] that this directory belongs to is dropped.
    pub fn read_binary_file<T: BinaryWriter + Send + Sync + 'static>(
        &self,
        name: &CStr,
        data: &'data T,
    ) {
        self.create_file(name, data, &T::FILE_OPS)
    }

    /// Creates a read-only file in this directory, with contents from a callback.
    ///
    /// The file contents are generated by calling `f` with `data`.
    ///
    ///
    /// `f` must be a function item or a non-capturing closure.
    /// This is statically asserted and not a safety requirement.
    ///
    /// This function does not produce an owning handle to the file. The created
    /// file is removed when the [`Scope`] that this directory belongs
    /// to is dropped.
    pub fn read_callback_file<T, F>(&self, name: &CStr, data: &'data T, _f: &'static F)
    where
        T: Send + Sync + 'static,
        F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync,
    {
        let vtable = <FormatAdapter<T, F> as ReadFile<_>>::FILE_OPS.adapt();
        self.create_file(name, data, vtable)
    }

    /// Creates a read-write file in this directory.
    ///
    /// Reading the file uses the [`Writer`] implementation on `data`. Writing to the file uses
    /// the [`Reader`] implementation on `data`.
    ///
    /// This function does not produce an owning handle to the file. The created
    /// file is removed when the [`Scope`] that this directory belongs
    /// to is dropped.
    pub fn read_write_file<T: Writer + Reader + Send + Sync + 'static>(
        &self,
        name: &CStr,
        data: &'data T,
    ) {
        let vtable = &<T as ReadWriteFile<_>>::FILE_OPS;
        self.create_file(name, data, vtable)
    }

    /// Creates a read-write binary file in this directory.
    ///
    /// Reading the file uses the [`BinaryWriter`] implementation on `data`. Writing to the file
    /// uses the [`BinaryReader`] implementation on `data`.
    ///
    /// This function does not produce an owning handle to the file. The created file is removed
    /// when the [`Scope`] that this directory belongs to is dropped.
    pub fn read_write_binary_file<T: BinaryWriter + BinaryReader + Send + Sync + 'static>(
        &self,
        name: &CStr,
        data: &'data T,
    ) {
        let vtable = &<T as BinaryReadWriteFile<_>>::FILE_OPS;
        self.create_file(name, data, vtable)
    }

    /// Creates a read-write file in this directory, with logic from callbacks.
    ///
    /// Reading from the file is handled by `f`. Writing to the file is handled by `w`.
    ///
    /// `f` and `w` must be function items or non-capturing closures.
    /// This is statically asserted and not a safety requirement.
    ///
    /// This function does not produce an owning handle to the file. The created
    /// file is removed when the [`Scope`] that this directory belongs
    /// to is dropped.
    pub fn read_write_callback_file<T, F, W>(
        &self,
        name: &CStr,
        data: &'data T,
        _f: &'static F,
        _w: &'static W,
    ) where
        T: Send + Sync + 'static,
        F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync,
        W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync,
    {
        let vtable = <WritableAdapter<FormatAdapter<T, F>, W> as ReadWriteFile<_>>::FILE_OPS
            .adapt()
            .adapt();
        self.create_file(name, data, vtable)
    }

    /// Creates a write-only file in this directory.
    ///
    /// Writing to the file uses the [`Reader`] implementation on `data`.
    ///
    /// This function does not produce an owning handle to the file. The created
    /// file is removed when the [`Scope`] that this directory belongs
    /// to is dropped.
    pub fn write_only_file<T: Reader + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) {
        let vtable = &<T as WriteFile<_>>::FILE_OPS;
        self.create_file(name, data, vtable)
    }

    /// Creates a write-only binary file in this directory.
    ///
    /// Writing to the file uses the [`BinaryReader`] implementation on `data`.
    ///
    /// This function does not produce an owning handle to the file. The created file is removed
    /// when the [`Scope`] that this directory belongs to is dropped.
    pub fn write_binary_file<T: BinaryReader + Send + Sync + 'static>(
        &self,
        name: &CStr,
        data: &'data T,
    ) {
        self.create_file(name, data, &T::FILE_OPS)
    }

    /// Creates a write-only file in this directory, with write logic from a callback.
    ///
    /// Writing to the file is handled by `w`.
    ///
    /// `w` must be a function item or a non-capturing closure.
    /// This is statically asserted and not a safety requirement.
    ///
    /// This function does not produce an owning handle to the file. The created
    /// file is removed when the [`Scope`] that this directory belongs
    /// to is dropped.
    pub fn write_only_callback_file<T, W>(&self, name: &CStr, data: &'data T, _w: &'static W)
    where
        T: Send + Sync + 'static,
        W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync,
    {
        let vtable = &<WritableAdapter<NoWriter<T>, W> as WriteFile<_>>::FILE_OPS
            .adapt()
            .adapt();
        self.create_file(name, data, vtable)
    }

    fn empty() -> Self {
        ScopedDir {
            #[cfg(CONFIG_DEBUG_FS)]
            entry: ManuallyDrop::new(Entry::empty()),
            _phantom: PhantomData,
        }
    }
    #[cfg(CONFIG_DEBUG_FS)]
    fn into_entry(self) -> Entry<'dir> {
        ManuallyDrop::into_inner(self.entry)
    }
    #[cfg(not(CONFIG_DEBUG_FS))]
    fn into_entry(self) {}
}

impl<'data> ScopedDir<'data, 'static> {
    // This is safe, but intentionally not exported due to footgun status. A ScopedDir with no
    // parent will never be released by default, and needs to have its entry extracted and used
    // somewhere.
    fn new(name: &CStr) -> ScopedDir<'data, 'static> {
        ScopedDir {
            #[cfg(CONFIG_DEBUG_FS)]
            entry: ManuallyDrop::new(Entry::dir(name, None)),
            _phantom: PhantomData,
        }
    }
}
