aboutsummaryrefslogtreecommitdiff
path: root/weed/filesys
diff options
context:
space:
mode:
Diffstat (limited to 'weed/filesys')
-rw-r--r--weed/filesys/dir.go34
-rw-r--r--weed/filesys/dir_rename.go38
-rw-r--r--weed/filesys/file.go1
-rw-r--r--weed/filesys/filehandle.go12
-rw-r--r--weed/filesys/fscache.go207
-rw-r--r--weed/filesys/fscache_test.go96
-rw-r--r--weed/filesys/wfs.go2
7 files changed, 54 insertions, 336 deletions
diff --git a/weed/filesys/dir.go b/weed/filesys/dir.go
index 9ef74a95c..77d01d463 100644
--- a/weed/filesys/dir.go
+++ b/weed/filesys/dir.go
@@ -27,6 +27,7 @@ type Dir struct {
var _ = fs.Node(&Dir{})
var _ = fs.NodeCreater(&Dir{})
var _ = fs.NodeMkdirer(&Dir{})
+var _ = fs.NodeFsyncer(&Dir{})
var _ = fs.NodeRequestLookuper(&Dir{})
var _ = fs.HandleReadDirAller(&Dir{})
var _ = fs.NodeRemover(&Dir{})
@@ -90,23 +91,27 @@ func (dir *Dir) setRootDirAttributes(attr *fuse.Attr) {
attr.BlockSize = 1024 * 1024
}
+func (dir *Dir) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
+ // fsync works at OS level
+ // write the file chunks to the filerGrpcAddress
+ glog.V(3).Infof("dir %s fsync %+v", dir.FullPath(), req)
+
+ return nil
+}
+
func (dir *Dir) newFile(name string, entry *filer_pb.Entry) fs.Node {
- return dir.wfs.fsNodeCache.EnsureFsNode(util.NewFullPath(dir.FullPath(), name), func() fs.Node {
- return &File{
- Name: name,
- dir: dir,
- wfs: dir.wfs,
- entry: entry,
- entryViewCache: nil,
- }
- })
+ return &File{
+ Name: name,
+ dir: dir,
+ wfs: dir.wfs,
+ entry: entry,
+ entryViewCache: nil,
+ }
}
func (dir *Dir) newDirectory(fullpath util.FullPath, entry *filer_pb.Entry) fs.Node {
- return dir.wfs.fsNodeCache.EnsureFsNode(fullpath, func() fs.Node {
- return &Dir{name: entry.Name, wfs: dir.wfs, entry: entry, parent: dir}
- })
+ return &Dir{name: entry.Name, wfs: dir.wfs, entry: entry, parent: dir}
}
@@ -306,8 +311,6 @@ func (dir *Dir) removeOneFile(req *fuse.RemoveRequest) error {
dir.wfs.deleteFileChunks(entry.Chunks)
- dir.wfs.fsNodeCache.DeleteFsNode(filePath)
-
dir.wfs.metaCache.DeleteEntry(context.Background(), filePath)
glog.V(3).Infof("remove file: %v", req)
@@ -324,7 +327,6 @@ func (dir *Dir) removeOneFile(req *fuse.RemoveRequest) error {
func (dir *Dir) removeFolder(req *fuse.RemoveRequest) error {
t := util.NewFullPath(dir.FullPath(), req.Name)
- dir.wfs.fsNodeCache.DeleteFsNode(t)
dir.wfs.metaCache.DeleteEntry(context.Background(), t)
@@ -417,8 +419,6 @@ func (dir *Dir) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp
func (dir *Dir) Forget() {
glog.V(3).Infof("Forget dir %s", dir.FullPath())
-
- dir.wfs.fsNodeCache.DeleteFsNode(util.FullPath(dir.FullPath()))
}
func (dir *Dir) maybeLoadEntry() error {
diff --git a/weed/filesys/dir_rename.go b/weed/filesys/dir_rename.go
index 0f7f131b1..120dffd1d 100644
--- a/weed/filesys/dir_rename.go
+++ b/weed/filesys/dir_rename.go
@@ -3,11 +3,12 @@ package filesys
import (
"context"
+ "github.com/seaweedfs/fuse"
+ "github.com/seaweedfs/fuse/fs"
+
"github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
"github.com/chrislusf/seaweedfs/weed/util"
- "github.com/seaweedfs/fuse"
- "github.com/seaweedfs/fuse/fs"
)
func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirectory fs.Node) error {
@@ -19,7 +20,15 @@ func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirector
glog.V(4).Infof("dir Rename %s => %s", oldPath, newPath)
- err := dir.wfs.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
+ // find local old entry
+ oldEntry, err := dir.wfs.metaCache.FindEntry(context.Background(), oldPath)
+ if err != nil {
+ glog.V(0).Infof("dir Rename can not find source %s : %v", oldPath, err)
+ return fuse.ENOENT
+ }
+
+ // update remote filer
+ err = dir.wfs.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
request := &filer_pb.AtomicRenameEntryRequest{
OldDirectory: dir.FullPath(),
@@ -30,21 +39,30 @@ func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirector
_, err := client.AtomicRenameEntry(context.Background(), request)
if err != nil {
- glog.V(0).Infof("dir Rename %s => %s : %v", oldPath, newPath, err)
return fuse.EIO
}
return nil
})
+ if err != nil {
+ glog.V(0).Infof("dir Rename %s => %s : %v", oldPath, newPath, err)
+ return fuse.EIO
+ }
- if err == nil {
-
- // fmt.Printf("rename path: %v => %v\n", oldPath, newPath)
- dir.wfs.fsNodeCache.Move(oldPath, newPath)
- delete(dir.wfs.handles, oldPath.AsInode())
-
+ // TODO: replicate renaming logic on filer
+ if err := dir.wfs.metaCache.DeleteEntry(context.Background(), oldPath); err != nil {
+ glog.V(0).Infof("dir Rename delete local %s => %s : %v", oldPath, newPath, err)
+ return fuse.EIO
+ }
+ oldEntry.FullPath = newPath
+ if err := dir.wfs.metaCache.InsertEntry(context.Background(), oldEntry); err != nil {
+ glog.V(0).Infof("dir Rename insert local %s => %s : %v", oldPath, newPath, err)
+ return fuse.EIO
}
+ // fmt.Printf("rename path: %v => %v\n", oldPath, newPath)
+ delete(dir.wfs.handles, oldPath.AsInode())
+
return err
}
diff --git a/weed/filesys/file.go b/weed/filesys/file.go
index dcda93522..f96cd8118 100644
--- a/weed/filesys/file.go
+++ b/weed/filesys/file.go
@@ -213,7 +213,6 @@ func (file *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) error {
func (file *File) Forget() {
t := util.NewFullPath(file.dir.FullPath(), file.Name)
glog.V(3).Infof("Forget file %s", t)
- file.wfs.fsNodeCache.DeleteFsNode(t)
}
func (file *File) maybeLoadEntry(ctx context.Context) error {
diff --git a/weed/filesys/filehandle.go b/weed/filesys/filehandle.go
index 31fd08f97..ca35bfd02 100644
--- a/weed/filesys/filehandle.go
+++ b/weed/filesys/filehandle.go
@@ -191,10 +191,16 @@ func (fh *FileHandle) Flush(ctx context.Context, req *fuse.FlushRequest) error {
if fh.f.entry.Attributes != nil {
fh.f.entry.Attributes.Mime = fh.contentType
- fh.f.entry.Attributes.Uid = req.Uid
- fh.f.entry.Attributes.Gid = req.Gid
+ if fh.f.entry.Attributes.Uid == 0 {
+ fh.f.entry.Attributes.Uid = req.Uid
+ }
+ if fh.f.entry.Attributes.Gid == 0 {
+ fh.f.entry.Attributes.Gid = req.Gid
+ }
+ if fh.f.entry.Attributes.Crtime == 0 {
+ fh.f.entry.Attributes.Crtime = time.Now().Unix()
+ }
fh.f.entry.Attributes.Mtime = time.Now().Unix()
- fh.f.entry.Attributes.Crtime = time.Now().Unix()
fh.f.entry.Attributes.FileMode = uint32(os.FileMode(fh.f.entry.Attributes.FileMode) &^ fh.f.wfs.option.Umask)
fh.f.entry.Attributes.Collection = fh.dirtyPages.collection
fh.f.entry.Attributes.Replication = fh.dirtyPages.replication
diff --git a/weed/filesys/fscache.go b/weed/filesys/fscache.go
deleted file mode 100644
index b146f0615..000000000
--- a/weed/filesys/fscache.go
+++ /dev/null
@@ -1,207 +0,0 @@
-package filesys
-
-import (
- "sync"
-
- "github.com/chrislusf/seaweedfs/weed/util"
- "github.com/seaweedfs/fuse/fs"
-)
-
-type FsCache struct {
- root *FsNode
- sync.RWMutex
-}
-type FsNode struct {
- parent *FsNode
- node fs.Node
- name string
- childrenLock sync.RWMutex
- children map[string]*FsNode
-}
-
-func newFsCache(root fs.Node) *FsCache {
- return &FsCache{
- root: &FsNode{
- node: root,
- },
- }
-}
-
-func (c *FsCache) GetFsNode(path util.FullPath) fs.Node {
-
- c.RLock()
- defer c.RUnlock()
-
- return c.doGetFsNode(path)
-}
-
-func (c *FsCache) doGetFsNode(path util.FullPath) fs.Node {
- t := c.root
- for _, p := range path.Split() {
- t = t.findChild(p)
- if t == nil {
- return nil
- }
- }
- return t.node
-}
-
-func (c *FsCache) SetFsNode(path util.FullPath, node fs.Node) {
-
- c.Lock()
- defer c.Unlock()
-
- c.doSetFsNode(path, node)
-}
-
-func (c *FsCache) doSetFsNode(path util.FullPath, node fs.Node) {
- t := c.root
- for _, p := range path.Split() {
- t = t.ensureChild(p)
- }
- t.node = node
-}
-
-func (c *FsCache) EnsureFsNode(path util.FullPath, genNodeFn func() fs.Node) fs.Node {
-
- c.Lock()
- defer c.Unlock()
-
- t := c.doGetFsNode(path)
- if t != nil {
- return t
- }
- t = genNodeFn()
- c.doSetFsNode(path, t)
- return t
-}
-
-func (c *FsCache) DeleteFsNode(path util.FullPath) {
-
- c.Lock()
- defer c.Unlock()
-
- t := c.root
- for _, p := range path.Split() {
- t = t.findChild(p)
- if t == nil {
- return
- }
- }
- if t.parent != nil {
- t.parent.disconnectChild(t)
- }
- t.deleteSelf()
-}
-
-// oldPath and newPath are full path including the new name
-func (c *FsCache) Move(oldPath util.FullPath, newPath util.FullPath) *FsNode {
-
- c.Lock()
- defer c.Unlock()
-
- // find old node
- src := c.root
- for _, p := range oldPath.Split() {
- src = src.findChild(p)
- if src == nil {
- return src
- }
- }
- if src.parent != nil {
- src.parent.disconnectChild(src)
- }
-
- // find new node
- target := c.root
- for _, p := range newPath.Split() {
- target = target.ensureChild(p)
- }
- parent := target.parent
- src.name = target.name
- if dir, ok := src.node.(*Dir); ok {
- dir.name = target.name // target is not Dir, but a shortcut
- }
- if f, ok := src.node.(*File); ok {
- f.Name = target.name
- if f.entry != nil {
- f.entry.Name = f.Name
- }
- }
- parent.disconnectChild(target)
-
- target.deleteSelf()
-
- src.connectToParent(parent)
-
- return src
-}
-
-func (n *FsNode) connectToParent(parent *FsNode) {
- n.parent = parent
- oldNode := parent.findChild(n.name)
- if oldNode != nil {
- oldNode.deleteSelf()
- }
- if dir, ok := n.node.(*Dir); ok {
- dir.parent = parent.node.(*Dir)
- }
- if f, ok := n.node.(*File); ok {
- f.dir = parent.node.(*Dir)
- }
- n.childrenLock.Lock()
- parent.children[n.name] = n
- n.childrenLock.Unlock()
-}
-
-func (n *FsNode) findChild(name string) *FsNode {
- n.childrenLock.RLock()
- defer n.childrenLock.RUnlock()
-
- child, found := n.children[name]
- if found {
- return child
- }
- return nil
-}
-
-func (n *FsNode) ensureChild(name string) *FsNode {
- n.childrenLock.Lock()
- defer n.childrenLock.Unlock()
-
- if n.children == nil {
- n.children = make(map[string]*FsNode)
- }
- child, found := n.children[name]
- if found {
- return child
- }
- t := &FsNode{
- parent: n,
- node: nil,
- name: name,
- children: nil,
- }
- n.children[name] = t
- return t
-}
-
-func (n *FsNode) disconnectChild(child *FsNode) {
- n.childrenLock.Lock()
- delete(n.children, child.name)
- n.childrenLock.Unlock()
- child.parent = nil
-}
-
-func (n *FsNode) deleteSelf() {
- n.childrenLock.Lock()
- for _, child := range n.children {
- child.deleteSelf()
- }
- n.children = nil
- n.childrenLock.Unlock()
-
- n.node = nil
- n.parent = nil
-
-}
diff --git a/weed/filesys/fscache_test.go b/weed/filesys/fscache_test.go
deleted file mode 100644
index 67f9aacc8..000000000
--- a/weed/filesys/fscache_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package filesys
-
-import (
- "testing"
-
- "github.com/chrislusf/seaweedfs/weed/util"
-)
-
-func TestPathSplit(t *testing.T) {
- parts := util.FullPath("/").Split()
- if len(parts) != 0 {
- t.Errorf("expecting an empty list, but getting %d", len(parts))
- }
-
- parts = util.FullPath("/readme.md").Split()
- if len(parts) != 1 {
- t.Errorf("expecting an empty list, but getting %d", len(parts))
- }
-
-}
-
-func TestFsCache(t *testing.T) {
-
- cache := newFsCache(nil)
-
- x := cache.GetFsNode(util.FullPath("/y/x"))
- if x != nil {
- t.Errorf("wrong node!")
- }
-
- p := util.FullPath("/a/b/c")
- cache.SetFsNode(p, &File{Name: "cc"})
- tNode := cache.GetFsNode(p)
- tFile := tNode.(*File)
- if tFile.Name != "cc" {
- t.Errorf("expecting a FsNode")
- }
-
- cache.SetFsNode(util.FullPath("/a/b/d"), &File{Name: "dd"})
- cache.SetFsNode(util.FullPath("/a/b/e"), &File{Name: "ee"})
- cache.SetFsNode(util.FullPath("/a/b/f"), &File{Name: "ff"})
- cache.SetFsNode(util.FullPath("/z"), &File{Name: "zz"})
- cache.SetFsNode(util.FullPath("/a"), &File{Name: "aa"})
-
- b := cache.GetFsNode(util.FullPath("/a/b"))
- if b != nil {
- t.Errorf("unexpected node!")
- }
-
- a := cache.GetFsNode(util.FullPath("/a"))
- if a == nil {
- t.Errorf("missing node!")
- }
-
- cache.DeleteFsNode(util.FullPath("/a"))
- if b != nil {
- t.Errorf("unexpected node!")
- }
-
- a = cache.GetFsNode(util.FullPath("/a"))
- if a != nil {
- t.Errorf("wrong DeleteFsNode!")
- }
-
- z := cache.GetFsNode(util.FullPath("/z"))
- if z == nil {
- t.Errorf("missing node!")
- }
-
- y := cache.GetFsNode(util.FullPath("/x/y"))
- if y != nil {
- t.Errorf("wrong node!")
- }
-
-}
-
-func TestFsCacheMove(t *testing.T) {
-
- cache := newFsCache(nil)
-
- cache.SetFsNode(util.FullPath("/a/b/d"), &File{Name: "dd"})
- cache.SetFsNode(util.FullPath("/a/b/e"), &File{Name: "ee"})
- cache.SetFsNode(util.FullPath("/z"), &File{Name: "zz"})
- cache.SetFsNode(util.FullPath("/a"), &File{Name: "aa"})
-
- cache.Move(util.FullPath("/a/b"), util.FullPath("/z/x"))
-
- d := cache.GetFsNode(util.FullPath("/z/x/d"))
- if d == nil {
- t.Errorf("unexpected nil node!")
- }
- if d.(*File).Name != "dd" {
- t.Errorf("unexpected non dd node!")
- }
-
-}
diff --git a/weed/filesys/wfs.go b/weed/filesys/wfs.go
index 1bd36167b..e41693048 100644
--- a/weed/filesys/wfs.go
+++ b/weed/filesys/wfs.go
@@ -64,7 +64,6 @@ type WFS struct {
stats statsCache
root fs.Node
- fsNodeCache *FsCache
chunkCache *chunk_cache.ChunkCache
metaCache *meta_cache.MetaCache
@@ -102,7 +101,6 @@ func NewSeaweedFileSystem(option *Option) *WFS {
})
wfs.root = &Dir{name: wfs.option.FilerMountRootPath, wfs: wfs}
- wfs.fsNodeCache = newFsCache(wfs.root)
return wfs
}