From e0eda52c5418f53fda895741a1878e66d8dffb44 Mon Sep 17 00:00:00 2001 From: chrislu Date: Thu, 28 Jul 2022 16:32:00 -0700 Subject: [PATCH] mount: ensure symlink parent directory is tracked fix https://github.com/chrislusf/seaweedfs/issues/3373 --- weed/mount/inode_to_path.go | 15 +++++++++++++++ weed/mount/weedfs.go | 6 ++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/weed/mount/inode_to_path.go b/weed/mount/inode_to_path.go index 0c34b2ab4..f12121dd9 100644 --- a/weed/mount/inode_to_path.go +++ b/weed/mount/inode_to_path.go @@ -5,6 +5,7 @@ import ( "github.com/chrislusf/seaweedfs/weed/util" "github.com/hanwen/go-fuse/v2/fuse" "sync" + "time" ) type InodeToPath struct { @@ -52,6 +53,20 @@ func NewInodeToPath(root util.FullPath) *InodeToPath { return t } +// EnsurePath make sure the full path is tracked, used by symlink. +func (i *InodeToPath) EnsurePath(path util.FullPath, isDirectory bool) bool { + for { + dir, _ := path.DirAndName() + if dir == "/" { + return true + } + if i.EnsurePath(util.FullPath(dir), true) { + i.Lookup(path, time.Now().Unix(), isDirectory, false, 0, false) + } + } + return false +} + func (i *InodeToPath) Lookup(path util.FullPath, unixTime int64, isDirectory bool, isHardlink bool, possibleInode uint64, isLookup bool) uint64 { i.Lock() defer i.Unlock() diff --git a/weed/mount/weedfs.go b/weed/mount/weedfs.go index d7516b6c1..f360594f9 100644 --- a/weed/mount/weedfs.go +++ b/weed/mount/weedfs.go @@ -144,8 +144,10 @@ func (wfs *WFS) maybeReadEntry(inode uint64, followSymLink bool) (path util.Full if entry != nil && entry.Attributes != nil && entry.Attributes.Inode != 0 { targetInode = entry.Attributes.Inode } - target := filepath.Join(string(path), "../"+entry.Attributes.SymlinkTarget) - entry, status = wfs.maybeLoadEntry(util.FullPath(target)) + target := util.FullPath(filepath.Join(string(path), "../"+entry.Attributes.SymlinkTarget)) + targetParent, _ := target.DirAndName() + wfs.inodeToPath.EnsurePath(util.FullPath(targetParent), true) + entry, status = wfs.maybeLoadEntry(target) } return }