summaryrefslogtreecommitdiff
path: root/internal/fusefrontend/node.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-07-12 13:53:47 +0200
committerJakob Unterwurzacher2020-07-12 13:55:24 +0200
commit230d92c4f461f96ff95c07c92010790102a51edd (patch)
tree52f2e32a9ee5b34931f1123c0b7058a565e62346 /internal/fusefrontend/node.go
parentf3a0dbabeedf3290b27c603b91bcf7ae5a65ad72 (diff)
v2api: fix Rename trying to overwrite itself
We used to do this [pid 99182] renameat2(14, "Y_4DAxKvj1QnXmJx2AkrKA", 15, ".", RENAME_NOREPLACE <unfinished ...> which was not the intention.
Diffstat (limited to 'internal/fusefrontend/node.go')
-rw-r--r--internal/fusefrontend/node.go5
1 files changed, 3 insertions, 2 deletions
diff --git a/internal/fusefrontend/node.go b/internal/fusefrontend/node.go
index 6cdc552..2c9a4f7 100644
--- a/internal/fusefrontend/node.go
+++ b/internal/fusefrontend/node.go
@@ -453,6 +453,7 @@ func (n *Node) Symlink(ctx context.Context, target, name string, out *fuse.Entry
}
// Rename - FUSE call.
+// This function is called on the PARENT DIRECTORY of `name`.
//
// Symlink-safe through Renameat().
func (n *Node) Rename(ctx context.Context, name string, newParent fs.InodeEmbedder, newName string, flags uint32) (errno syscall.Errno) {
@@ -463,7 +464,7 @@ func (n *Node) Rename(ctx context.Context, name string, newParent fs.InodeEmbedd
defer syscall.Close(dirfd)
n2 := toNode(newParent)
- dirfd2, cName2, errno := n2.prepareAtSyscall("")
+ dirfd2, cName2, errno := n2.prepareAtSyscall(newName)
if errno != 0 {
return
}
@@ -491,7 +492,7 @@ func (n *Node) Rename(ctx context.Context, name string, newParent fs.InodeEmbedd
// Actual rename
tlog.Debug.Printf("Renameat %d/%s -> %d/%s\n", dirfd, cName, dirfd2, cName2)
err = unix.Renameat2(dirfd, cName, dirfd2, cName2, uint(flags))
- if err == syscall.ENOTEMPTY || err == syscall.EEXIST {
+ if (flags&unix.RENAME_NOREPLACE == 0) && (err == syscall.ENOTEMPTY || err == syscall.EEXIST) {
// If an empty directory is overwritten we will always get an error as
// the "empty" directory will still contain gocryptfs.diriv.
// Interestingly, ext4 returns ENOTEMPTY while xfs returns EEXIST.