From 0902e5c48e21455f0884810546d45ea62d2f195b Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 13 Sep 2021 10:32:40 +0100 Subject: [PATCH] vfs: Ignore ECLOSED in Setattr when truncating file handles Before this change file handles could get closed while the truncate the file handles loop was running. This would mean that ocassionally an ECLOSED (which is translated into EBADF by cmd/mount) would spuriously be returned if Release happened to happen in the middle of a Truncate call (Setattr called with size=0). This change ignores the ECLOSED while truncating file handles. See: https://forum.rclone.org/t/writes-to-wasabi-mount-failing-with-bad-file-descriptor-intermittently/26321 --- vfs/file.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/vfs/file.go b/vfs/file.go index e30d85692..d890b1f54 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -746,18 +746,23 @@ func (f *File) Truncate(size int64) (err error) { copy(writers, f.writers) f.mu.Unlock() - // FIXME: handle closing writer - // If have writers then call truncate for each writer if len(writers) != 0 { + var openWriters = len(writers) fs.Debugf(f.Path(), "Truncating %d file handles", len(writers)) for _, h := range writers { truncateErr := h.Truncate(size) - if truncateErr != nil { + if truncateErr == ECLOSED { + // Ignore ECLOSED since file handle can get closed while this is running + openWriters-- + } else if truncateErr != nil { err = truncateErr } } - return err + // If at least one open writer return here + if openWriters > 0 { + return err + } } // if o is nil it isn't valid yet