ref: 40ad4e69f1c70b8152c095fee65d37d03e248e24
dir: /mntgen.go/
package main import ( "bazil.org/fuse" "bazil.org/fuse/fs" "context" "fmt" "os" "os/signal" "sync/atomic" "syscall" "time" ) var inodeCount uint64 type Dir struct { Fs *FS Name string Attributes fuse.Attr Entries map[string]*Dir } func NewDir(fs *FS, name string) *Dir { atomic.AddUint64(&inodeCount, 1) now := time.Now() return &Dir{ Fs: fs, Name: name, Attributes: fuse.Attr{ Inode: inodeCount, Atime: now, Mtime: now, Ctime: now, Mode: os.ModeDir | 0o755, Nlink: 2, Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid()), }, Entries: make(map[string]*Dir), } } func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) error { *a = d.Attributes return nil } func (d *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { if d == d.Fs.RootDir { if node, ok := d.Entries[name]; ok { return node, nil } else { nd := NewDir(d.Fs, name) d.Entries[name] = nd return nd, nil } } return nil, syscall.ENOENT } func (d *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { entries := make([]fuse.Dirent, 0, len(d.Entries)) for name, entry := range d.Entries { entries = append(entries, fuse.Dirent{ Inode: entry.Attributes.Inode, Type: fuse.DT_Dir, Name: name, }) } return entries, nil } type FS struct { RootDir *Dir } func NewFS() *FS { fs := &FS{} fs.RootDir = NewDir(fs, "") return fs } func (fs FS) Root() (fs.Node, error) { return fs.RootDir, nil } func usage() { fmt.Fprintf(os.Stderr, "usage: %s [ mnt ]\n", os.Args[0]) os.Exit(1) } func main() { mtpt := "/n" switch len(os.Args) { case 1: case 2: mtpt = os.Args[1] default: usage() } c, err := fuse.Mount(mtpt, fuse.FSName("mntgen"), fuse.Subtype("mntgen"), fuse.AllowOther()) if err != nil { fmt.Fprintf(os.Stderr, "mount: %v\n", err) os.Exit(1) } defer c.Close() sigc := make(chan os.Signal, 1) signal.Notify(sigc, syscall.SIGTERM, syscall.SIGINT) go func() { for { <-sigc if err := fuse.Unmount(mtpt); err != nil { fmt.Fprintf(os.Stderr, "unmount failed: %v\n", err) } } }() err = fs.Serve(c, NewFS()) if err != nil { fmt.Fprintf(os.Stderr, "serve: %v\n", err) os.Exit(1) } }