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.

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

报告相同问题?

悬赏问题

  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)