Browse Source

implement read directory and read directory plus

pull/2668/head
chrislu 3 years ago
parent
commit
72faae91e1
  1. 7
      weed/mount/weedfs.go
  2. 37
      weed/mount/weedfs_attr.go
  3. 71
      weed/mount/weedfs_dir.go

7
weed/mount/weedfs.go

@ -94,9 +94,10 @@ func (wfs *WFS) String() string {
return "seaweedfs" return "seaweedfs"
} }
func (wfs *WFS) maybeReadEntry(inode uint64) (*filer_pb.Entry, fuse.Status) {
path := wfs.inodeToPath.GetPath(inode)
return wfs.maybeLoadEntry(path)
func (wfs *WFS) maybeReadEntry(inode uint64) (path util.FullPath, entry *filer_pb.Entry, status fuse.Status) {
path = wfs.inodeToPath.GetPath(inode)
entry, status = wfs.maybeLoadEntry(path)
return
} }
func (wfs *WFS) maybeLoadEntry(fullpath util.FullPath) (*filer_pb.Entry, fuse.Status) { func (wfs *WFS) maybeLoadEntry(fullpath util.FullPath) (*filer_pb.Entry, fuse.Status) {

37
weed/mount/weedfs_attr.go

@ -16,11 +16,12 @@ func (wfs *WFS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse
return fuse.OK return fuse.OK
} }
entry, status := wfs.maybeReadEntry(input.NodeId)
_, entry, status := wfs.maybeReadEntry(input.NodeId)
if status != fuse.OK { if status != fuse.OK {
return status return status
} }
wfs.setOutAttr(out, input.NodeId, entry)
out.AttrValid = 1
wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry)
return fuse.OK return fuse.OK
} }
@ -54,16 +55,15 @@ func (wfs *WFS) setRootAttr(out *fuse.AttrOut) {
out.Mtime = now out.Mtime = now
out.Ctime = now out.Ctime = now
out.Atime = now out.Atime = now
out.Mode = osToSystemMode(os.ModeDir) | uint32(wfs.option.MountMode)
out.Mode = toSystemType(os.ModeDir) | uint32(wfs.option.MountMode)
out.Nlink = 1 out.Nlink = 1
} }
func (wfs *WFS) setOutAttr(out *fuse.AttrOut, inode uint64, entry *filer_pb.Entry) {
out.AttrValid = 1
func (wfs *WFS) setAttrByPbEntry(out *fuse.Attr, inode uint64, entry *filer_pb.Entry) {
out.Ino = inode out.Ino = inode
out.Uid = entry.Attributes.Uid out.Uid = entry.Attributes.Uid
out.Gid = entry.Attributes.Gid out.Gid = entry.Attributes.Gid
out.Mode = modeToSystemMode(entry.Attributes.FileMode)
out.Mode = toSystemMode(os.FileMode(entry.Attributes.FileMode))
out.Mtime = uint64(entry.Attributes.Mtime) out.Mtime = uint64(entry.Attributes.Mtime)
out.Ctime = uint64(entry.Attributes.Mtime) out.Ctime = uint64(entry.Attributes.Mtime)
out.Atime = uint64(entry.Attributes.Mtime) out.Atime = uint64(entry.Attributes.Mtime)
@ -72,15 +72,32 @@ func (wfs *WFS) setOutAttr(out *fuse.AttrOut, inode uint64, entry *filer_pb.Entr
} }
out.Size = filer.FileSize(entry) out.Size = filer.FileSize(entry)
out.Blocks = out.Size/blockSize + 1 out.Blocks = out.Size/blockSize + 1
setBlksize(&out.Attr, blockSize)
setBlksize(out, blockSize)
out.Nlink = 1
}
func (wfs *WFS) setAttrByFilerEntry(out *fuse.Attr, inode uint64, entry *filer.Entry) {
out.Ino = inode
out.Uid = entry.Attr.Uid
out.Gid = entry.Attr.Gid
out.Mode = toSystemMode(entry.Attr.Mode)
out.Mtime = uint64(entry.Attr.Mtime.Unix())
out.Ctime = uint64(entry.Attr.Mtime.Unix())
out.Atime = uint64(entry.Attr.Mtime.Unix())
if entry.HardLinkCounter > 0 {
out.Nlink = uint32(entry.HardLinkCounter)
}
out.Size = entry.FileSize
out.Blocks = out.Size/blockSize + 1
setBlksize(out, blockSize)
out.Nlink = 1 out.Nlink = 1
} }
func modeToSystemMode(mode uint32) uint32 {
return osToSystemMode(os.FileMode(mode)) | mode
func toSystemMode(mode os.FileMode) uint32 {
return toSystemType(mode) | uint32(mode)
} }
func osToSystemMode(mode os.FileMode) uint32 {
func toSystemType(mode os.FileMode) uint32 {
switch mode & os.ModeType { switch mode & os.ModeType {
case os.ModeDir: case os.ModeDir:
return syscall.S_IFDIR return syscall.S_IFDIR

71
weed/mount/weedfs_dir.go

@ -0,0 +1,71 @@
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/hanwen/go-fuse/v2/fuse"
"math"
)
// Directory handling
func (wfs *WFS) OpenDir(cancel <-chan struct{}, input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) {
return fuse.OK
}
func (wfs *WFS) ReleaseDir(input *fuse.ReleaseIn) {
}
func (wfs *WFS) FsyncDir(cancel <-chan struct{}, input *fuse.FsyncIn) (code fuse.Status) {
return fuse.OK
}
func (wfs *WFS) ReadDir(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
return wfs.doReadDirectory(input, out, false)
}
func (wfs *WFS) ReadDirPlus(cancel <-chan struct{}, input *fuse.ReadIn, out *fuse.DirEntryList) (code fuse.Status) {
return wfs.doReadDirectory(input, out, true)
}
func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPlusMode bool) fuse.Status {
dirPath := wfs.inodeToPath.GetPath(input.NodeId)
var dirEntry fuse.DirEntry
processEachEntryFn := func(entry *filer.Entry, isLast bool) bool {
dirEntry.Name = entry.Name()
inode := wfs.inodeToPath.GetInode(dirPath.Child(dirEntry.Name))
dirEntry.Ino = inode
dirEntry.Mode = toSystemMode(entry.Mode)
if !isPlusMode {
if !out.AddDirEntry(dirEntry) {
return false
}
} else {
entryOut := out.AddDirLookupEntry(dirEntry)
if entryOut == nil {
return false
}
entryOut.Generation = 1
entryOut.EntryValid = 1
entryOut.AttrValid = 1
wfs.setAttrByFilerEntry(&entryOut.Attr, inode, entry)
}
return true
}
// TODO remove this with checking whether directory is not forgotten
if err := meta_cache.EnsureVisited(wfs.metaCache, wfs, dirPath); err != nil {
glog.Errorf("dir ReadDirAll %s: %v", dirPath, err)
return fuse.EIO
}
listErr := wfs.metaCache.ListDirectoryEntries(context.Background(), dirPath, "", false, int64(math.MaxInt32), func(entry *filer.Entry) bool {
return processEachEntryFn(entry, false)
})
if listErr != nil {
glog.Errorf("list meta cache: %v", listErr)
return fuse.EIO
}
return fuse.OK
}
Loading…
Cancel
Save