Ubuntu22虚拟机FUSE文件系统ls报错:Input/output error求助
问题排查与修复方案
1. 根节点初始化不完整
你定义的根节点仅初始化了path字段,num_children、permissions、user_id等关键字段都是未初始化的垃圾值。getattr访问这些值时,会触发不可预测的错误,最终导致内核返回IO错误。
修复:完整初始化根节点,示例代码:
#include <unistd.h> #include <time.h> struct filetype *dfs_tree_root = &(struct filetype){ .path="/", .num_children=0, .user_id=getuid(), // 挂载用户的UID .group_id=getgid(), // 挂载用户的GID .permissions=S_IFDIR | 0755, // 标记为目录+读写执行权限 .num_links=2, // 目录硬链接数至少为2(自身和父目录) .size=4096, // 目录默认大小 .a_time=time(NULL), .m_time=time(NULL), .c_time=time(NULL) };
2. getattr未清空stat结构体
FUSE要求填充stbuf前必须先清空结构体,内存中的残留数据会导致内核解析失败,触发IO错误。
修复:在getattr开头添加清空代码:
static int dfs_getattr(const char *path, struct stat *stbuf) { printf( "Called [getattr]\n" ); printf( "\tAttributes of %s requested\n", path ); memset(stbuf, 0, sizeof(struct stat)); // 新增这行,清空结构体 // ... 剩余代码 }
3. 路径查找的逻辑验证
当传入路径为"/"时,strlen(path)为1,会进入路径分割逻辑。此时strtok("/", "/")返回NULL,循环不执行直接返回根节点,这部分逻辑没问题,但要确保子节点的path字段存储的是相对父目录的文件名(比如"test"而非"/test"),否则strcmp(current->children[i]->path, component)无法匹配到子节点。
4. 调试补充
挂载时已启用-d调试模式,可通过终端输出定位问题:
- 若看不到
Called [getattr]输出,说明struct fuse_operations中getattr字段未正确指向dfs_getattr,需检查操作结构体的注册代码。 - 若看到
GETATTR /但返回错误,说明根节点查找失败或stat字段填充有误。
内容的提问来源于stack exchange,提问作者redhunter
相关产品推荐
相关产品推荐

