chrislu
3 years ago
7 changed files with 147 additions and 26 deletions
-
1go.mod
-
4weed/Makefile
-
2weed/command/mount2_std.go
-
42weed/mount/directory.go
-
84weed/mount/directory_read.go
-
34weed/mount/weedfs.go
-
6weed/mount/weedfs_stats.go
@ -0,0 +1,42 @@ |
|||||
|
package mount |
||||
|
|
||||
|
import ( |
||||
|
"bytes" |
||||
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" |
||||
|
"github.com/hanwen/go-fuse/v2/fs" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
type Directory struct { |
||||
|
fs.Inode |
||||
|
|
||||
|
name string |
||||
|
wfs *WFS |
||||
|
entry *filer_pb.Entry |
||||
|
parent *Directory |
||||
|
id uint64 |
||||
|
} |
||||
|
|
||||
|
func (dir *Directory) FullPath() string { |
||||
|
var parts []string |
||||
|
for p := dir; p != nil; p = p.parent { |
||||
|
if strings.HasPrefix(p.name, "/") { |
||||
|
if len(p.name) > 1 { |
||||
|
parts = append(parts, p.name[1:]) |
||||
|
} |
||||
|
} else { |
||||
|
parts = append(parts, p.name) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if len(parts) == 0 { |
||||
|
return "/" |
||||
|
} |
||||
|
|
||||
|
var buf bytes.Buffer |
||||
|
for i := len(parts) - 1; i >= 0; i-- { |
||||
|
buf.WriteString("/") |
||||
|
buf.WriteString(parts[i]) |
||||
|
} |
||||
|
return buf.String() |
||||
|
} |
@ -0,0 +1,84 @@ |
|||||
|
package mount |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"github.com/chrislusf/seaweedfs/weed/filer" |
||||
|
"github.com/chrislusf/seaweedfs/weed/filesys/meta_cache" |
||||
|
"github.com/chrislusf/seaweedfs/weed/glog" |
||||
|
"github.com/chrislusf/seaweedfs/weed/util" |
||||
|
"github.com/hanwen/go-fuse/v2/fs" |
||||
|
"github.com/hanwen/go-fuse/v2/fuse" |
||||
|
"math" |
||||
|
"os" |
||||
|
"syscall" |
||||
|
) |
||||
|
|
||||
|
var _ = fs.NodeReaddirer(&Directory{}) |
||||
|
var _ = fs.NodeGetattrer(&Directory{}) |
||||
|
|
||||
|
func (dir *Directory) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno { |
||||
|
out.Mode = 0755 |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
func (dir *Directory) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { |
||||
|
|
||||
|
dirPath := util.FullPath(dir.FullPath()) |
||||
|
glog.V(4).Infof("Readdir %s", dirPath) |
||||
|
|
||||
|
sourceChan := make(chan fuse.DirEntry, 64) |
||||
|
|
||||
|
stream := newDirectoryListStream(sourceChan) |
||||
|
|
||||
|
processEachEntryFn := func(entry *filer.Entry, isLast bool) { |
||||
|
sourceChan <- fuse.DirEntry{ |
||||
|
Mode: uint32(entry.Mode), |
||||
|
Name: entry.Name(), |
||||
|
Ino: dirPath.Child(entry.Name()).AsInode(os.ModeDir), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if err := meta_cache.EnsureVisited(dir.wfs.metaCache, dir.wfs, dirPath); err != nil { |
||||
|
glog.Errorf("dir ReadDirAll %s: %v", dirPath, err) |
||||
|
return nil, fs.ToErrno(os.ErrInvalid) |
||||
|
} |
||||
|
go func() { |
||||
|
dir.wfs.metaCache.ListDirectoryEntries(context.Background(), dirPath, "", false, int64(math.MaxInt32), func(entry *filer.Entry) bool { |
||||
|
processEachEntryFn(entry, false) |
||||
|
return true |
||||
|
}) |
||||
|
close(sourceChan) |
||||
|
}() |
||||
|
|
||||
|
return stream, fs.OK |
||||
|
} |
||||
|
|
||||
|
var _ = fs.DirStream(&DirectoryListStream{}) |
||||
|
|
||||
|
type DirectoryListStream struct { |
||||
|
next fuse.DirEntry |
||||
|
sourceChan chan fuse.DirEntry |
||||
|
isStarted bool |
||||
|
hasNext bool |
||||
|
} |
||||
|
|
||||
|
func newDirectoryListStream(ch chan fuse.DirEntry) *DirectoryListStream { |
||||
|
return &DirectoryListStream{ |
||||
|
sourceChan: ch, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (i *DirectoryListStream) HasNext() bool { |
||||
|
if !i.isStarted { |
||||
|
i.next, i.hasNext = <-i.sourceChan |
||||
|
i.isStarted = true |
||||
|
} |
||||
|
return i.hasNext |
||||
|
} |
||||
|
func (i *DirectoryListStream) Next() (fuse.DirEntry, syscall.Errno) { |
||||
|
t := i.next |
||||
|
i.next, i.hasNext = <-i.sourceChan |
||||
|
return t, fs.OK |
||||
|
} |
||||
|
func (i *DirectoryListStream) Close() { |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue