В памяти FUSE файловая система - PullRequest
12 голосов
/ 25 января 2012

Напишите простую файловую систему FUSE, которая хранится в памяти.Файловая система должна поддерживать следующие команды:

ls, mkdir, cp

Этот вопрос был недавно задан в интервью, я не смог ответить на него.Поэтому я решил изучить его.

Я провел поиск и нашел несколько руководств по созданию моей собственной файловой системы FUSE.Я действительно не знаю, как реализовать файловую систему в памяти.

Мои вопросы

  • Я иду в правильном направлении?
  • Что еще я должен прочитатьнаверх?
  • Какое решение?

Ссылки, которые я читаю:

В последней ссылке есть упоминание о кешировании в памяти с PyFileSystem .Я не уверен, как это могло бы помочь.

PS: Это было письменное интервью. Вопрос, поэтому ответ должен быть достаточно простым, чтобы написать на бумаге в течение 10-15 минут.

Ответы [ 2 ]

5 голосов
/ 27 января 2012

Я прошел курс, где нам пришлось создать распределенную файловую систему в памяти, схожую по дизайну с Frangipani .Курс был вдохновлен курсом Распределенные системы MIT .Выполнение их первых нескольких лабораторных заданий было бы хорошим упражнением.

Это руководство также весьма полезно.

3 голосов
/ 05 февраля 2017

Вы не указали язык программирования, хотя FUSE является родным C ++, есть собственные привязки Golang, реализованные в bazil.org / fuse .

Я бы сказал, что основные части ответа должны включать следующее:

  1. Структура данных для обработки дерева файловой системы в памяти
  2. Описание узлов и их связь с iNodes
  3. Хуки для захвата запросов сервера FUSE для обработки команд cli
  4. Описание монтирования папки с сервером FUSE.

Недавно я написал файловую систему в памяти, используя этот адаптер: github.com / bbengfort / memfs . Моя запись о его производительности находится здесь: Файловая система в памяти с FUSE . Быстро, несколько вариантов, которые я сделал:

Структура данных в памяти содержит 2 первичных структуры, dir и файл, которые являются узлами:

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 a Dir добавляется его дочерний элемент, а в cp a 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 перехватывает вызовы ядра и передает их вашему процессу в пространстве пользователя.

...