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);