From e994ffa27d5c27c7502f657f6d2de2e105aaaa09 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 30 Jun 2016 23:12:22 +0200 Subject: [PATCH] fusefrontend: handle dir-overwrites-dir on XFS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XFS returns a different error code if you try to overwrite a non-empty directory with a directory: XFS: mv: cannot move ‘foo’ to ‘bar/foo’: File exists ext4: mv: cannot move 'foo' to 'bar/foo': Directory not empty So have EEXIST trigger the Rmdir logic as well. Fixes issue #20 Link: https://github.com/rfjakob/gocryptfs/issues/20 --- internal/fusefrontend/fs.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 49bd031..58881d1 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -408,10 +408,12 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod } // Actual rename err = syscall.Renameat(finalOldDirFd, finalOldPath, finalNewDirFd, finalNewPath) - if err == syscall.ENOTEMPTY { - // If an empty directory is overwritten we will always get ENOTEMPTY as + if 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. - // Handle that case by removing the target directory and trying again. + // Interestingly, ext4 returns ENOTEMPTY while xfs returns EEXIST. + // We handle that by trying to fs.Rmdir() the target directory and trying + // again. tlog.Debug.Printf("Rename: Handling ENOTEMPTY") if fs.Rmdir(newPath, context) == fuse.OK { err = syscall.Renameat(finalOldDirFd, finalOldPath, finalNewDirFd, finalNewPath)