aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorSebastian Lackner2017-11-25 01:56:56 +0100
committerrfjakob2017-11-25 16:19:09 +0100
commit9f56b33e0c8701085189aa77463f1b471b70a705 (patch)
tree924753e68c55dec84048c58678eb90f9361f3ea6 /internal
parentd257bb34c1dd478cdb62c0d19c3e280d4f8649b4 (diff)
fusefrontend: Fix longname handling for renames with existing target
Fixes https://github.com/rfjakob/gocryptfs/issues/170 Steps to reproduce the problem: * Create a regular forward mount point * Create a file with a shortname and one with a long filename * Try to run 'mv <shortname> <longname>' This should actually work and replace the existing file, but instead it fails with: mv: cannot move '<shortname>' to '<longname>': File exists The problem is the creation of the .name file. If the target already exists we can safely ignore the EEXIST error and just keep the existing .name file.
Diffstat (limited to 'internal')
-rw-r--r--internal/fusefrontend/fs.go8
-rw-r--r--internal/nametransform/longnames.go6
2 files changed, 12 insertions, 2 deletions
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go
index 3c442a5..b4819fd 100644
--- a/internal/fusefrontend/fs.go
+++ b/internal/fusefrontend/fs.go
@@ -517,7 +517,13 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
finalNewPath = cNewName
// Create destination .name file
err = fs.nameTransform.WriteLongName(newDirFd, cNewName, newPath)
- if err != nil {
+ // Failure to write the .name file is expected when the target path already
+ // exists. Since hashes are pretty unique, there is no need to modify the
+ // file anyway. We still set newDirFd to nil to ensure that we do not delete
+ // the file on error.
+ if err == syscall.EEXIST {
+ newDirFd = nil
+ } else if err != nil {
return fuse.ToStatus(err)
}
}
diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go
index 8af191d..7cd904e 100644
--- a/internal/nametransform/longnames.go
+++ b/internal/nametransform/longnames.go
@@ -114,7 +114,11 @@ func (n *NameTransform) WriteLongName(dirfd *os.File, hashName string, plainName
fdRaw, err := syscallcompat.Openat(int(dirfd.Fd()), hashName+LongNameSuffix,
syscall.O_WRONLY|syscall.O_CREAT|syscall.O_EXCL, 0600)
if err != nil {
- tlog.Warn.Printf("WriteLongName: Openat: %v", err)
+ // Don't warn if the file already exists - this is allowed for renames
+ // and should be handled by the caller.
+ if err != syscall.EEXIST {
+ tlog.Warn.Printf("WriteLongName: Openat: %v", err)
+ }
return err
}
fd := os.NewFile(uintptr(fdRaw), hashName+LongNameSuffix)