aboutsummaryrefslogtreecommitdiff
path: root/weed/mount/directory_read.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/mount/directory_read.go')
-rw-r--r--weed/mount/directory_read.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/weed/mount/directory_read.go b/weed/mount/directory_read.go
new file mode 100644
index 000000000..51c51ae16
--- /dev/null
+++ b/weed/mount/directory_read.go
@@ -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() {
+}