inotify on FUSE

http://sourceforge.net/p/fuse/mailman/message/24625009/

因為最近自己想做 FUSE ,為了加速,希望能夠做到 inotify 的功能。基本上我想做的事情是類似 Google Drive 網頁界面會做的事情,開啟一個目錄的時候先使用本地的快取回應,同時在背景發出 request 向 server 請求新目錄資料,收到請求之後再更新顯示畫面。也就是說在一個資料夾點兩下,會馬上進去並且看到資料夾的內容,這份內容由 cache 提供,同時在背景向 server 發出更新請求,從 server 取回新的結果之後,更新 cache ,並且顯示新的結果。

這東西用網頁做當然很容易,可是如果讓桌面應用程式像是檔案管理員(譬如說 Nautilus )做到這個功能,就必須支援 FUSE 。因為爬了一下文之後發現 Nautilus 裡面這部分的功能應該是用 GIO 實作的,而 GIO 達到檔案系統通知的方法又是依賴 kernel 的 inotify 。

所以要達到的話很自然就是需要讓 FUSE 也能夠支援 inotify 。

我原本以為 inotify 會提供 filesystem module 一個 system call 來通知某個路徑有更新,filesystem module 只要呼叫這個 syscall 就可以了。在 FUSE 的狀況下則是 FUSE 的 kernel filesystem module 會再接收來自 userspace libfuse 的呼叫,然後 FUSE 實作只要呼叫 libfuse 的這個 function 就可以了。

結果發現 inotify 完全不是這樣實作的。

inotify 的實作依賴 VFS ,也就是說,inotify 之所以知道某個物件被動過是因為有其他程式透過 VFS 來修改這個物件,而不是由 VFS 底層的 filesystem module 來通知 inotify 。事實上 VFS 並不提供任何方法讓 filesystem module 通知它物件的更動。

螢幕快照 2015-06-13 下午5.58.16

也就是說,圖中的 FUSE 沒有任何方法可以通知 VFS 某個物件被修改了。VFS 知道物件被修改(VFS 知道就等於 inotify 知道,應該是每個 VFS 的操作都有 inotify 的 hook 之類的)是因為有除了圖中 ls -l 之外其他的 userspace 程式呼叫 VFS ,這時候就會一併 invoke inotify 的 hook ,inotify 進而通知 watcher 。

所以基本上,要達到我想要的功能,這個 userspace 的 FUSE 程式本身要去戳 VFS ,才會觸發 inotify 。

可是這樣顯然非常容易造成 deadlock ,因為 VFS 收到呼叫會再呼叫 FUSE filesystem module ,然後又會呼叫 userspace 的 FUSE 程式,要詳加調查有什麼不會造成 deadlock 的方式……

或是說另一個方式是直接去改 VFS ,讓 VFS 支援由底層的 filesystem module 來 trigger inotify 。這樣可行性不知道如何。

或是說要做到我所說的效果,似乎應該直接 patch Nautilus ,讓 userspace FUSE 程式和 Nautilus 有溝通的機制,某種程度上的整合。

參考資料:

  • 巴西某大學的課程簡報,講 VFS 和一點點 FUSE ,蠻易懂的快速入門:http://www.ic.unicamp.br/~islene/2s2013-mo806/vfs/andre-zhen.pdf

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s