FUSE API 的两种使用方法
2013-01-29 11:51
302 查看
refer: http://blog.csdn.net/langeldep/article/details/6401567
FUSE 虚拟文件系统集成到我们的应用程序时,有两种使用策略,一种是使用比较上层的API,
主循环我们只能调用 ret = fuse_main (fargc, fargv, &my_handler, NULL) 这个主循环的接口,
my_handler我们只取我们关心API属性,如下所示
[cpp]
view plaincopy
static struct fuse_operations my_handler =
{
.getattr = xmp_getattr,
.opendir = xmp_opendir,
.readdir = xmp_readdir,
.mkdir = xmp_mkdir,
.unlink = xmp_unlink,
.rmdir = xmp_rmdir,
.rename = xmp_rename,
.link = xmp_link,
.truncate = xmp_truncate,
.create = xmp_create,
.open = xmp_open,
.read = xmp_read,
.write = xmp_write,
.flush = xmp_flush,
.release = xmp_release,
};
然后我们自己要来实现上面的各种 xmp_ 开头的函数。
还有一种是使用 fuse_session_loop 这个比较底层的函数来实现,这个时候我们要实现的API都是一些比较底层
的API, 比如下面的代码所示 :
[c-sharp]
view plaincopy
static struct fuse_lowlevel_ops lowlevel_handler =
{
.lookup = lowlevel_lookup,
.getattr = lowlevel_getattr,
.readdir = lowlevel_readdir,
.mkdir = lowlevel_mkdir,
.rmdir = lowlevel_rmdir,
.open = lowlevel_open,
.read = lowlevel_read,
.write = lowlevel_write,
.unlink = lowlevel_unlink,
.rename = lowlevel_rename,
};
具体的使用方法如下 :
[c-sharp]
view plaincopy
struct fuse_chan *ch;
fargc = 3;
fargv[0] = g_Config.processName;
fargv[1] = g_Config.mountSource;
fargv[2] = g_Config.mountPath;
struct fuse_args args = FUSE_ARGS_INIT(fargc, fargv);
snprintf (buf, sizeof(buf)-1, "umount -l %s", g_Config.mountPath);
system(buf);
ret = fuse_parse_cmdline(&args, &g_Config.mountPath, NULL, NULL);
ch = fuse_mount(g_Config.mountPath, &args);
if (ret == -1 || ch == NULL)
{
fprintf (stderr, "fuse mout fail/n");
exit(1);
}
struct fuse_session *se;
se = fuse_lowlevel_new(&args, &lowlevel_handler, sizeof(lowlevel_handler), NULL);
if (se != NULL)
{
if (fuse_set_signal_handlers(se) != -1)
{
fuse_session_add_chan(se, ch);
ret = fuse_session_loop(se);
fuse_remove_signal_handlers(se);
fuse_session_remove_chan(ch);
}
fuse_session_destroy(se);
}
fuse_unmount(g_Config.mountPath, ch);
fuse_opt_free_args(&args);;
底层的API使用起来相对灵活性大一点,本人推荐使用底层的API。当然了,上层的API使用起来相对简单一点。
下面复制了一个具体的底层API的实现,供大家参考。
[c-sharp]
view plaincopy
void lowlevel_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
writelog (LOG_DEBUG, "call user function_______%s______fuse_ino_t = %d", __FUNCTION__, ino);
if (ino != 2)
fuse_reply_err(req, EISDIR);
else if ((fi->flags & 3) != O_RDONLY)
fuse_reply_err(req, EACCES);
else
{
/* direct_io is supposed to allow partial reads. However, setting
* the flag causes read length max at 4096 bytes which leads to
* *many* requests, poor performance, and errors. Some resources
* like TCP ports are recycled too fast for Linux to cope.
*/
//fi->direct_io = 1;
fuse_reply_open(req, fi);
}
}
另外在使用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。
这两个地方时很关键的。
FUSE 虚拟文件系统集成到我们的应用程序时,有两种使用策略,一种是使用比较上层的API,
主循环我们只能调用 ret = fuse_main (fargc, fargv, &my_handler, NULL) 这个主循环的接口,
my_handler我们只取我们关心API属性,如下所示
[cpp]
view plaincopy
static struct fuse_operations my_handler =
{
.getattr = xmp_getattr,
.opendir = xmp_opendir,
.readdir = xmp_readdir,
.mkdir = xmp_mkdir,
.unlink = xmp_unlink,
.rmdir = xmp_rmdir,
.rename = xmp_rename,
.link = xmp_link,
.truncate = xmp_truncate,
.create = xmp_create,
.open = xmp_open,
.read = xmp_read,
.write = xmp_write,
.flush = xmp_flush,
.release = xmp_release,
};
然后我们自己要来实现上面的各种 xmp_ 开头的函数。
还有一种是使用 fuse_session_loop 这个比较底层的函数来实现,这个时候我们要实现的API都是一些比较底层
的API, 比如下面的代码所示 :
[c-sharp]
view plaincopy
static struct fuse_lowlevel_ops lowlevel_handler =
{
.lookup = lowlevel_lookup,
.getattr = lowlevel_getattr,
.readdir = lowlevel_readdir,
.mkdir = lowlevel_mkdir,
.rmdir = lowlevel_rmdir,
.open = lowlevel_open,
.read = lowlevel_read,
.write = lowlevel_write,
.unlink = lowlevel_unlink,
.rename = lowlevel_rename,
};
具体的使用方法如下 :
[c-sharp]
view plaincopy
struct fuse_chan *ch;
fargc = 3;
fargv[0] = g_Config.processName;
fargv[1] = g_Config.mountSource;
fargv[2] = g_Config.mountPath;
struct fuse_args args = FUSE_ARGS_INIT(fargc, fargv);
snprintf (buf, sizeof(buf)-1, "umount -l %s", g_Config.mountPath);
system(buf);
ret = fuse_parse_cmdline(&args, &g_Config.mountPath, NULL, NULL);
ch = fuse_mount(g_Config.mountPath, &args);
if (ret == -1 || ch == NULL)
{
fprintf (stderr, "fuse mout fail/n");
exit(1);
}
struct fuse_session *se;
se = fuse_lowlevel_new(&args, &lowlevel_handler, sizeof(lowlevel_handler), NULL);
if (se != NULL)
{
if (fuse_set_signal_handlers(se) != -1)
{
fuse_session_add_chan(se, ch);
ret = fuse_session_loop(se);
fuse_remove_signal_handlers(se);
fuse_session_remove_chan(ch);
}
fuse_session_destroy(se);
}
fuse_unmount(g_Config.mountPath, ch);
fuse_opt_free_args(&args);;
底层的API使用起来相对灵活性大一点,本人推荐使用底层的API。当然了,上层的API使用起来相对简单一点。
下面复制了一个具体的底层API的实现,供大家参考。
[c-sharp]
view plaincopy
void lowlevel_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
writelog (LOG_DEBUG, "call user function_______%s______fuse_ino_t = %d", __FUNCTION__, ino);
if (ino != 2)
fuse_reply_err(req, EISDIR);
else if ((fi->flags & 3) != O_RDONLY)
fuse_reply_err(req, EACCES);
else
{
/* direct_io is supposed to allow partial reads. However, setting
* the flag causes read length max at 4096 bytes which leads to
* *many* requests, poor performance, and errors. Some resources
* like TCP ports are recycled too fast for Linux to cope.
*/
//fi->direct_io = 1;
fuse_reply_open(req, fi);
}
}
另外在使用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。
这两个地方时很关键的。
相关文章推荐
- ceph存储 FUSE API 的两种使用方法
- FUSE API 的两种使用方法
- java使用JexcelApi和POI两种方法操作excel
- PHP使用api的两种方法
- PHP使用api的两种方法
- Eclipse中SVN的安装步骤(两种)和使用方法
- Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数、ColModel API、事件及方法
- 使用PHP调用微信API,使用微信做通知类应用的方法
- mongodb java api常用方法的使用以及和spring的集成使用
- Android不同版本的API方法使用和Android系统版本对应的API版本号
- RSS制作(C#) - 使用XML DOM和XmlTextWriter(见评论)两种方法
- 一个可以禁用USB存储设备的程序(SetupAPI的使用方法)
- Eclipse中SVN的安装步骤(两种)和使用方法
- 安卓 Notification 使用方法 API的更新
- HashMap的遍历两种常用的方法,那就是使用keyset及entryset来进行遍历
- 使用J2SE API读取Properties文件的六种方法
- 全面挖掘Java Excel API 使用方法(JExcelApi)
- htc a3380关于因使用google map api,导致apk程序安装时提示 程序未安装 的解决方法
- VBA中使用计时器的两种方法
- PHPStorm设置xdebug工具调试php(使用浏览器或不使用浏览器两种方法)