Вы не указали язык программирования, хотя FUSE является родным C++, существуют встроенные привязки Golang, реализованные в bazil.org/fuse.
Я бы сказал, что основные части ответа должны включать в себя следующее:
- структуру данных для обработки дерева файловой системы в памяти
- Описания узлов и их отношение к Inodes
- Крючки для захвата запросов сервера 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 в memory_ означает, что вам нужно выделить какой-то буфер и использовать этот буфер в качестве fs-бэкэнд? –