不能 "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"属性。所以操作文件的属性必须非常小心。
我在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
$ ./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"属性。所以操作文件的属性必须非常小心。