Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493526
  • 博文数量: 72
  • 博客积分: 1851
  • 博客等级: 上尉
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-16 17:50
文章分类

全部博文(72)

文章存档

2013年(1)

2012年(17)

2011年(51)

2010年(3)

分类: LINUX

2011-06-20 16:18:12

系统初始化

与系统初始化的处理函数如下:

读取的数据结构体为:

  1. //读入的数据
  2. struct fuse_init_in {
  3.     __u32 major;
  4.     __u32 minor;
  5.     __u32 max_readahead;
  6.     __u32 flags;
  7. }
  8. //发送的数据
  9. struct fuse_init_out {
  10.     __u32 major;
  11.     __u32 minor;
  12.     __u32 max_readahead;
  13.     __u32 flags;
  14. }
  15. static void do_init(fuse_req_t req,fuse_ino_t nodeid,const void *inarg)
  16. {
  17.     struct fuse_init_in *arg = (struct fuse_init_in* )arg;
  18.     struct fuse_init_out outarg;
  19.     struct fuse_ll *f = req->f;
  20.     size_t bufsize = fuse_chan_bufsize(req->ch);
  21.     
  22.     …....
  23.     //初始化fuse相关的参数
  24.     f->conn.proto_major = arg->major;
  25.     f->conn.proto_minor = arg->minor;
  26.     f->conn.capable = 0;
  27.     f->conn.want = 0;
  28.     
  29.     memset(&outarg,0,sizeof(outarg));
  30.     //发送确认的参数
  31.     outarg.major = FUSE_KERNEL_VERSION;
  32.     outarg.minor = FUSE_KERNEL_MINOR_VERSION;
  33.     //下面就是判断不同的版本,进行不同的参数设置
  34.     ….....
  35. }

读取数据

  1. 如果是读取请求则调用流程为:
  2. //接收的数据
  3. struct fuse_read_in {
  4.     __u64 fh;
  5.     __u64 offset;
  6.     __u32 size;
  7.     __u32 read_flags;
  8.     __u64 lock_owner;
  9.     __u32 flags;
  10.     __u32 padding;
  11. }

请求分发

  1. //发送的数据
  2. struct
  3. static void do_read(fuse_req_t req,fuse_ino_t nodeid,const void*inarg)
  4. {
  5.     struct fuse_read_in *arg = (struct fuse_read_in*)inarg;
  6.     
  7.     if(req->f->op.read){
  8.     struct fuse_file_info fi;
  9.     
  10.     memset(&fi,0,sizeof(fi));
  11.     fi.fh = arg->fh;//文件句柄
  12.     fi.fh_old = fi.fh;
  13.     if(req->f->conn.proto_minor>=9) {
  14.         fi.lock_owner = arg->lock_owner;
  15.         fi.flags = arg->flags;
  16.     }
  17.     req->f->op.read(req,nodeid,arg->size,arg->offset,&fi);
  18.     }else
  19.         fuse_reply_err(req,ENOSYS);
  20. }

其中req->f->op.read()调用了fuse_lib_read函数,原型如下:

  1. static void fuse_lib_read(fuse_req_t req,fuse_ino_t ino,size_t size,off_t off,struct fuse_file_info *fi)
  2. {
  3.     struct fuse *f = req_fuse_prepare(req);
  4.     char *path;
  5.     char *buf;
  6.     int res;

  7.     buf = (char*)malloc(size);
  8.     if(buf==NULL) {
  9.      reply_err(req,-ENOMEM);
  10.      return;
  11.     }
  12.     //通过ino获取文件路径
  13.     res = get_path_nullok(f,ino,&path);
  14.     if(res ==0) {
  15.      struct fuse_intr_data d;
  16.     
  17.      fuse_prepare_interrupt(f,req,&d);
  18.      //转到客户端自己注册的fuse_operations的相关操作
  19.      res = fuse_fs_read(f->fs,path,buf,size,off,fi);
  20.      fuse_finish_interrupt(f,req,&d);
  21.      free_path(f,ino,path);
  22.     }
  23.     
  24.     if(res>=0)
  25.         fuse_reply_buf(req,buf,res);
  26.     else
  27.         fuse_reply_err(req,res);
  28.     free(buf);
  29. }

获取文件路径

这里面的get_path_nullok函数则调用了get_path_common,原型如下:

  1. //get_path_common(f,nodeid,NULL,path,NULL)
  2. static int get_path_common(struct fuse* f,fuse_ino_t nodeid,const char* name,
  3.      char**path,struct node **wnode)
  4. {
  5.     int err;
  6.     int ticket;
  7.     
  8.     pthread_mutex_lock(&f->lock);
  9.     ticket = get_tickets(f);
  10.     //直接通过文件nodeid获取文件路径
  11.     err = try_get_path(f,nodeid,name,path,wnode);
  12.     //正在被其它线程访问
  13.     if(err==-EAGAIN) {
  14.     //定义原型:
  15.     //struct lock_queue_element {
  16.     // struct lock_queue_element *next;
  17.     // pthread_cond_t cond;
  18.     //}    
  19.      struct lock_queue_element qe;
  20.      //放入等待队列
  21.      queue_path(f,,&qe,nodeid,name,!!wnode);
  22.      do {
  23.         //等待fuse解锁,线程阻塞
  24.         wait_on_path(f,&qe,nodeid,name,!!wnode);
  25.         //只要错误为-EAGAIN,就说明当前调用出现阻塞情况,需要等待
  26.         err = try_get_path(f,nodeid,name,path,wnode,ticket);
  27.         //唤醒下一个等待的条件变量
  28.         wake_up_next(&qe);
  29.      }while(err == -EAGAIN);
  30.      //操作成功后,就销毁条件变量
  31.      dequeue_path(f,&qe,nodeid,name,!!wnode);
  32.     }
  33.      pthread_mutex_unlock(&f->lock);
  34.     
  35.      return err;
  36. }

继续看其中的调用函数:

  1. //try_get_path(f,nodeid,NULL,path,NULL) 从nodeid(索引节点缓存)对应的缓存中取出path
  2. static int try_get_path(struct fuse *f,fuse_ino_t nodeid,const char* name,
  3.         char **path,struct node **wnodep,int ticket)
  4. {
  5.     unsigned bufsize=256;
  6.     char *buf;
  7.     char *s;
  8.     struct node *node;
  9.     struct node *wnode = NULL;
  10.     int err;
  11.     *path = NULL;
  12.     buf = malloc(bufsize);
  13.     …..
  14.     s= buf+bufsize-1;
  15.     *s = '\0';
  16.     if(name!=NULL) {
  17.     //add_name:转换为绝对路径,也就是在路径名前面 加上/
  18.     s = add_name(&buf,&bufsize,s,name);    
  19.     err = -ENOMEM;
  20.     if (s == NULL) goto out_free;
  21.     }
  22.     //如果父节点不为空,则nodeid指向的是父节点
  23.     if(wnodep) {
  24.      assert(ticket);
  25.      wnode = lookup_node(f,nodeid,name);
  26.          ….......
  27.     }
  28.     //逆向遍历文件夹,生成绝对路径:开始从该索引节点开始一步一步向上寻找父目录,直到/
  29.      err = 0;
  30.     for(node = get_node(f,nodeid);node->nodeid != FUSE_ROOT_ID; node = node->parent){
  31.         //每寻找一项,就加入到路径之中
  32.         s = add_name(&buf,&bufsize,s,node->name);
  33.         ….......
  34.     }
  35.     *path = buf;
  36.      ….......
  37.     return 0;
  38. }



阅读(1953) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~