不能 "read" 任何东西通过 FUSE 文件系统

Can not "read" anything through the FUSE file system

我在MIT 6.824实验室用fuse搭建了自己的文件系统,read操作就是在这个函数中实现的

void
fuseserver_read(fuse_req_t req, fuse_ino_t ino, size_t size,
        off_t off, struct fuse_file_info *fi)
{
    std::string buf;
    int r;
    if ((r = yfs->read(ino, size, off, buf)) == yfs_client::OK) {

        char* retbuf = (char *)malloc(buf.size());
        memcpy(retbuf,buf.data(),buf.size());
        //Print the information of the result.
        printf("debug read in fuse: the content of %lu is %s, size %lu\n",ino,retbuf, buf.size());

       fuse_reply_buf(req,retbuf,buf.size());    
    } else {
        fuse_reply_err(req, ENOENT);
    }

//global definition
//struct fuse_lowlevel_ops fuseserver_oper;

//In main()
//    fuseserver_oper.read       = fuseserver_read;

我把前面的buf的信息打印出来return。

write操作当然也实现了

然后我运行一个简单的测试来读出一些单词。

//test.c
int main(){
    //./yfs1 is the mount point of my filesystem
    int fd = open("./yfs1/test-file",O_RDWR | O_CREAT,0777);
    char* buf = "123";
    char* readout;
    readout = (char *)malloc(3);
    int writesize = write(fd,buf,3);
    int readsize = read(fd,readout,3);
    printf("%s,%d\n",buf,writesize);
    printf("%s,%d\n",readout,readsize);
    close(fd);
}

我read(fd,readout,3)什么也得不到,但是fuseserver_read打印的信息显示在fuse_reply_buf

之前buffer读出成功
$ ./test
123,3
,0
debug read in fuse: the content of 2 is 123, size 3

那么为什么 test.c 中的 read() 无法从我的文件系统中读取任何内容??

还需要通过发送一个空缓冲区来通知您已完成阅读,作为 "EOF"。您可以使用 reply_buf_limited 来做到这一点。 查看 fuse source tree 中的 hello_ll 示例:

static void tfs_read(fuse_req_t req, fuse_ino_t ino, size_t size,
                     off_t off, struct fuse_file_info *fi) {
    (void) fi;

    assert(ino == FILE_INO);
    reply_buf_limited(req, file_contents, file_size, off, size);
}

static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
                 off_t off, size_t maxsize)
{
    if (off < bufsize)
        return fuse_reply_buf(req, buf + off,
                      min(bufsize - off, maxsize));
    else
        return fuse_reply_buf(req, NULL, 0);
}

首先,我在编写测试文件时犯了一个错误。 "write"之后文件指针会指向文件末尾,当然后面什么也读不到了。所以只需重新打开文件即可使测试正常进行。 其次,在FUSE的read()操作之前,FUSE会先getattr(),将read()操作的结果截断为文件的"size"属性。所以操作文件的属性必须非常小心。