2012-01-25 7 views
11

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

Ls, MKDIR, Cp

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

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

Мои вопросы

  • Am I движется в правильном направлении?
  • Что еще я должен прочитать?
  • Какое решение?

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

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

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

+1

Я понимаю, что это может быть обход вопроса, но почему бы не использовать [tmpfs] (http://en.wikipedia.org/wiki/Tmpfs) вместо того, чтобы загружать свою собственную файловую систему через FUSE? –

+0

@ FrédéricHamidi: tmpfs - хорошая альтернатива. Но, к сожалению, это не отвечает на вопрос, как вы упомянули. – Gautam

+0

Я предполагаю, что _stored в memory_ означает, что вам нужно выделить какой-то буфер и использовать этот буфер в качестве fs-бэкэнд? –

ответ

5

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

This tutorial также весьма полезен.

3

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

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

  1. структуру данных для обработки дерева файловой системы в памяти
  2. Описания узлов и их отношение к Inodes
  3. Крючки для захвата запросов сервера FUSE для обработки команд cli
  4. Описание установки папки с сервером 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 перехватывает вызовы и вызовы ядра и передает их к процессу в пользовательское пространство.

+0

Удивительный ответ, предоставленный код, спасибо! –

Смежные вопросы