【发布时间】:2020-10-21 16:34:14
【问题描述】:
我最近正在研究 fuse,但由于我对 linux 中的文件系统知之甚少,因此仍然无法掌握它的工作原理。最令人困惑的事情之一是 如果我使用系统调用 open() 在 fuse_operation "open" 的函数中打开一个文件会发生什么,就像下面的 code
int bb_open(const char *path, struct fuse_file_info *fi)
{
int retstat = 0;
int fd;
char fpath[PATH_MAX];
bb_fullpath(fpath, path);
log_msg("bb_open(fpath\"%s\", fi=0x%08x)\n",
fpath, (int) fi);
fd = open(fpath, fi->flags);
if (fd < 0)
retstat = bb_error("bb_open open");
fi->fh = fd;
log_fi(fi);
return retstat;
}
我的假设是:
- 正在打开此文件系统(“myfilesystem”)中的文件,请求最终被 fuse 接受并调用 bb_open()。
- 当执行到达 "fd = open(fpath, fi->flags)" 时,它将再次 open() 该文件系统中的一个文件,然后返回到第一步,然后是一个循环。
但是在尝试了代码之后,它实际上最终成功地打开了文件,这让我感到困惑。我错过了什么重要的事情吗?希望我能理解这个问题,并提前感谢!
编辑
感谢大家的帮助!但我仍然无法得到 user253751 提到的死锁,我想我应该在这里发布更多细节:
static int hello_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
(void) fi;
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path+1, "hello") == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen("hello there");
} else
res = -ENOENT;
return res;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{
(void) offset;
(void) fi;
(void) flags;
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0, 0);
filler(buf, "..", NULL, 0, 0);
filler(buf, "hello", NULL, 0, 0);
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
char* fpath = get_full_path(path);
int fd = open(fpath,O_RDONLY);
fi->fh = fd;
log1(fpath);
log1(" open\n");
return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
char* fpath = get_full_path(path);
read(fi->fh,buf,size);
log1(fpath);
log1(" read\n");
return size;
}
基本上我使用 hello_readdir() 将文件名填充到目录中,然后告诉 hello_getattr() 获取文件的一些随机信息。然后我 "tail" 文件五次,这就是我从 log
得到的/home/P1G3s/WorkSpace/PIT/libfuse-fuse-3.9.2/example/hello open
/home/P1G3s/WorkSpace/PIT/libfuse-fuse-3.9.2/example/hello read
/home/P1G3s/WorkSpace/PIT/libfuse-fuse-3.9.2/example/hello open
/home/P1G3s/WorkSpace/PIT/libfuse-fuse-3.9.2/example/hello open
/home/P1G3s/WorkSpace/PIT/libfuse-fuse-3.9.2/example/hello open
我认为它不应该打开一个不存在的文件,但似乎 open() 运行良好并且没有发生死锁,但是在第一个尾部之后读取不会显示。
【问题讨论】:
-
bb_fullpath生成的路径是否在 FUSE 文件系统的挂载点之外? -
path 和 fpath 的一些示例值是什么?
-
另外,您对
open()的使用不正确。如果open()调用可以创建文件,则需要第三个参数来指定创建文件的初始权限。 -
哦,是的,我觉得我创建文件的方式有点奇怪,我用libfuse的例子“hello”做的方法,文件是通过readdir操作下的filler()添加的,这是否意味着打开的文件只是一个名称?
-
@Ian Abbott 对不起,我没有使用 bb_fullpath(),我只是手动输入路径,文件就在挂载点的正下方。我尝试了相对路径和绝对路径,在这两种情况下都成功打开了文件。我正在使用python打开文件,它似乎打开了文件。
标签: c filesystems system-calls fuse