Skip to content

Instantly share code, notes, and snippets.

@Scoder12
Created March 31, 2021 21:38
Show Gist options
  • Save Scoder12/5e3fe1c05fa5a4cbef5923f0e0c8aa53 to your computer and use it in GitHub Desktop.
Save Scoder12/5e3fe1c05fa5a4cbef5923f0e0c8aa53 to your computer and use it in GitHub Desktop.
Fuse test
package main
import (
"context"
"flag"
"log"
"syscall"
"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
)
type Root struct {
fs.Inode
files []string
}
type File struct {
fs.Inode
name string
}
func (r *Root) HasFile(name string) bool {
for _, f := range r.files {
if f == name {
return true
}
}
return false
}
func (r *Root) NewFileInode(ctx context.Context, name string) *fs.Inode {
stable := fs.StableAttr{
Mode: fuse.S_IFREG,
Ino: 0,
}
operations := &File{name: name}
child := r.NewInode(ctx, operations, stable)
// In case of concurrent lookup requests, it can happen that operations !=
// child.Operations().
return child
}
var _ = (fs.NodeReaddirer)((*Root)(nil))
func (r *Root) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
entries := make([]fuse.DirEntry, len(r.files))
for i, k := range r.files {
entries[i] = fuse.DirEntry{
Name: k,
Ino: 0, // 0 = auto-generate the number
Mode: fuse.S_IFREG,
}
}
return fs.NewListDirStream(entries), fs.OK
}
var _ = (fs.NodeLookuper)((*Root)(nil))
func (r *Root) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
if r.HasFile(name) {
return r.NewFileInode(ctx, name), syscall.F_OK
}
return nil, syscall.ENOENT
}
var _ = (fs.NodeCreater)((*Root)(nil))
func (r *Root) Create(
ctx context.Context,
name string,
flags uint32,
mode uint32,
out *fuse.EntryOut,
) (node *fs.Inode, fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) {
// In real implementation I would return a filehandle here
return r.NewFileInode(ctx, name), nil, fuse.FOPEN_NONSEEKABLE | fuse.FOPEN_DIRECT_IO, syscall.F_OK
}
var _ = (fs.NodeOpener)((*File)(nil))
func (f *File) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) {
log.Printf("Opening file %s with flags: %d\n", f.name, flags)
return nil, fuse.FOPEN_DIRECT_IO, syscall.EAGAIN
}
func main() {
debug := flag.Bool("debug", false, "print debug data")
flag.Parse()
if len(flag.Args()) < 1 {
log.Fatal("Usage:\n hello MOUNTPOINT")
}
mountpoint := flag.Arg(0)
root := &Root{
files: make([]string, 1),
}
root.files[0] = "test.txt"
opts := &fs.Options{}
opts.Debug = *debug
log.Printf("Mounting on %s\n", mountpoint)
server, err := fs.Mount(mountpoint, root, opts)
if err != nil {
log.Fatalf("Mount fail: %v\n", err)
}
server.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment