在内存FUSE文件系统中

写一个存储在内存中的简单的FUSE文件系统。 文件系统必须支持以下命令:

ls,mkdir,cp

这个问题最近在接受采访时被问到,我无法回答。 所以我决定学习它。

做了一些search,并find一些build立我自己的FUSE文件系统的指南。 我对如何在内存中实现文件系统毫无头绪。

我的问题是

  • 我正朝着正确的方向走吗?
  • 还有什么我应该读的?
  • 解决办法是什么 ?

我正在阅读的链接:

  • http://fuse.sourceforge.net/
  • http://www.ibm.com/developerworks/linux/library/l-fuse/
  • http://pramode.net/articles/lfy/fuse/pramode.html
  • http://revista.python.org.ar/3/en/html/python_en_tu_fs.html
  • http://pysnippet.blogspot.com/2009/11/fuse-filesystem-in-userspace-part-1.html
  • 用FUSE在python中创build一个临时文件
  • http://www.willmcgugan.com/blog/tech/2011/3/20/creating-a-virtual-filesystem-with-python-and-why-you-need-one/

在最后一个链接中,提到了PyFileSystem在内存中的caching。 我不确定这可能会有什么帮助。

PS:这是一个书面的面试问题,所以答案要足够简单,在10-15分钟内写在纸上。

我已经采取了一个课程,我们不得不建立一个内存类似的分布式文件系统设计到素馨花 。 该课程深受MIT分布式系统课程启发。 做前几个实验任务是一个很好的练习。

本教程也相当有帮助。

你没有指定编程语言,虽然FUSE是本机C ++,但是有本地的Golang绑定,在bazil.org/fuse中实现。

我会说答案的主要部分需要包括以下内容:

  1. 一个数据结构来处理内存中的文件系统树
  2. 节点描述及其与iNodes的关系
  3. 钩捕捉FUSE服务器请求来处理cli命令
  4. 使用FUSE服务器安装文件夹的说明。

我最近用这个适配器写了一个内存中的文件系统: github.com/bbengfort/memfs 。 关于它的性能我写在这里: 与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 } 

正如你所看到的,这是一个简单的树,可以通过ChildrenParent链接遍历。 文件的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如何拦截内核调用并将它们传递给用户空间中的进程。