1

这是一个有点奇怪的问题。我正在使用go-fuse库编写一个 fuse 模块,目前我有一个大小为 6000 字节的“假”文件,它将为所有读取请求输出一些不相关的数据。我的读取函数如下所示:

func (f *MyFile) Read(buf []byte, off int64) (fuse.ReadResult, fuse.Status) {
    log.Printf("Reading into buffer of len %d from %d\n",len(buf),off)
    FillBuffer(buf, uint64(off), f.secret)
    return fuse.ReadResultData(buf), fuse.OK
}

如您所见,我正在输出包含读取请求范围的每个读取的日志。奇怪的是,当我cat得到以下文件时:

2013/09/13 21:09:03 Reading into buffer of len 4096 from 0
2013/09/13 21:09:03 Reading into buffer of len 8192 from 0

cat显然是读取前 4096 个字节的数据,将其丢弃,然后读取 8192 个字节,其中包含所有数据,因此成功。我也尝试过其他程序,包括hexdumpand vim,它们都做同样的事情。有趣的是,如果我执行 a head -c 3000 dir/fakefile,它仍然会执行两次读取,即使后者完全没有必要。有没有人对为什么会发生这种情况有任何见解?

4

1 回答 1

2

我建议你 strace 你的 cat 进程来亲自看看。在我的系统上, cat 读取 64K 块,并执行最终的 read() 以确保它读取整个文件。最后一个 read() 对于区分读取“块大小的文件”和更大的文件是必要的。即,它确保没有任何内容可供读取,因为文件大小可能在 fstat() 和 read() 系统调用之间发生了变化。

stat/fstat() 系统调用是否将您的“假文件”大小正确返回给 FUSE?

于 2013-09-14T04:59:01.103 回答