diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go index 3fa5a48..62303df 100644 --- a/internal/fusefrontend/file.go +++ b/internal/fusefrontend/file.go @@ -286,7 +286,9 @@ func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) { f.fdLock.RLock() defer f.fdLock.RUnlock() if f.released { - // The file descriptor has been closed concurrently. + // The file descriptor has been closed concurrently, which also means + // the wlock has been freed. Exit here so we don't crash trying to access + // it. toggledlog.Warn.Printf("ino%d fh%d: Write on released file", f.ino, f.intFd()) return 0, fuse.EBADF } @@ -514,5 +516,14 @@ func (f *file) Utimens(a *time.Time, m *time.Time) fuse.Status { } fn := fmt.Sprintf("/proc/self/fd/%d", f.fd.Fd()) - return fuse.ToStatus(syscall.UtimesNano(fn, ts)) + err := syscall.UtimesNano(fn, ts) + if err != nil { + toggledlog.Debug.Printf("UtimesNano on %q failed: %v", fn, err) + } + if err == syscall.ENOENT { + // If /proc/self/fd/X did not exist, the actual error is that the file + // descriptor was invalid. + return fuse.EBADF + } + return fuse.ToStatus(err) } diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go index 5fea438..e946087 100644 --- a/internal/fusefrontend/fs_dir.go +++ b/internal/fusefrontend/fs_dir.go @@ -190,7 +190,7 @@ func (fs *FS) Rmdir(path string, context *fuse.Context) (code fuse.Status) { } return fuse.ToStatus(err) } - // Delete "gocryptfs.diriv.rmdir.INODENUMBER" + // Delete "gocryptfs.diriv.rmdir.XYZ" err = syscall.Unlinkat(int(parentDirFd.Fd()), tmpName) if err != nil { toggledlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)