From 456738ba6482118ad95fea0a694ca33036921612 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sat, 5 May 2018 22:47:16 -0700 Subject: [PATCH] refactoring fuse --- weed/command/mount_std.go | 104 ++------------------------------------ weed/filesys/dir.go | 62 +++++++++++++++++++++++ weed/filesys/file.go | 34 +++++++++++++ weed/filesys/wfs.go | 17 +++++++ 4 files changed, 117 insertions(+), 100 deletions(-) create mode 100644 weed/filesys/dir.go create mode 100644 weed/filesys/file.go create mode 100644 weed/filesys/wfs.go diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index ef962e15b..3c39979e1 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -4,18 +4,13 @@ package command import ( "fmt" - "os" "runtime" - "path" - "bazil.org/fuse" "bazil.org/fuse/fs" - "github.com/chrislusf/seaweedfs/weed/filer" "github.com/chrislusf/seaweedfs/weed/glog" - "github.com/chrislusf/seaweedfs/weed/storage" "github.com/chrislusf/seaweedfs/weed/util" - "golang.org/x/net/context" + "github.com/chrislusf/seaweedfs/weed/filesys" ) func runMount(cmd *Command, args []string) bool { @@ -25,6 +20,8 @@ func runMount(cmd *Command, args []string) bool { return false } + fuse.Unmount(*mountOptions.dir) + c, err := fuse.Mount(*mountOptions.dir, fuse.LocalVolume()) if err != nil { glog.Fatal(err) @@ -36,7 +33,7 @@ func runMount(cmd *Command, args []string) bool { c.Close() }) - err = fs.Serve(c, WFS{}) + err = fs.Serve(c, filesys.NewSeaweedFileSystem(*mountOptions.filer)) if err != nil { fuse.Unmount(*mountOptions.dir) } @@ -49,96 +46,3 @@ func runMount(cmd *Command, args []string) bool { return true } - -type WFS struct{} - -func (WFS) Root() (fs.Node, error) { - return &Dir{Path: "/"}, nil -} - -var fileIdMap = make(map[uint64]filer.FileId) - -type Dir struct { - Path string - DirentMap map[string]*fuse.Dirent -} - -func (dir *Dir) Attr(context context.Context, attr *fuse.Attr) error { - attr.Mode = os.ModeDir | 0555 - return nil -} - -func (dir *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { - if entry, err := filer.LookupDirectoryEntry(*mountOptions.filer, dir.Path, name); err == nil { - if !entry.Found { - return nil, fuse.ENOENT - } - if entry.FileId != "" { - return &File{FileId: filer.FileId(entry.FileId), Name: name}, nil - } else { - return &Dir{Path: path.Join(dir.Path, name)}, nil - } - } - - return nil, fuse.ENOENT -} - -func (dir *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { - var ret []fuse.Dirent - if dir.DirentMap == nil { - dir.DirentMap = make(map[string]*fuse.Dirent) - } - if dirs, e := filer.ListDirectories(*mountOptions.filer, dir.Path); e == nil { - for _, d := range dirs.Directories { - dirent := fuse.Dirent{Name: string(d), Type: fuse.DT_Dir} - ret = append(ret, dirent) - dir.DirentMap[string(d)] = &dirent - } - } - if files, e := filer.ListFiles(*mountOptions.filer, dir.Path, ""); e == nil { - for _, f := range files.Files { - if fileId, e := storage.ParseFileId(string(f.Id)); e == nil { - fileInode := uint64(fileId.VolumeId)<<48 + fileId.Key - dirent := fuse.Dirent{Name: f.Name, Type: fuse.DT_File} - ret = append(ret, dirent) - dir.DirentMap[f.Name] = &dirent - fileIdMap[fileInode] = f.Id - } - } - } - return ret, nil -} - -func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { - name := path.Join(dir.Path, req.Name) - err := filer.DeleteDirectoryOrFile(*mountOptions.filer, name, req.Dir) - if err != nil { - fmt.Printf("Delete file %s [ERROR] %s\n", name, err) - } - return err -} - -type File struct { - FileId filer.FileId - Name string -} - -func (file *File) Attr(context context.Context, attr *fuse.Attr) error { - attr.Mode = 0444 - ret, err := filer.GetFileSize(*mountOptions.filer, string(file.FileId)) - if err == nil { - attr.Size = ret.Size - } else { - fmt.Printf("Get file %s attr [ERROR] %s\n", file.Name, err) - } - return err -} - -func (file *File) ReadAll(ctx context.Context) ([]byte, error) { - ret, err := filer.GetFileContent(*mountOptions.filer, string(file.FileId)) - if err == nil { - return ret.Content, nil - } - fmt.Printf("Get file %s content [ERROR] %s\n", file.Name, err) - return nil, err -} diff --git a/weed/filesys/dir.go b/weed/filesys/dir.go new file mode 100644 index 000000000..66877a5f6 --- /dev/null +++ b/weed/filesys/dir.go @@ -0,0 +1,62 @@ +package filesys + +import ( + "bazil.org/fuse/fs" + "bazil.org/fuse" + "context" + "os" + "fmt" + "path" + "github.com/chrislusf/seaweedfs/weed/filer" +) + +type Dir struct { + Path string + wfs *WFS +} + +func (dir *Dir) Attr(context context.Context, attr *fuse.Attr) error { + attr.Mode = os.ModeDir | 0555 + return nil +} + +func (dir *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) { + if entry, err := filer.LookupDirectoryEntry(dir.wfs.filer, dir.Path, name); err == nil { + if !entry.Found { + return nil, fuse.ENOENT + } + if entry.FileId != "" { + return &File{FileId: filer.FileId(entry.FileId), Name: name, wfs: dir.wfs}, nil + } else { + return &Dir{Path: path.Join(dir.Path, name), wfs: dir.wfs}, nil + } + } + + return nil, fuse.ENOENT +} + +func (dir *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { + var ret []fuse.Dirent + if dirs, e := filer.ListDirectories(dir.wfs.filer, dir.Path); e == nil { + for _, d := range dirs.Directories { + dirent := fuse.Dirent{Name: string(d), Type: fuse.DT_Dir} + ret = append(ret, dirent) + } + } + if files, e := filer.ListFiles(dir.wfs.filer, dir.Path, ""); e == nil { + for _, f := range files.Files { + dirent := fuse.Dirent{Name: f.Name, Type: fuse.DT_File} + ret = append(ret, dirent) + } + } + return ret, nil +} + +func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { + name := path.Join(dir.Path, req.Name) + err := filer.DeleteDirectoryOrFile(dir.wfs.filer, name, req.Dir) + if err != nil { + fmt.Printf("Delete file %s [ERROR] %s\n", name, err) + } + return err +} diff --git a/weed/filesys/file.go b/weed/filesys/file.go new file mode 100644 index 000000000..bb2e52113 --- /dev/null +++ b/weed/filesys/file.go @@ -0,0 +1,34 @@ +package filesys + +import ( + "bazil.org/fuse" + "fmt" + "github.com/chrislusf/seaweedfs/weed/filer" + "context" +) + +type File struct { + FileId filer.FileId + Name string + wfs *WFS +} + +func (file *File) Attr(context context.Context, attr *fuse.Attr) error { + attr.Mode = 0444 + ret, err := filer.GetFileSize(file.wfs.filer, string(file.FileId)) + if err == nil { + attr.Size = ret.Size + } else { + fmt.Printf("Get file %s attr [ERROR] %s\n", file.Name, err) + } + return err +} + +func (file *File) ReadAll(ctx context.Context) ([]byte, error) { + ret, err := filer.GetFileContent(file.wfs.filer, string(file.FileId)) + if err == nil { + return ret.Content, nil + } + fmt.Printf("Get file %s content [ERROR] %s\n", file.Name, err) + return nil, err +} diff --git a/weed/filesys/wfs.go b/weed/filesys/wfs.go new file mode 100644 index 000000000..f0716b650 --- /dev/null +++ b/weed/filesys/wfs.go @@ -0,0 +1,17 @@ +package filesys + +import "bazil.org/fuse/fs" + +type WFS struct { + filer string +} + +func NewSeaweedFileSystem(filer string) *WFS { + return &WFS{ + filer: filer, + } +} + +func (wfs *WFS) Root() (fs.Node, error) { + return &Dir{Path: "/", wfs: wfs}, nil +}