编写一个存储在内存中的简单FUSE文件系统。文件系统必须支持以下命令:
ls,mkdir,cp
这个问题最近在接受采访时被问到,我无法回答。 所以我决定学习它。
进行了一些搜索并找到了一些关于构建我自己的FUSE文件系统的指南。 我真的对如何在内存中实现文件系统毫无头绪。
我的问题是
我正在阅读的链接:
在最后一个链接中提到了使用PyFileSystem的内存缓存。 我不确定这可能会有什么帮助。
PS:这是一个书面采访问题,所以答案很简单,可以在10-15分钟内写在纸上。答案 0 :(得分:5)
我选择了一个课程,我们必须在内部构建一个类似于Frangipani的内存分布式文件系统。该课程受到MIT's Distributed Systems course的启发。做他们的前几个实验作业将是一个很好的练习。
This tutorial也很有帮助。
答案 1 :(得分:3)
您没有指定编程语言,尽管FUSE是本机C ++,但存在本地Golang绑定,在bazil.org/fuse实现。
我要说答案的主要部分需要包含以下内容:
我最近使用此适配器编写了一个内存文件系统:github.com/bbengfort/memfs。我的关于其性能的文章在这里: In-Memory File System with FUSE 。很快,我做了一些选择:
内存数据结构包含2个主要结构,dir和file都是节点:
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如何拦截内核调用并将它们传递给用户空间中的进程。