如何在FUSE文件系统的write()操作中返回ENOSPC错误?
在FUSE文件系统中返回ENOSPC错误的实现方法
FUSE的write回调并非只能返回写入的字节数,当遇到空间不足这类错误时,直接返回负的errno值即可向用户空间传递正确的错误码,具体实现如下:
预检查剩余空间:在执行写入操作前,先计算本次写入需要的空间,对比文件系统剩余容量。如果空间不足,直接返回
-ENOSPC:int my_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { // 计算本次写入需要的总空间(需考虑文件当前大小与offset的关系) size_t needed_space = size; if (offset > get_file_size(path)) { needed_space += offset - get_file_size(path); // 处理文件空洞的情况 } size_t free_space = get_fs_free_space(); // 自定义函数获取文件系统剩余空间 if (needed_space > free_space) { return -ENOSPC; // 直接返回空间不足错误 } // 执行实际写入逻辑 ssize_t written = perform_write(path, buf, size, offset, fi); if (written < 0) { return written; // 返回其他写入错误 } return written; }处理中途空间不足的情况:如果写入过程中才发现空间不足,需要回滚已写入的部分数据,再返回
-ENOSPC。因为FUSE要求write要么完成全部请求(除非挂载时指定direct_io),不能返回部分写入的字节数,否则内核会默认返回EIO错误。适配copy_file_range调用:当用户使用
copy_file_range(如cp命令)时,FUSE内核模块会将其转换为对应的write操作请求,只要write回调正确返回-ENOSPC,内核就会将该错误码传递给用户空间,此时cp命令会收到正确的"设备上没有剩余空间"错误,而非EIO。
注意:FUSE的所有操作回调都支持返回负的errno值来表示错误,这是API的标准用法,只是文档未重点强调。之前出现EIO错误,是因为当write返回的写入字节数小于请求大小且未主动返回错误码时,FUSE内核会默认返回EIO。
内容的提问来源于stack exchange,提问作者t-w
相关产品推荐
相关产品推荐

