summaryrefslogtreecommitdiff
path: root/internal/fusefrontend/fs.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-05-24 20:19:27 +0200
committerJakob Unterwurzacher2020-05-24 20:19:27 +0200
commitcb8872577d66ff0fc38bcd70493be06bc0f34ffa (patch)
treef5821da461a297a3219e3544fde32d41093983a3 /internal/fusefrontend/fs.go
parent2a9b99a0ef8d1eb8b067374462f31a19a098ef64 (diff)
fusefrontend: don't always clear the dircache in Rename
When filename encryption is on, we do know when we overwrite a directory, and can clear only in this case. sshfs-benchmark.bash: sshfs gocryptfs-on-sshfs git init 1.74 7.80 rsync 6.19 11.63
Diffstat (limited to 'internal/fusefrontend/fs.go')
-rw-r--r--internal/fusefrontend/fs.go9
1 files changed, 8 insertions, 1 deletions
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go
index e8dae9f..db473ee 100644
--- a/internal/fusefrontend/fs.go
+++ b/internal/fusefrontend/fs.go
@@ -533,7 +533,6 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
//
// Symlink-safe through Renameat().
func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (code fuse.Status) {
- defer fs.dirCache.Clear()
if fs.isFiltered(newPath) {
return fuse.EPERM
}
@@ -549,6 +548,9 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
defer syscall.Close(newDirfd)
// Easy case.
if fs.args.PlaintextNames {
+ // The rename may replace another directory. Make sure we drop the
+ // deleted directory from the cache.
+ defer fs.dirCache.Clear()
return fuse.ToStatus(syscallcompat.Renameat(oldDirfd, oldCName, newDirfd, newCName))
}
// Long destination file name: create .name file
@@ -575,6 +577,11 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
// again.
tlog.Debug.Printf("Rename: Handling ENOTEMPTY")
if fs.Rmdir(newPath, context) == fuse.OK {
+ // The rename replaced another directory. Make sure we drop the
+ // deleted directory from the cache (note: fs.Rmdir also clears it,
+ // but this is not guaranteed forever, and a double clear does no
+ // harm).
+ defer fs.dirCache.Clear()
err = syscallcompat.Renameat(oldDirfd, oldCName, newDirfd, newCName)
}
}