mirror of
https://github.com/rclone/rclone.git
synced 2026-07-12 16:55:58 -04:00
cmd/mount2: fix ESTALE over NFS by reporting stable inode numbers
setAttr left attr.Ino unset (0) and the NewInode sites left StableAttr.Ino
unset, so the kernel saw inode 0 while the node identity differed, which
breaks NFS file-handle validation. Set both to the stable VFS inode. The
bazil cmd/mount backend does not hit this because its framework assigns
stable inodes automatically; go-fuse needs them set explicitly.
Before: chmod/chown/truncate on a just-written file through an
NFS-exported mount2 mount failed with ESTALE.
After: they succeed.
Exercising the NFS handle-validation path needs a kernel NFS server, so it
isn't covered by the local vfstest harness; validated against a real Linux
nfs-kernel-server export over NFSv3, NFSv4.0 and NFSv4.2.
#9547
(cherry picked from commit 92b78aefa4)
This commit is contained in:
committed by
Nick Craig-Wood
parent
e4093ec952
commit
b9fd40d182
@@ -75,6 +75,7 @@ func setAttr(node vfs.Node, attr *fuse.Attr) {
|
||||
vfs := node.VFS()
|
||||
attr.Owner.Gid = vfs.Opt.GID
|
||||
attr.Owner.Uid = vfs.Opt.UID
|
||||
attr.Ino = node.Inode()
|
||||
attr.Mode = getMode(node)
|
||||
attr.Size = Size
|
||||
attr.Nlink = 1
|
||||
|
||||
@@ -201,7 +201,7 @@ func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (ino
|
||||
// out.SetAttrTimeout(dt time.Duration)
|
||||
n.fsys.setEntryOut(vfsNode, out)
|
||||
|
||||
return n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode}), 0
|
||||
return n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode, Ino: newNode.node.Inode()}), 0
|
||||
}
|
||||
|
||||
var _ = (fusefs.NodeLookuper)((*Node)(nil))
|
||||
@@ -337,7 +337,7 @@ func (n *Node) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.En
|
||||
}
|
||||
newNode := newNode(n.fsys, newDir)
|
||||
n.fsys.setEntryOut(newNode.node, out)
|
||||
newInode := n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode})
|
||||
newInode := n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode, Ino: newNode.node.Inode()})
|
||||
return newInode, 0
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ func (n *Node) Create(ctx context.Context, name string, flags uint32, mode uint3
|
||||
n.fsys.setEntryOut(vfsNode, out)
|
||||
newNode := newNode(n.fsys, vfsNode)
|
||||
fs.Debugf(nil, "attr=%#v", out.Attr)
|
||||
newInode := n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode})
|
||||
newInode := n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode, Ino: newNode.node.Inode()})
|
||||
return newInode, fh, 0, 0
|
||||
}
|
||||
|
||||
@@ -528,7 +528,7 @@ func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.Entry
|
||||
|
||||
n.fsys.setEntryOut(vfsNode, out)
|
||||
newNode := newNode(n.fsys, vfsNode)
|
||||
newInode := n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode})
|
||||
newInode := n.NewInode(ctx, newNode, fusefs.StableAttr{Mode: out.Attr.Mode, Ino: newNode.node.Inode()})
|
||||
|
||||
return newInode, 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user