FUSE API 的两种使用方法

refer:  http://blog.csdn.net/langeldep/article/details/6401567



FUSE 虚拟文件系统集成到我们的应用程序时,有两种使用策略,一种是使用比较上层的API,

主循环我们只能调用 ret = fuse_main (fargc, fargv, &my_handler, NULL) 这个主循环的接口,

 

my_handler我们只取我们关心API属性,如下所示

 

  1. static struct fuse_operations my_handler =   
  2. {  
  3.     .getattr    = xmp_getattr,  
  4.     .opendir    = xmp_opendir,  
  5.     .readdir    = xmp_readdir,  
  6.     .mkdir      = xmp_mkdir,  
  7.     .unlink     = xmp_unlink,  
  8.     .rmdir      = xmp_rmdir,  
  9.     .rename     = xmp_rename,  
  10.     .link       = xmp_link,  
  11.     .truncate   = xmp_truncate,  
  12.     .create     = xmp_create,  
  13.     .open       = xmp_open,  
  14.     .read       = xmp_read,  
  15.     .write      = xmp_write,  
  16.     .flush      = xmp_flush,  
  17.     .release    = xmp_release,  
  18. };  

 

然后我们自己要来实现上面的各种 xmp_ 开头的函数。

 

 

还有一种是使用  fuse_session_loop 这个比较底层的函数来实现,这个时候我们要实现的API都是一些比较底层

的API, 比如下面的代码所示 :

[c-sharp] view plain copy
  1. static struct fuse_lowlevel_ops  lowlevel_handler =   
  2. {  
  3.     .lookup   = lowlevel_lookup,  
  4.     .getattr  = lowlevel_getattr,  
  5.     .readdir  = lowlevel_readdir,  
  6.     .mkdir    = lowlevel_mkdir,  
  7.     .rmdir    = lowlevel_rmdir,  
  8.     .open     = lowlevel_open,  
  9.     .read     = lowlevel_read,  
  10.     .write    = lowlevel_write,  
  11.     .unlink   = lowlevel_unlink,  
  12.     .rename   = lowlevel_rename,  
  13. };  

 

 

具体的使用方法如下 :

 

[c-sharp] view plain copy
  1. struct fuse_chan *ch;  
  2.       
  3. fargc = 3;  
  4. fargv[0] = g_Config.processName;  
  5. fargv[1] = g_Config.mountSource;  
  6. fargv[2] = g_Config.mountPath;  
  7. struct fuse_args args = FUSE_ARGS_INIT(fargc, fargv);  
  8.   
  9. snprintf (buf, sizeof(buf)-1, "umount -l %s", g_Config.mountPath);  
  10. system(buf);  
  11. ret = fuse_parse_cmdline(&args, &g_Config.mountPath, NULL, NULL);  
  12. ch  = fuse_mount(g_Config.mountPath, &args);  
  13. if (ret == -1 || ch == NULL)  
  14. {  
  15.     fprintf (stderr, "fuse mout fail/n");  
  16.     exit(1);  
  17. }  
  18. struct fuse_session *se;  
  19. se = fuse_lowlevel_new(&args, &lowlevel_handler, sizeof(lowlevel_handler), NULL);  
  20. if (se != NULL)   
  21. {  
  22.     if (fuse_set_signal_handlers(se) != -1)  
  23.     {  
  24.         fuse_session_add_chan(se, ch);  
  25.         ret = fuse_session_loop(se);  
  26.         fuse_remove_signal_handlers(se);  
  27.         fuse_session_remove_chan(ch);  
  28.     }  
  29.     fuse_session_destroy(se);  
  30. }  
  31. fuse_unmount(g_Config.mountPath, ch);  
  32. fuse_opt_free_args(&args);;  

 

 

底层的API使用起来相对灵活性大一点,本人推荐使用底层的API。当然了,上层的API使用起来相对简单一点。

 

下面复制了一个具体的底层API的实现,供大家参考。

 

[c-sharp] view plain copy
  1. void lowlevel_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)  
  2. {  
  3.     writelog (LOG_DEBUG, "call user function_______%s______fuse_ino_t = %d", __FUNCTION__, ino);  
  4.     if (ino != 2)  
  5.         fuse_reply_err(req, EISDIR);  
  6.     else if ((fi->flags & 3) != O_RDONLY)  
  7.         fuse_reply_err(req, EACCES);  
  8.     else  
  9.     {  
  10.         /* direct_io is supposed to allow partial reads. However, setting 
  11.         * the flag causes read length max at 4096 bytes which leads to 
  12.         * *many* requests, poor performance, and errors. Some resources 
  13.         * like TCP ports are recycled too fast for Linux to cope. 
  14.         */  
  15.         //fi->direct_io = 1;  
  16.         fuse_reply_open(req, fi);  
  17.     }  
  18. }  

 

另外在使用fuse的时候,要注意的是 struct fuse_file_info *fi 这个结构体数据的填充,

 

其中最关键的是 direct_io 和 nonseekable。

 

具体如下 :

                    fi->fh = socket(PF_INET, SOCK_STREAM, 0);
                    fi->direct_io = 1;
                    fi->nonseekable = 0;

 

设置了direct_io=1 可以提高文件读写的速度,一次IO的大小就不在局限于4K,

设置 nonseekable=0, 上层的应用才可以调用seek函数进行,否则无法seek。

 

这两个地方时很关键的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值