libfuse3低级API读取文件时挂起问题求助
问题
我用libfuse的低级API写了一个C++实现的用户态文件系统,已经实现了lookup、forget、getattr、setattr、mknod、read、write、opendir、readdir和releasedir这些函数。初始化时在根目录创建了几个测试文件,测试读写时发现写入能成功,但读取操作会导致FUSE挂起。
操作日志
unique: 302, opcode: LOOKUP (1), nodeid: 1, insize: 46, pid: 444120 <---- echo foo >cat mnt/foo unique: 302, success, outsize: 144 unique: 304, opcode: OPEN (14), nodeid: 2, insize: 48, pid: 444120 unique: 304, success, outsize: 32 unique: 306, opcode: GETXATTR (22), nodeid: 2, insize: 68, pid: 444120 unique: 306, error: -38 (Function not implemented), outsize: 16 unique: 308, opcode: FLUSH (25), nodeid: 2, insize: 64, pid: 444120 unique: 308, error: -38 (Function not implemented), outsize: 16 unique: 310, opcode: WRITE (16), nodeid: 2, insize: 84, pid: 444120 unique: 310, success, outsize: 24 unique: 312, opcode: LOOKUP (1), nodeid: 1, insize: 46, pid: 477019 <---- cat mnt/foo unique: 312, success, outsize: 144 unique: 314, opcode: OPEN (14), nodeid: 2, insize: 48, pid: 477019 unique: 314, success, outsize: 32
奇怪的是,空文件可以正常用cat读取,但写入内容后FUSE就会挂起。我已经启用了单线程模式,但调试起来很困难,因为挂起发生在我的回调函数执行之后。
文件foo的stat信息
File: mnt/foo Size: 4 Blocks: 8 IO Block: 4096 regular file Device: 59h/89d Inode: 2 Links: 1 Access: (0666/-rw-rw-rw-) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2023-10-24 21:04:25.000000000 -0100 Modify: 2023-10-24 21:04:25.000000000 -0100 Change: 2023-10-24 21:04:25.000000000 -0100 Birth: -
可能的问题方向
- READ回调的响应逻辑错误:从日志看,
cat操作完成LOOKUP和OPEN后没有后续请求的响应,说明READ请求已发送但程序未正确处理:- 检查是否正确将数据拷贝到READ回调的
buf参数中,如果写入内容后读取时未填充数据或拷贝长度错误,会导致FUSE等待。 - 确认返回值是否合规:成功读取时返回实际读取的字节数,到文件末尾需返回0,错误场景返回对应负错误码。返回无效值会导致FUSE挂起。
- 检查是否正确将数据拷贝到READ回调的
- 文件元数据与实际存储不一致:stat显示文件Size为4(对应"foo\n"的长度),但如果内部存储的实际数据长度与
st_size不匹配,cat会持续尝试读取直到达到st_size,导致死等。需确认写入操作后是否同步更新了内部存储的长度,以及getattr返回的st_size是否准确。 - OPEN回调的状态初始化错误:检查OPEN回调是否正确设置了文件的打开状态(如读写模式标记),若写入后文件状态被错误标记,可能导致READ回调无法触发或内部逻辑卡住。
- 单线程模式下的隐性阻塞:即使挂起发生在回调之后,也要排查READ回调中是否存在隐性阻塞操作,比如等待未触发的条件变量、访问未初始化资源导致死循环,单线程模式下任何阻塞都会导致整个FUSE进程挂起。
- 遗漏FUSE请求回复:确认是否在READ回调中调用了
fuse_reply_buf等低级API函数回复请求,若忘记回复,FUSE内核会一直等待用户态程序的响应,表现为挂起。
内容的提问来源于stack exchange,提问作者Caian
相关产品推荐
相关产品推荐

