diff options
author | Jakob Unterwurzacher | 2020-05-24 20:19:27 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2020-05-24 20:19:27 +0200 |
commit | cb8872577d66ff0fc38bcd70493be06bc0f34ffa (patch) | |
tree | f5821da461a297a3219e3544fde32d41093983a3 /internal/fusefrontend/fs.go | |
parent | 2a9b99a0ef8d1eb8b067374462f31a19a098ef64 (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.go | 9 |
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) } } |