Linux下利用fuse实现文件系统

(1)fuse库的下载地址:下载链接

(2)#tar -xzvf fuse-xx.xx.xx.tar.gz
#cd fuse-xx.xx.xx (进入目录,下述命令需要在该目录下执行)
安装编译:
#./configure --prefix=/usr (设定安装目录)
#sudo make
#sudo make install

#cp ~/fuse-xx.xx.xx/fuse.pc /usr/share/pkgconfig

#sudo modprobe fuse (挂载)
#lsmod|grep fuse (查看是否挂载成功)

卸载:
#rmmod fuse

卸载安装及编译:
(以下命令要在"fuse-xx.xx.xx"的安装目录执行)
#sudo make uninstall
#sudo make clean
#sudo make distclean

(3)对照fuse.h实现文件系统必须的接口函数

执行example里的例子  =>     #./可执行文件名   /挂载目录

即在对应挂载目录挂载出一个文件系统;如果我们需要实现自己的文件系统,模仿example将例子中的实现代码替换成我们自己的实现代码即可。


Windows下利用dokan实现文件系统

windows下,准备dokan库,安装dokan.sys。

dokan的Github地址:下载链接   

开源项目里介绍了如何安装驱动等等;

dokany\samples\dokan_mirror下面的mirror.c即是dokan的简单应用,实现相应的回调函数,并注册回调函数;

我们需要做的就是实现dokany\dokan\dokan.h里面对应的文件系统操作函数。

比如CreateFile:

dokan.h定义如下

  NTSTATUS(DOKAN_CALLBACK *ZwCreateFile)(LPCWSTR FileName,
      PDOKAN_IO_SECURITY_CONTEXT SecurityContext,
      ACCESS_MASK DesiredAccess,
      ULONG FileAttributes,
      ULONG ShareAccess,
      ULONG CreateDisposition,
      ULONG CreateOptions,

      PDOKAN_FILE_INFO DokanFileInfo);

mirror里面的实现如下:

static NTSTATUS DOKAN_CALLBACK
MirrorCreateFile(LPCWSTR FileName, PDOKAN_IO_SECURITY_CONTEXT SecurityContext,
                 ACCESS_MASK DesiredAccess, ULONG FileAttributes,
                 ULONG ShareAccess, ULONG CreateDisposition,

                 ULONG CreateOptions, PDOKAN_FILE_INFO DokanFileInfo) {

    //实现代码

}

  ZeroMemory(dokanOperations, sizeof(DOKAN_OPERATIONS));
  dokanOperations->ZwCreateFile = MirrorCreateFile; //传递回调函数地址

  status = DokanMain(dokanOptions, dokanOperations);

dokany\dokan下的DokanMain函数用来注册实现的回调函数。

如果仅仅需要文件系统只运行在window下,实现dokan.h里的回调函数即可。


同时实现Linux和Windows文件系统

dokanfuse库可以用来将fuse接口转换为dokan接口(在dokan项目代码下)。利用dokanfuse,可以将我们自己编写的文件系统可以同时运行在windows和linux下。

dokanfuse 与fuse-xx.xx.xx\include都有fuse.h,尽量找两个版本一致的fuse.h;

万一没找到版本一致的fuse.h(接口函数参数有可能不一致),利用条件编译:

#ifdef WIN32

#else

#endif 

Windows处,我们的项目需要链接dokanfuse(调用fuse_main函数),dokanfuse链接dokan(调用DokanMain函数);

Linux处,makefile 包含fuse-xx.xx.xx\include 以及依赖fuse-xx.xx.xx\lib下的fuse

(1)实现fuse.h里相应的fuse接口函数。

(2)传递函数地址

         struct fuse_operations fuse_operations;

         memset(&fuse_operations, 0, sizeof(fuse_operations));

 fuse_operations.getattr = fuse_getattr;

         ......

(3)注册回调函数地址

fuse_main(argc, argv, &fuse_operations, NULL);


Logo

更多推荐