您沒有指定編程語言,但FUSE是本地C++,本地Golang綁定在bazil.org/fuse處執行。
我想說的是,答案的主要部分需要包括以下內容:
- 的數據結構來處理文件系統樹在內存中的節點
- 描述和他們的i節點
關係
- 用於捕獲FUSE服務器請求以處理cli命令的鉤子
- 用FUSE服務器裝入文件夾的說明。
我最近用這個適配器寫了一個內存中的文件系統:github.com/bbengfort/memfs。關於它的性能我寫在這裏:In-Memory File System with FUSE。很快,幾個選擇我做:
的內存中的數據結構包含2層主要結構,目錄和文件是兩個節點:
type Node struct {
ID uint64
Name string
Attrs fuse.Attr
Parent *Dir
}
type Dir struct {
Node
Children map[string]Node
}
type File struct {
Node
Data []byte
}
正如你可以看到,這是一個簡單的樹是穿越上下通過Children
和Parent
鏈接。文件的Data
屬性保存文件的所有內容。因此,文件系統只需在掛載點創建一個名爲"\"
的「根」目錄,然後在mkdir
上將Dir
添加到其子節點,並在cp
上添加File
。在Go中,這很簡單:
type FS struct {
root *Dir
}
func Mount(path string) error {
// Unmount the FS in case it was mounted with errors.
fuse.Unmount(path)
// Mount the FS with the specified options
conn, err := fuse.Mount(path)
if err != nil {
return err
}
// Ensure that the file system is shutdown
defer conn.Close()
// Create the root dir and file system
memfs := FS{
root: &Dir{
ID: 1,
Name: "\",
Parent: nil,
},
}
// Serve the file system
if err := fs.Serve(conn, memfs); err != nil {
return err
}
}
現在您需要掛鉤來實現各種FUSE請求和調用。下面是mkdir
一個例子:
func (d *Dir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
// Update the directory Atime
d.Attrs.Atime = time.Now()
// Create the child directory
c := new(Dir)
c.Init(req.Name, req.Mode, d)
// Set the directory's UID and GID to that of the caller
c.Attrs.Uid = req.Header.Uid
c.Attrs.Gid = req.Header.Gid
// Add the directory to the directory
d.Children[c.Name] = c
// Update the directory Mtime
d.Attrs.Mtime = time.Now()
return c, nil
}
最後,結束面試問題,以瞭解如何編譯和運行服務器,安裝的路徑,也許如何FUSE攔截內核調用,並在它們傳遞給你的流程的討論用戶空間。
我明白這可能會繞過這個問題,但爲什麼不使用[tmpfs](http://en.wikipedia.org/wiki/Tmpfs)而不是通過FUSE來滾動自己的文件系統? –
@FrédéricHamidi:tmpfs是一個很好的選擇,謝謝。但可悲的是,這並不能回答你提到的問題。 – Gautam
我想_stored in memory_意味着你必須分配某種緩衝區並將該緩衝區用作fs後端? –