doudao2407 2018-02-16 13:59
浏览 171
已采纳

osxfuse cgofuse mkdir输入/输出错误

while using cgofuse i cant create dir inside mounted fs with os.Mkdir:

panic: mkdir mp/testDir: input/output error

Code:

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 definition for cgofuse is next (almost same as in example from 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))
}

giving the "-d" mount options i get this additional output:

make dir... unique: 9, opcode: LOOKUP (1), nodeid: 1, insize: 48, pid: 27053 LOOKUP /testDir getattr /testDir unique: 9, error: -2 (No such file or directory), outsize: 16 unique: 7, opcode: GETATTR (3), nodeid: 1, insize: 56, pid: 27053 getattr / unique: 7, success, outsize: 136 unique: 2, opcode: DESTROY (38), nodeid: 1, insize: 40, pid: 27053 unique: 2, success, outsize: 16

dir "testDir" inside root dir in mountpoint isnt exist yet, so i guess "No such file or directory" is okay for this. But even after "success" of GETATTR of "root" dir i still can't create dir. Opcode DESTROY i believe gets by unmounting of system caused by defer host.Unmount().

[EDIT] Diving deeper: func syscall.Lstat() is used from 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条回答 默认 最新

  • douhui3330 2018-05-23 09:28
    关注

    My mistake was in Getattr() function implementation. It is necessary to correctly put stats inside given stat pointer struct, not rewriting another address with stat struct instead of given. Correctly fill given stat struct via pointer and it will work as intended.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器