FUSE用户态文件系统中自己实现的highlevel接口函数从注册到调用完全追踪

来源:互联网 发布:有哪些抢购软件 编辑:程序博客网 时间:2024/06/05 19:03
注册时:
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内核模块与守护进程的交互过程。

0 0
原创粉丝点击