osxfuse cgofuse mkdir ошибка ввода / вывода

При использовании cgofuse я не могу создать каталог внутри смонтированного fs с помощью os.Mkdir:

паника: mkdir mp/testDir: ошибка ввода / вывода

Код:

import (
    "fmt"
    "os"
    "path/filepath"
    "syscall"

    "github.com/billziss-gh/cgofuse/fuse"
)
type Ptfs struct {
    fuse.FileSystemBase
    root string
}

var (
    dirName = "testDir"
)

func main() {
    mountPoint = os.Args[1]

    fs := Ptfs{}
    host := fuse.NewFileSystemHost(&fs)
    host.SetCapReaddirPlus(true)

    go host.Mount(mountPoint, []string{"-d"})
    defer host.Unmount()

    fmt.Println("init completed...")
    fmt.Scanln()
    fmt.Println("make dir...")

    err := os.Mkdir(filepath.Join(mountPoint, dirName), 0700)
    if err != nil {
        panic(err)
    }
}

Определение Getattr для cgofuse следующее (почти такое же, как в примере с github):

func (self *Ptfs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
    stgo := syscall.Stat_t{}
    if ^uint64(0) == fh {
        path = filepath.Join(self.root, path)
        errc = errno(syscall.Lstat(path, &stgo))
    } else {
        errc = errno(syscall.Fstat(int(fh), &stgo))
    }
    return
}

func (self *Ptfs) Mkdir(path string, mode uint32) (errc int) {
    path = filepath.Join(self.root, path)
    return errno(syscall.Mkdir(path, mode))
}

давая опции монтирования "-d", я получаю этот дополнительный вывод:

make dir... unique: 9, код операции: LOOKUP (1), nodeid: 1, insize: 48, pid: 27053 LOOKUP /testDir getattr /testDir уникально: 9, ошибка: -2 (такого файла или каталога нет), размер больше: 16 уникальных: 7, код операции: GETATTR (3), nodeid: 1, размер: 56, pid: 27053 getattr / unique: 7, успех, размер больше: 136 уникальных: 2, код операции: DESTROY (38), nodeid: 1, размер: 40, pid: 27053 уникально: 2, успех, больше: 16

dir "testDir" в корневом каталоге dir в точке монтирования еще не существует, поэтому я думаю, что "Нет такого файла или каталога" - это нормально. Но даже после "успеха" GETATTR "корневого" каталога я все еще не могу создать каталог. Уничтожение кода операции Я полагаю, что получается путем размонтирования системы, вызванной отсрочкой host.Unmount ().

[EDIT] Погружение глубже: func syscall.Lstat() используется из Getattr():

func Lstat(path string, stat *Stat_t) (err error) {
    var _p0 *byte
    _p0, err = BytePtrFromString(path)
    if err != nil {
        return
    }
    _, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
    if e1 != 0 {
        err = errnoErr(e1)
    }
    return
}

1 ответ

Решение

Моя ошибка была в реализации функции Getattr(). Необходимо правильно поместить статистику в данную структуру указателя статов, не переписывая другой адрес со структурой статов вместо заданных. Правильно заполните данную структуру стат через указатель, и она будет работать как задумано.

Другие вопросы по тегам