diff --git a/weed/mount/weedfs.go b/weed/mount/weedfs.go index 38127617a..d7516b6c1 100644 --- a/weed/mount/weedfs.go +++ b/weed/mount/weedfs.go @@ -125,7 +125,7 @@ func (wfs *WFS) Init(server *fuse.Server) { wfs.fuseServer = server } -func (wfs *WFS) maybeReadEntry(inode uint64) (path util.FullPath, fh *FileHandle, entry *filer_pb.Entry, status fuse.Status) { +func (wfs *WFS) maybeReadEntry(inode uint64, followSymLink bool) (path util.FullPath, fh *FileHandle, entry *filer_pb.Entry, targetInode uint64, status fuse.Status) { path, status = wfs.inodeToPath.GetPath(inode) if status != fuse.OK { return @@ -136,11 +136,14 @@ func (wfs *WFS) maybeReadEntry(inode uint64) (path util.FullPath, fh *FileHandle if entry != nil && fh.entry.Attributes == nil { entry.Attributes = &filer_pb.FuseAttributes{} } - status = fuse.OK } else { entry, status = wfs.maybeLoadEntry(path) } - if status == fuse.OK && entry.FileMode()&os.ModeSymlink != 0 { + targetInode = inode + if status == fuse.OK && followSymLink && entry.FileMode()&os.ModeSymlink != 0 { + 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)) } diff --git a/weed/mount/weedfs_attr.go b/weed/mount/weedfs_attr.go index 41575a48f..032456399 100644 --- a/weed/mount/weedfs_attr.go +++ b/weed/mount/weedfs_attr.go @@ -16,15 +16,16 @@ func (wfs *WFS) GetAttr(cancel <-chan struct{}, input *fuse.GetAttrIn, out *fuse return fuse.OK } - _, _, entry, status := wfs.maybeReadEntry(input.NodeId) + inode := input.NodeId + _, _, entry, inode, status := wfs.maybeReadEntry(inode, true) if status == fuse.OK { out.AttrValid = 1 - wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry) + wfs.setAttrByPbEntry(&out.Attr, inode, entry) return status } else { - if fh, found := wfs.fhmap.FindFileHandle(input.NodeId); found { + if fh, found := wfs.fhmap.FindFileHandle(inode); found { out.AttrValid = 1 - wfs.setAttrByPbEntry(&out.Attr, input.NodeId, fh.entry) + wfs.setAttrByPbEntry(&out.Attr, inode, fh.entry) out.Nlink = 0 return fuse.OK } @@ -39,7 +40,7 @@ func (wfs *WFS) SetAttr(cancel <-chan struct{}, input *fuse.SetAttrIn, out *fuse return fuse.Status(syscall.ENOSPC) } - path, fh, entry, status := wfs.maybeReadEntry(input.NodeId) + path, fh, entry, inode, status := wfs.maybeReadEntry(input.NodeId, false) if status != fuse.OK { return status } @@ -111,7 +112,7 @@ func (wfs *WFS) SetAttr(cancel <-chan struct{}, input *fuse.SetAttrIn, out *fuse } out.AttrValid = 1 - wfs.setAttrByPbEntry(&out.Attr, input.NodeId, entry) + wfs.setAttrByPbEntry(&out.Attr, inode, entry) if fh != nil { fh.dirtyMetadata = true @@ -138,6 +139,9 @@ func (wfs *WFS) setRootAttr(out *fuse.AttrOut) { func (wfs *WFS) setAttrByPbEntry(out *fuse.Attr, inode uint64, entry *filer_pb.Entry) { out.Ino = inode + if entry.Attributes != nil && entry.Attributes.Inode != 0 { + out.Ino = entry.Attributes.Inode + } out.Size = filer.FileSize(entry) out.Blocks = (out.Size + blockSize - 1) / blockSize setBlksize(out, blockSize) diff --git a/weed/mount/weedfs_filehandle.go b/weed/mount/weedfs_filehandle.go index d769e51c5..ec174dd11 100644 --- a/weed/mount/weedfs_filehandle.go +++ b/weed/mount/weedfs_filehandle.go @@ -7,7 +7,7 @@ import ( func (wfs *WFS) AcquireHandle(inode uint64, uid, gid uint32) (fileHandle *FileHandle, status fuse.Status) { var entry *filer_pb.Entry - _, _, entry, status = wfs.maybeReadEntry(inode) + _, _, entry, inode, status = wfs.maybeReadEntry(inode, true) if status == fuse.OK { // need to AcquireFileHandle again to ensure correct handle counter fileHandle = wfs.fhmap.AcquireFileHandle(wfs, inode, entry) diff --git a/weed/mount/weedfs_xattr.go b/weed/mount/weedfs_xattr.go index fbfd6fca7..74ccd9336 100644 --- a/weed/mount/weedfs_xattr.go +++ b/weed/mount/weedfs_xattr.go @@ -36,7 +36,7 @@ func (wfs *WFS) GetXAttr(cancel <-chan struct{}, header *fuse.InHeader, attr str return 0, fuse.EINVAL } - _, _, entry, status := wfs.maybeReadEntry(header.NodeId) + _, _, entry, _, status := wfs.maybeReadEntry(header.NodeId, true) if status != fuse.OK { return 0, status } @@ -102,7 +102,7 @@ func (wfs *WFS) SetXAttr(cancel <-chan struct{}, input *fuse.SetXAttrIn, attr st } } - path, fh, entry, status := wfs.maybeReadEntry(input.NodeId) + path, fh, entry, _, status := wfs.maybeReadEntry(input.NodeId, true) if status != fuse.OK { return status } @@ -143,7 +143,7 @@ func (wfs *WFS) ListXAttr(cancel <-chan struct{}, header *fuse.InHeader, dest [] return 0, fuse.Status(syscall.ENOTSUP) } - _, _, entry, status := wfs.maybeReadEntry(header.NodeId) + _, _, entry, _, status := wfs.maybeReadEntry(header.NodeId, true) if status != fuse.OK { return 0, status } @@ -180,7 +180,7 @@ func (wfs *WFS) RemoveXAttr(cancel <-chan struct{}, header *fuse.InHeader, attr if len(attr) == 0 { return fuse.EINVAL } - path, fh, entry, status := wfs.maybeReadEntry(header.NodeId) + path, fh, entry, _, status := wfs.maybeReadEntry(header.NodeId, true) if status != fuse.OK { return status }