Skip to content

Conversation

@songhahaha66
Copy link
Contributor

@Ivanbeethoven Ivanbeethoven requested a review from Copilot October 24, 2025 08:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the overlay filesystem implementation to replace direct use of PassthroughFs with a generic Layer trait, enabling support for multiple filesystem layer implementations. This architectural change makes the overlay filesystem more flexible and extensible.

Key changes:

  • Introduces a Layer trait that defines the interface required for overlay filesystem layers
  • Parameterizes core overlay types (OverlayFs, OverlayInode, RealInode, etc.) with generic type L: Layer + Send + Sync + 'static
  • Simplifies opaque directory handling by removing complex xattr-based checks and defaulting to false

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.

File Description
project/libfuse-fs/src/overlayfs/mod.rs Refactored to use generic Layer trait; updated all type signatures to be parameterized by L; simplified opaque/whiteout checks
project/libfuse-fs/src/overlayfs/layer.rs Defined Layer trait with required methods; added helper methods for copy-up operations; implemented Layer for PassthroughFs
project/libfuse-fs/src/overlayfs/inode_store.rs Updated InodeStore to be generic over Layer type; added clear method for cleanup
project/libfuse-fs/src/overlayfs/async_io.rs Updated Filesystem implementation to work with generic Layer type

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 24 to 29
fn create_whiteout(
&self,
ctx: Request,
parent: Inode,
name: &OsStr,
) -> Result<ReplyEntry> {
) -> impl std::future::Future<Output = Result<ReplyEntry>> + Send {
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method signature change from async fn to fn returning impl Future is inconsistent with the trait bounds. Consider keeping async fn syntax for better readability and consistency with the trait's Filesystem requirement, or document why this pattern is necessary.

Copilot uses AI. Check for mistakes.
Comment on lines 97 to 98
fn is_whiteout(&self, ctx: Request, inode: Inode) -> impl std::future::Future<Output = Result<bool>> + Send
where Self: Send {
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The where Self: Send bound is redundant since the trait already requires Send + Sync + 'static at line 17. Remove this unnecessary constraint.

Suggested change
fn is_whiteout(&self, ctx: Request, inode: Inode) -> impl std::future::Future<Output = Result<bool>> + Send
where Self: Send {
fn is_whiteout(&self, ctx: Request, inode: Inode) -> impl std::future::Future<Output = Result<bool>> + Send {

Copilot uses AI. Check for mistakes.
Comment on lines 127 to 128
fn is_opaque(&self, _ctx: Request, _inode: Inode) -> impl std::future::Future<Output = Result<bool>> + Send
where Self: Send {
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The where Self: Send bound is redundant since the trait already requires Send + Sync + 'static at line 17. Remove this unnecessary constraint.

Copilot uses AI. Check for mistakes.
Comment on lines 236 to 241
fn is_opaque(&self, _ctx: Request, _inode: Inode) -> impl std::future::Future<Output = Result<bool>> + Send {
async move {
// Default implementation - override in specific Layer implementations
Ok(false)
}
}
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The is_opaque implementation is duplicated from the trait's default implementation (lines 127-133). Since PassthroughFs doesn't need custom behavior, this entire method can be removed to avoid duplication.

Suggested change
fn is_opaque(&self, _ctx: Request, _inode: Inode) -> impl std::future::Future<Output = Result<bool>> + Send {
async move {
// Default implementation - override in specific Layer implementations
Ok(false)
}
}

Copilot uses AI. Check for mistakes.
// The Entry must be forgotten in each layer, which will be done automatically by Drop operation.
let (whiteout, opaque) = if v.attr.kind == FileType::Directory {
(false, layer.is_opaque(ctx, v.attr.ino).await?)
(false, false)
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The opaque check has been hardcoded to false, removing the layer's ability to detect opaque directories. This should call self.layer.is_opaque(ctx, v.attr.ino).await? to properly delegate to the layer implementation.

Suggested change
(false, false)
let opaque = self.layer.is_opaque(ctx, v.attr.ino).await?;
(false, opaque)

Copilot uses AI. Check for mistakes.
(false, false)
} else {
(layer.is_whiteout(ctx, v.attr.ino).await?, false)
(false, false)
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whiteout check has been hardcoded to false, removing the layer's ability to detect whiteout files. This should call self.layer.is_whiteout(ctx, v.attr.ino).await? to properly delegate to the layer implementation.

Copilot uses AI. Check for mistakes.

let opaque = if utils::is_dir(&entry.attr.kind) {
self.layer.is_opaque(ctx, entry.attr.ino).await?
false
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The opaque check has been hardcoded to false. This should call self.layer.is_opaque(ctx, entry.attr.ino).await? to properly check if the directory is opaque.

Copilot uses AI. Check for mistakes.
ino,
false,
layer.is_opaque(ctx, ino).await?,
false,
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The opaque check has been hardcoded to false. This should call layer.is_opaque(ctx, ino).await? to properly check if the root directory is opaque when pushing a new layer.

Copilot uses AI. Check for mistakes.
ino,
false,
layer.is_opaque(ctx, ino).await?,
false,
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The opaque check has been hardcoded to false. This should call layer.is_opaque(ctx, ino).await? to properly check if the directory is opaque for lower layers when pushing a new layer.

Copilot uses AI. Check for mistakes.
Comment on lines 723 to 724
/// by using the [`getattr_helper`][crate::overlayfs::layer::Layer::getattr_helper] and
/// [`mkdir_helper`][crate::overlayfs::layer::Layer::mkdir_helper] methods.
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation references have been updated from PassthroughFs methods to Layer trait methods, but these doc links may not resolve correctly. Verify that the paths crate::overlayfs::layer::Layer::getattr_helper and crate::overlayfs::layer::Layer::mkdir_helper are valid rustdoc references.

Suggested change
/// by using the [`getattr_helper`][crate::overlayfs::layer::Layer::getattr_helper] and
/// [`mkdir_helper`][crate::overlayfs::layer::Layer::mkdir_helper] methods.
/// by using the `getattr_helper` and `mkdir_helper` methods of the Layer trait.

Copilot uses AI. Check for mistakes.
@Ricky-Daxia
Copy link
Collaborator

Note

do_*_helper 接口放到 Layer trait 中实现不是一种好的实践,目前这么设计是针对 PassthroughFs 现有实现的一个 workaround,一个修改建议如下(from copilot):

您分析得非常准确,将特定于 passthrough 实现的 do_*_helper 函数添加到通用的 Layer trait 中确实不是一个好的实践。这会造成“接口污染”,使得 Layer trait 的抽象泄漏了其某个具体实现的内部细节。所有 Layer 的实现者都将被迫实现这些它们可能根本不需要的、用于 overlayfs copy-up 逻辑的特殊函数。

您的直觉是正确的。我们应该寻求一种方法,既能让 OverlayFs 持有通用的 Box<dyn Layer>,又能在需要时“特殊处理” PassthroughFs 类型的实例,而无需修改 Layer trait 的公共契约。

以下是几种推荐的替代方案,按推荐程度排序:

方案一:使用内部上下文对象(推荐)

这是最清晰、最符合 Rust 设计模式的方案。其核心思想是,将那些需要特殊参数(如原始 UID/GID)的操作,通过一个上下文(Context)对象来传递,而不是创建独立的 _helper 方法。

  1. 定义一个上下文结构体
    这个结构体将包含 FUSE 请求的原始信息以及任何内部操作可能需要的额外参数。

    // 可以放在一个公共的模块,比如 crate::context
    pub struct OperationContext {
        pub req: Request,
        /// 内部操作可以覆盖此UID,否则使用 req.uid
        pub uid: Option<u32>,
        /// 内部操作可以覆盖此GID,否则使用 req.gid
        pub gid: Option<u32>,
        // ... 未来可以添加其他参数
    }
    
    impl From<Request> for OperationContext {
        fn from(req: Request) -> Self {
            OperationContext {
                req,
                uid: None,
                gid: None,
            }
        }
    }
  2. 修改 Filesystem (以及 Layer) 的方法签名
    将所有需要访问请求者信息或可能被内部调用覆盖的方法,从接收 Request 改为接收 OperationContext

    // in project/libfuse-fs/src/overlayfs/layer.rs
    // ...
    pub trait Layer: Filesystem {
        // ...
    }
    
    // in rfuse3/src/raw/filesystem.rs (或者您自己的 Filesystem trait)
    pub trait Filesystem {
        // ...
        async fn create(
            &self,
            ctx: OperationContext, // <--- 修改
            parent: Inode,
            name: &OsStr,
            mode: u32,
            flags: u32,
        ) -> Result<ReplyCreated>;
    
        async fn mkdir(
            &self,
            ctx: OperationContext, // <--- 修改
            parent: Inode,
            name: &OsStr,
            mode: u32,
            umask: u32,
        ) -> Result<ReplyEntry>;
        // ... 其他类似方法
    }
  3. PassthroughFs 中实现新签名
    do_create_inner 这样的函数就不再需要了。create 方法内部直接根据 OperationContext 的内容来决定使用哪个 UID/GID。

    // in project/libfuse-fs/src/passthrough/async_io.rs
    // ...
    impl Filesystem for PassthroughFs {
        async fn create(
            &self,
            ctx: OperationContext, // <--- 新的上下文
            parent: Inode,
            name: &OsStr,
            mode: u32,
            flags: u32,
        ) -> Result<ReplyCreated> {
            let name = osstr_to_cstr(name).unwrap();
            let name = name.as_ref();
            self.validate_path_component(name)?;
    
            let dir = self.inode_map.get(parent).await?;
            let dir_file = dir.get_file()?;
    
            // 决定使用哪个 UID/GID
            let effective_uid = ctx.uid.unwrap_or(self.cfg.mapping.get_uid(ctx.req.uid));
            let effective_gid = ctx.gid.unwrap_or(self.cfg.mapping.get_gid(ctx.req.gid));
    
            let new_file = {
                let flags = self.get_writeback_open_flags(flags as i32).await;
                let _guard = set_creds(effective_uid, effective_gid)?;
                Self::create_file_excl(&dir_file, name, flags, mode)?
            };
    
            // ... 剩余逻辑不变 ...
            // `do_create_inner` 和 `do_create_helper` 可以被移除或合并到这里
        }
        // ...
    }
  4. OverlayFs 中调用
    OverlayFs 进行 copy-up 时,它会创建一个 OperationContext 并填充 uidgid 字段,然后调用 layer.create()

    // in project/libfuse-fs/src/overlayfs/mod.rs
    // ...
    // 在 copy_regfile_up 或类似函数中
    let mut ctx = OperationContext::from(req);
    ctx.uid = Some(st.attr.uid); // 原始的 host UID
    ctx.gid = Some(st.attr.gid); // 原始的 host GID
    
    let create_rep = parent_real_inode
        .layer
        .create(
            ctx, // <--- 传递定制的上下文
            parent_real_inode.inode,
            name,
            mode,
            flags.try_into().unwrap(),
        )
        .await?;
    // ...

优点

  • 接口干净Layer trait 的接口保持通用和简洁。
  • 意图明确OperationContext 清晰地表达了操作的上下文和意图,比多个 _helper 方法更具扩展性。
  • 类型安全:完全利用了 trait 和 struct,没有运行时类型转换。

方案二:使用 Any 进行动态向下转型(Downcasting)

如果不想修改 Filesystem trait 的签名,可以使用 std::any::Any 在运行时检查 Layer trait object 的具体类型。

  1. Layer trait 继承 Any
    为了能够进行 downcast,trait 必须是 'static 并且提供 as_any 方法。一个简单的方法是让它继承 Any

    // in project/libfuse-fs/src/overlayfs/layer.rs
    use std::any::Any;
    // ...
    pub trait Layer: Filesystem + Any + Send + Sync {
        fn as_any(&self) -> &dyn Any;
        // ...
    }
    
    // in project/libfuse-fs/src/passthrough/mod.rs
    impl Layer for PassthroughFs {
        fn as_any(&self) -> &dyn Any {
            self
        }
        fn root_inode(&self) -> Inode {
            1
        }
    }
  2. OverlayFs 中进行 Downcast
    当需要调用 do_create_helper 时,尝试将 &dyn Layer 转换为 &PassthroughFs

    // in project/libfuse-fs/src/overlayfs/mod.rs
    // ...
    // 在 copy_regfile_up 或类似函数中
    let layer = &parent_real_inode.layer;
    
    if let Some(passthrough_fs) = layer.as_any().downcast_ref::<PassthroughFs>() {
        // 转型成功,现在可以调用 PassthroughFs 的特有方法
        let create_rep = passthrough_fs
            .do_create_helper(
                ctx,
                parent_real_inode.inode,
                name,
                mode,
                flags.try_into().unwrap(),
                st.attr.uid,
                st.attr.gid,
            )
            .await?;
        // ...
    } else {
        // 转型失败,说明底层的 layer 不是 PassthroughFs。
        // 在这里需要决定如何处理:
        // 1. 返回错误,因为 copy-up 逻辑无法完成。
        // 2. 尝试使用标准的 create 方法(但这会丢失 UID/GID)。
        return Err(Error::new(
            std::io::ErrorKind::Unsupported,
            "The underlying layer does not support preserving UID/GID on copy-up.",
        ));
    }
    // ...

优点

  • Layer trait 的方法签名保持不变。

缺点

  • 引入了运行时类型检查,如果转型失败,需要有备用逻辑或直接报错。
  • OverlayFs 的 copy-up 逻辑与 PassthroughFs 的具体实现紧密耦合在了一起,尽管 Layer trait 本身是解耦的。

结论与建议

方案一(内部上下文对象)是更优的解决方案。 它通过一个通用的上下文对象优雅地解决了问题,保持了接口的整洁和设计的可扩展性,是更符合 Rust 风格和稳健软件设计原则的做法。

方案二(Downcasting) 是一个可行的备选方案,特别是当您无法或不想修改 Filesystem trait 的现有签名时。它能快速解决问题,但从长远来看,其设计不如方案一清晰。

考虑到您正在进行重构,这是一个引入更清晰设计(如方案一)的绝佳时机。

self.forget(ctx, v.attr.ino, 1).await;
// File exists with same name, create whiteout file is not allowed.
return Err(Error::from_raw_os_error(libc::EEXIST).into());
) -> impl std::future::Future<Output = Result<ReplyEntry>> + Send {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里将原有异步函数改为同步的原因可以在注释中加以说明,便于其他人理解

@genedna genedna requested a review from Copilot October 28, 2025 01:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.

} else {
(layer.is_whiteout(ctx, v.attr.ino).await?, false)
};
let (whiteout, opaque) = (false, false);
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding whiteout and opaque to false removes critical overlay filesystem functionality. The original code called layer.is_whiteout() and layer.is_opaque() to detect whiteout files and opaque directories, which are essential for proper overlay semantics. This change will break the ability to handle deleted files and merged directories correctly.

Suggested change
let (whiteout, opaque) = (false, false);
let whiteout = self.layer.is_whiteout(v.attr.ino).await.unwrap_or(false);
let opaque = self.layer.is_opaque(v.attr.ino).await.unwrap_or(false);

Copilot uses AI. Check for mistakes.
} else {
false
};
let opaque = false;
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding opaque to false in the link operation removes the check for opaque directories. The original code correctly checked if the linked entry is a directory and called is_opaque() to determine if the directory should be marked opaque. This breaks the overlay directory merging semantics.

Copilot uses AI. Check for mistakes.
layer.is_opaque(ctx, ino).await?,
)
.await;
let real = RealInode::new(layer.clone(), true, ino, false, false).await;
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding the opaque parameter to false when creating the root upper inode ignores whether the root directory is actually opaque. The original code called layer.is_opaque(ctx, ino).await? to determine this. This will break correct overlay behavior for the root directory.

Suggested change
let real = RealInode::new(layer.clone(), true, ino, false, false).await;
let opaque = layer.is_opaque(&ctx, ino).await?;
let real = RealInode::new(layer.clone(), true, ino, opaque, false).await;

Copilot uses AI. Check for mistakes.
layer.is_opaque(ctx, ino).await?,
)
.await;
let real: RealInode<L> = RealInode::new(layer.clone(), false, ino, false, false).await;
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding the opaque parameter to false when creating root lower inodes ignores whether these directories are actually opaque. The original code called layer.is_opaque(ctx, ino).await? to check this. This breaks proper directory merging in the overlay filesystem.

Suggested change
let real: RealInode<L> = RealInode::new(layer.clone(), false, ino, false, false).await;
let opaque = layer.is_opaque(&ctx, ino).await?;
let real: RealInode<L> = RealInode::new(layer.clone(), false, ino, opaque, false).await;

Copilot uses AI. Check for mistakes.
Comment on lines 18 to 19
#[async_trait]
pub trait Layer: Filesystem + Send + Sync + 'static {
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trait already requires Send + Sync + 'static in its definition, but individual methods still have where Self: Send clauses (e.g., line 111). This is redundant since the trait bound already ensures Self: Send. Consider removing the redundant where Self: Send clauses from method signatures.

Copilot uses AI. Check for mistakes.
) -> Result<(libc::stat64, Duration)> {
self.do_getattr_helper(inode, handle)
.await
.map_err(Into::into)
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .map_err(Into::into) is unnecessary here. Since do_getattr_helper already returns a compatible error type and the function signature expects Result<(libc::stat64, Duration)>, the error conversion is redundant. Consider removing it.

Suggested change
.map_err(Into::into)

Copilot uses AI. Check for mistakes.
Comment on lines 27 to 32
fn create_whiteout(
&self,
ctx: Request,
parent: Inode,
name: &OsStr,
) -> Result<ReplyEntry> {
// Use temp value to avoid moved 'parent'.
let ino: u64 = parent;
match self.lookup(ctx, ino, name).await {
Ok(v) => {
// Find whiteout char dev.
if is_whiteout(&v.attr) {
return Ok(v);
}
// Non-negative entry with inode larger than 0 indicates file exists.
if v.attr.ino != 0 {
// Decrease the refcount.
self.forget(ctx, v.attr.ino, 1).await;
// File exists with same name, create whiteout file is not allowed.
return Err(Error::from_raw_os_error(libc::EEXIST).into());
) -> impl std::future::Future<Output = Result<ReplyEntry>> + Send {
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method signature changed from async fn to fn returning impl Future, but the documentation comment on line 23-26 still describes it as if it's an async fn. Consider updating the doc comment to clarify this is a trait method returning a future, or explain why this pattern is used instead of async fn in traits.

Copilot uses AI. Check for mistakes.
@songhahaha66 songhahaha66 marked this pull request as draft October 28, 2025 14:44
@songhahaha66 songhahaha66 changed the title feat(overlay): Replace PassthroughFS with Layer Trait [WIP]feat(overlay): Replace PassthroughFS with Layer Trait Oct 28, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

layer.is_opaque(ctx, ino).await?,
)
.await;
let real: RealInode<L> = RealInode::new(layer.clone(), false, ino, false, false).await;
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The opaque parameter (5th argument) is hardcoded to false for lower layers. This should check layer.is_opaque(ctx, ino) to correctly handle opaque directories in lower layers.

Suggested change
let real: RealInode<L> = RealInode::new(layer.clone(), false, ino, false, false).await;
let opaque = layer.is_opaque(&ctx, ino).await;
let real: RealInode<L> = RealInode::new(layer.clone(), false, ino, opaque, false).await;

Copilot uses AI. Check for mistakes.
Comment on lines 27 to 33
fn create_whiteout(
&self,
ctx: Request,
parent: Inode,
name: &OsStr,
) -> Result<ReplyEntry> {
// Use temp value to avoid moved 'parent'.
let ino: u64 = parent;
match self.lookup(ctx, ino, name).await {
Ok(v) => {
// Find whiteout char dev.
if is_whiteout(&v.attr) {
return Ok(v);
}
// Non-negative entry with inode larger than 0 indicates file exists.
if v.attr.ino != 0 {
// Decrease the refcount.
self.forget(ctx, v.attr.ino, 1).await;
// File exists with same name, create whiteout file is not allowed.
return Err(Error::from_raw_os_error(libc::EEXIST).into());
) -> impl std::future::Future<Output = Result<ReplyEntry>> + Send {
async move {
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conversion from async fn to fn returning impl Future changes the trait's API contract. Methods using async move blocks will capture self by value rather than by reference, which could cause ownership issues for trait implementers. Consider using #[async_trait] for these methods instead, or explicitly specify lifetime bounds if the impl Future pattern is required.

Copilot uses AI. Check for mistakes.
Comment on lines 109 to 112
) -> impl std::future::Future<Output = Result<bool>> + Send
where
Self: Send,
{
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The where Self: Send clause is redundant because the trait already requires Send + Sync + 'static on line 19. Remove the unnecessary where clause.

Suggested change
) -> impl std::future::Future<Output = Result<bool>> + Send
where
Self: Send,
{
) -> impl std::future::Future<Output = Result<bool>> + Send {

Copilot uses AI. Check for mistakes.
@songhahaha66 songhahaha66 changed the title [WIP]feat(overlay): Replace PassthroughFS with Layer Trait feat(overlay): Replace PassthroughFS with Layer Trait Nov 3, 2025
@songhahaha66 songhahaha66 marked this pull request as ready for review November 3, 2025 08:22
@songhahaha66 songhahaha66 marked this pull request as ready for review November 3, 2025 08:22
Ivanbeethoven
Ivanbeethoven previously approved these changes Nov 3, 2025
@genedna genedna requested a review from Copilot November 3, 2025 15:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 14 out of 16 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

project/libfuse-fs/src/unionfs/tempfile.rs:1

  • The tempfile module is commented out in the imports but the file exists with full implementation and tests. Either remove the comment to enable the module or remove the unused file to avoid confusion about whether this code is intended to be active.
// Copyright 2017 The Chromium OS Authors. All rights reserved.

Ok(v1) => Ok(Some(v1)),
Err(e) => match e.raw_os_error() {
Some(raw_error) => {
if raw_error != libc::ENOENT || raw_error != libc::ENAMETOOLONG {
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect logical operator in error condition check. The condition raw_error != libc::ENOENT || raw_error != libc::ENAMETOOLONG will always evaluate to true for any raw_error value. If raw_error equals ENOENT, the second part is true; if it equals ENAMETOOLONG, the first part is true; if it's neither, both parts are true. This should use && (AND) instead of || (OR) to correctly check if the error is neither ENOENT nor ENAMETOOLONG: if raw_error != libc::ENOENT && raw_error != libc::ENAMETOOLONG.

Suggested change
if raw_error != libc::ENOENT || raw_error != libc::ENAMETOOLONG {
if raw_error == libc::ENOENT || raw_error == libc::ENAMETOOLONG {

Copilot uses AI. Check for mistakes.
@Ivanbeethoven Ivanbeethoven added this pull request to the merge queue Nov 4, 2025
Merged via the queue into rk8s-dev:main with commit 44799b9 Nov 4, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants