You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义FUSE文件系统执行ls命令报I/O错误原因排查求助

错误根因排查

你遇到的getdents64返回EIO错误由多个代码缺陷共同导致,最直接的触发原因有两个:

  1. ll_readdir函数只处理了ino=1的根目录请求,其他情况直接返回没有调用任何FUSE回复接口,FUSE框架收不到响应会默认返回EIO
  2. 填充完目录项后调用fuse_reply_buf时传入了完整的buf长度size,而不是实际写入的有效字节数,内核解析到无效的目录项结构直接返回I/O错误

其他必须修复的代码缺陷

1. sendmailfs_stat根目录权限被覆盖

根目录(ino=1)的st_mode赋值逻辑有重复覆盖问题:

// 先赋值了带权限的模式
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
stbuf->st_uid = uid;
// 这里又覆盖成了只有S_IFDIR标记,清空了权限位,直接删掉这行即可
stbuf->st_mode = S_IFDIR;

2. ll_readdir逻辑缺陷

2.1 缺少非根目录请求处理

你的文件系统不允许创建子目录,所以非ino=1的目录请求直接返回ENOTDIR错误即可,必须调用FUSE回复接口:

if (ino != 1) {
    fuse_reply_err(req, ENOTDIR);
    return;
}

2.2 未处理内核传入的偏移参数off

内核调用readdir时会传入当前读取的偏移,你完全忽略该参数每次都从0开始填充,多次读取时会返回重复内容,需要跳过偏移之前的目录项。

2.3 混用两种目录项填充API

fuse_add_direntry和fuse_add_direntry_plus生成的目录项结构完全不同,不能混着用:

  • 如果你没有开启FUSE的FUSE_CAP_READDIR_PLUS能力,全部改用fuse_add_direntry即可
  • 如果要使用plus接口,必须在fuse初始化时声明对应能力,且全部条目都用plus接口填充

2.4 缺少..目录项

标准目录必须包含.和..两个默认条目,你只加了.,需要补充..的条目,对应ino也为1(根目录的父目录指向自己)。

2.5 未判断填充返回值+回复长度错误

每次调用fuse_add_direntry后要判断返回值:返回0说明buf剩余空间不足,要停止填充。最终回复的长度是size - rest,不是完整的size,用完的buf要记得释放避免内存泄漏:

// 填充结束后调用
fuse_reply_buf(req, buf, size - rest);
free(buf);

2.6 非法访问私有成员+无锁遍历

mutex_map的_data是私有成员,你在外部直接遍历属于非法访问,要在mutex_map中加公共的遍历接口,且遍历的时候必须加锁,避免多线程读写冲突。


内容的提问来源于stack exchange,提问作者KiYugadgeter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:24:01