注册时:
example/hello.c
main ->
fuse_main(argc, argv, &hello_oper, NULL)//hello_oper ->
fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)//op ->
fuse_main_common(argc, argv, op, op_size, user_data, 0);//op ->
fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,&multithreaded, NULL, user_data, compat);//op ->
|//fuse结构体变量fuse即经过一下多层操作最终得到的返回值,其成员变量se含有我们注册函数的信息
| fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);//op ->
| //此函数中使用了fuse自己提供的lowlevel的op struct fuse_lowlevel_ops llop = fuse_path_ops;
| //且定义了fuse结构体变量f,f->fs->op即用户定义的op
| f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f); ->
| //struct fuse_session *fuse_lowlevel_new_common
| //(struct fuse_args *args,const struct fuse_lowlevel_ops *op,size_t op_size, void *userdata)
| //注意参数对比,f形参名为userdata,而fuse自己提供的llop则赋予形参op
| //fuse_lowlevel_new_common中定义了fuse_ll结构体变量f,和fuse_session结构体变量se作为返回值
| struct fuse_session_ops sop = {.process = fuse_ll_process,.destroy = fuse_ll_destroy,};
| memcpy(&f->op, op, op_size);//llop则赋予fuse_ll结构体变量f中的op成员
| f->userdata = userdata;//userdata即fuse结构体变量f
| se = fuse_session_new(&sop, f); ->
| |//struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
| |//data即fuse_ll结构体变量f,含有llop(f->op)和用户定义的操作(f->userdata->fs->op)
| | se->op = *op;
| | se->data = data;//se->data即fuse_ll结构体变量f,含有所有所需信息
| se->receive_buf = fuse_ll_receive_buf;
| se->process_buf = fuse_ll_process_buf;//fuse_ll_process_buf函数完成调用过程,在守护进程循环中会被调用
|
| 至此,lowlevel op, highlevel op, session op都聚集在fuse_session结构体变量se中,而se是fuse结构体变量的成员。
| 注册完成。
|
守护进程的循环过程:
|
|
|
int res = fuse_loop(fuse);//单线程情况 ->
return fuse_session_loop(f->se); ->
//int fuse_session_loop(struct fuse_session *se)
fuse_session_process_buf(se, &fbuf, tmpch); ->
//int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,struct fuse_chan **chp)
se->process_buf(se->data, buf, ch); ->
//如上所述,process_buf已经被注册为fuse自己提供的fuse_ll_process_buf
//static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,struct fuse_chan *ch)
//se->data即fuse_ll结构体变量f,含有所有所需信息
struct fuse_ll *f = (struct fuse_ll *) data;
req = fuse_ll_alloc_req(f); ->
|//static struct fuse_req *fuse_ll_alloc_req(struct fuse_ll *f)
| req->f = f;
fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);//req->f即fuse_ll结构体变量f ->
static struct {
void (*func)(fuse_req_t, fuse_ino_t, const void *);
const char *name;
} fuse_ll_ops[] = {
[FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
[FUSE_FORGET] = { do_forget, "FORGET" },
[FUSE_GETATTR] = { do_getattr, "GETATTR" },
[FUSE_SETATTR] = { do_setattr, "SETATTR" },
[FUSE_READLINK] = { do_readlink, "READLINK" },
[FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
[FUSE_MKNOD] = { do_mknod, "MKNOD" },
[FUSE_MKDIR] = { do_mkdir, "MKDIR" },
[FUSE_UNLINK] = { do_unlink, "UNLINK" },
[FUSE_RMDIR] = { do_rmdir, "RMDIR" },
[FUSE_RENAME] = { do_rename, "RENAME" },
[FUSE_LINK] = { do_link, "LINK" },
[FUSE_OPEN] = { do_open, "OPEN" },
[FUSE_READ] = { do_read, "READ" },
[FUSE_WRITE] = { do_write, "WRITE" },
[FUSE_STATFS] = { do_statfs, "STATFS" },
[FUSE_RELEASE] = { do_release, "RELEASE" },
[FUSE_FSYNC] = { do_fsync, "FSYNC" },
[FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
[FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
[FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
[FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
[FUSE_FLUSH] = { do_flush, "FLUSH" },
[FUSE_INIT] = { do_init, "INIT" },
[FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
[FUSE_READDIR] = { do_readdir, "READDIR" },
[FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
[FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
[FUSE_GETLK] = { do_getlk, "GETLK" },
[FUSE_SETLK] = { do_setlk, "SETLK" },
[FUSE_SETLKW] = { do_setlkw, "SETLKW" },
[FUSE_ACCESS] = { do_access, "ACCESS" },
[FUSE_CREATE] = { do_create, "CREATE" },
[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
[FUSE_BMAP] = { do_bmap, "BMAP" },
[FUSE_IOCTL] = { do_ioctl, "IOCTL" },
[FUSE_POLL] = { do_poll, "POLL" },
[FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" },
[FUSE_DESTROY] = { do_destroy, "DESTROY" },
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
[CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
}; ->(例如do_open)
static void do_open(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) ->
//req->f即fuse_ll结构体变量f,而req->f->op是lowlevel的op,
//对于实现highlevel接口的情况,这里的op即fuse自己提供的上文所述的fuse_path_ops,如下
//static struct fuse_lowlevel_ops fuse_path_ops = {
.init = fuse_lib_init,
.destroy = fuse_lib_destroy,
.lookup = fuse_lib_lookup,
.forget = fuse_lib_forget,
.forget_multi = fuse_lib_forget_multi,
.getattr = fuse_lib_getattr,
.setattr = fuse_lib_setattr,
.access = fuse_lib_access,
.readlink = fuse_lib_readlink,
.mknod = fuse_lib_mknod,
.mkdir = fuse_lib_mkdir,
.unlink = fuse_lib_unlink,
.rmdir = fuse_lib_rmdir,
.symlink = fuse_lib_symlink,
.rename = fuse_lib_rename,
.link = fuse_lib_link,
.create = fuse_lib_create,
.open = fuse_lib_open,
.read = fuse_lib_read,
.write_buf = fuse_lib_write_buf,
.flush = fuse_lib_flush,
.release = fuse_lib_release,
.fsync = fuse_lib_fsync,
.opendir = fuse_lib_opendir,
.readdir = fuse_lib_readdir,
.releasedir = fuse_lib_releasedir,
.fsyncdir = fuse_lib_fsyncdir,
.statfs = fuse_lib_statfs,
.setxattr = fuse_lib_setxattr,
.getxattr = fuse_lib_getxattr,
.listxattr = fuse_lib_listxattr,
.removexattr = fuse_lib_removexattr,
.getlk = fuse_lib_getlk,
.setlk = fuse_lib_setlk,
.flock = fuse_lib_flock,
.bmap = fuse_lib_bmap,
.ioctl = fuse_lib_ioctl,
.poll = fuse_lib_poll,
.fallocate = fuse_lib_fallocate,
};
req->f->op.open(req, nodeid, &fi); ->
//.open = fuse_lib_open,
static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,struct fuse_file_info *fi) ->
fuse *f = req_fuse_prepare(req);//f = req->f->userdata
|
err = fuse_fs_open(f->fs, path, fi); ->
err = fuse_compat_open(fs, path, fi); ->
fs->op.open(path, fi);//即用户自己定义的open操作
//至此完成open操作
守护进程完成一次操作
注:本文重点介绍了用户自己完成的highlevel函数的注册到最终被调用的完全追踪,不包含fuse内核模块与守护进程的交互过程。
example/hello.c
main ->
fuse_main(argc, argv, &hello_oper, NULL)//hello_oper ->
fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)//op ->
fuse_main_common(argc, argv, op, op_size, user_data, 0);//op ->
fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,&multithreaded, NULL, user_data, compat);//op ->
|//fuse结构体变量fuse即经过一下多层操作最终得到的返回值,其成员变量se含有我们注册函数的信息
| fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);//op ->
| //此函数中使用了fuse自己提供的lowlevel的op struct fuse_lowlevel_ops llop = fuse_path_ops;
| //且定义了fuse结构体变量f,f->fs->op即用户定义的op
| f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f); ->
| //struct fuse_session *fuse_lowlevel_new_common
| //(struct fuse_args *args,const struct fuse_lowlevel_ops *op,size_t op_size, void *userdata)
| //注意参数对比,f形参名为userdata,而fuse自己提供的llop则赋予形参op
| //fuse_lowlevel_new_common中定义了fuse_ll结构体变量f,和fuse_session结构体变量se作为返回值
| struct fuse_session_ops sop = {.process = fuse_ll_process,.destroy = fuse_ll_destroy,};
| memcpy(&f->op, op, op_size);//llop则赋予fuse_ll结构体变量f中的op成员
| f->userdata = userdata;//userdata即fuse结构体变量f
| se = fuse_session_new(&sop, f); ->
| |//struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
| |//data即fuse_ll结构体变量f,含有llop(f->op)和用户定义的操作(f->userdata->fs->op)
| | se->op = *op;
| | se->data = data;//se->data即fuse_ll结构体变量f,含有所有所需信息
| se->receive_buf = fuse_ll_receive_buf;
| se->process_buf = fuse_ll_process_buf;//fuse_ll_process_buf函数完成调用过程,在守护进程循环中会被调用
|
| 至此,lowlevel op, highlevel op, session op都聚集在fuse_session结构体变量se中,而se是fuse结构体变量的成员。
| 注册完成。
|
守护进程的循环过程:
|
|
|
int res = fuse_loop(fuse);//单线程情况 ->
return fuse_session_loop(f->se); ->
//int fuse_session_loop(struct fuse_session *se)
fuse_session_process_buf(se, &fbuf, tmpch); ->
//int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,struct fuse_chan **chp)
se->process_buf(se->data, buf, ch); ->
//如上所述,process_buf已经被注册为fuse自己提供的fuse_ll_process_buf
//static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,struct fuse_chan *ch)
//se->data即fuse_ll结构体变量f,含有所有所需信息
struct fuse_ll *f = (struct fuse_ll *) data;
req = fuse_ll_alloc_req(f); ->
|//static struct fuse_req *fuse_ll_alloc_req(struct fuse_ll *f)
| req->f = f;
fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);//req->f即fuse_ll结构体变量f ->
static struct {
void (*func)(fuse_req_t, fuse_ino_t, const void *);
const char *name;
} fuse_ll_ops[] = {
[FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
[FUSE_FORGET] = { do_forget, "FORGET" },
[FUSE_GETATTR] = { do_getattr, "GETATTR" },
[FUSE_SETATTR] = { do_setattr, "SETATTR" },
[FUSE_READLINK] = { do_readlink, "READLINK" },
[FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
[FUSE_MKNOD] = { do_mknod, "MKNOD" },
[FUSE_MKDIR] = { do_mkdir, "MKDIR" },
[FUSE_UNLINK] = { do_unlink, "UNLINK" },
[FUSE_RMDIR] = { do_rmdir, "RMDIR" },
[FUSE_RENAME] = { do_rename, "RENAME" },
[FUSE_LINK] = { do_link, "LINK" },
[FUSE_OPEN] = { do_open, "OPEN" },
[FUSE_READ] = { do_read, "READ" },
[FUSE_WRITE] = { do_write, "WRITE" },
[FUSE_STATFS] = { do_statfs, "STATFS" },
[FUSE_RELEASE] = { do_release, "RELEASE" },
[FUSE_FSYNC] = { do_fsync, "FSYNC" },
[FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
[FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
[FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
[FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
[FUSE_FLUSH] = { do_flush, "FLUSH" },
[FUSE_INIT] = { do_init, "INIT" },
[FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
[FUSE_READDIR] = { do_readdir, "READDIR" },
[FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
[FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
[FUSE_GETLK] = { do_getlk, "GETLK" },
[FUSE_SETLK] = { do_setlk, "SETLK" },
[FUSE_SETLKW] = { do_setlkw, "SETLKW" },
[FUSE_ACCESS] = { do_access, "ACCESS" },
[FUSE_CREATE] = { do_create, "CREATE" },
[FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
[FUSE_BMAP] = { do_bmap, "BMAP" },
[FUSE_IOCTL] = { do_ioctl, "IOCTL" },
[FUSE_POLL] = { do_poll, "POLL" },
[FUSE_FALLOCATE] = { do_fallocate, "FALLOCATE" },
[FUSE_DESTROY] = { do_destroy, "DESTROY" },
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
[CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
}; ->(例如do_open)
static void do_open(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) ->
//req->f即fuse_ll结构体变量f,而req->f->op是lowlevel的op,
//对于实现highlevel接口的情况,这里的op即fuse自己提供的上文所述的fuse_path_ops,如下
//static struct fuse_lowlevel_ops fuse_path_ops = {
.init = fuse_lib_init,
.destroy = fuse_lib_destroy,
.lookup = fuse_lib_lookup,
.forget = fuse_lib_forget,
.forget_multi = fuse_lib_forget_multi,
.getattr = fuse_lib_getattr,
.setattr = fuse_lib_setattr,
.access = fuse_lib_access,
.readlink = fuse_lib_readlink,
.mknod = fuse_lib_mknod,
.mkdir = fuse_lib_mkdir,
.unlink = fuse_lib_unlink,
.rmdir = fuse_lib_rmdir,
.symlink = fuse_lib_symlink,
.rename = fuse_lib_rename,
.link = fuse_lib_link,
.create = fuse_lib_create,
.open = fuse_lib_open,
.read = fuse_lib_read,
.write_buf = fuse_lib_write_buf,
.flush = fuse_lib_flush,
.release = fuse_lib_release,
.fsync = fuse_lib_fsync,
.opendir = fuse_lib_opendir,
.readdir = fuse_lib_readdir,
.releasedir = fuse_lib_releasedir,
.fsyncdir = fuse_lib_fsyncdir,
.statfs = fuse_lib_statfs,
.setxattr = fuse_lib_setxattr,
.getxattr = fuse_lib_getxattr,
.listxattr = fuse_lib_listxattr,
.removexattr = fuse_lib_removexattr,
.getlk = fuse_lib_getlk,
.setlk = fuse_lib_setlk,
.flock = fuse_lib_flock,
.bmap = fuse_lib_bmap,
.ioctl = fuse_lib_ioctl,
.poll = fuse_lib_poll,
.fallocate = fuse_lib_fallocate,
};
req->f->op.open(req, nodeid, &fi); ->
//.open = fuse_lib_open,
static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,struct fuse_file_info *fi) ->
fuse *f = req_fuse_prepare(req);//f = req->f->userdata
|
err = fuse_fs_open(f->fs, path, fi); ->
err = fuse_compat_open(fs, path, fi); ->
fs->op.open(path, fi);//即用户自己定义的open操作
//至此完成open操作
守护进程完成一次操作
注:本文重点介绍了用户自己完成的highlevel函数的注册到最终被调用的完全追踪,不包含fuse内核模块与守护进程的交互过程。