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
This commit is contained in:
Nick Craig-Wood 2021-09-13 10:32:40 +01:00
parent 5b6bcfc184
commit 0902e5c48e

View file

@ -746,18 +746,23 @@ func (f *File) Truncate(size int64) (err error) {
copy(writers, f.writers) copy(writers, f.writers)
f.mu.Unlock() f.mu.Unlock()
// FIXME: handle closing writer
// If have writers then call truncate for each writer // If have writers then call truncate for each writer
if len(writers) != 0 { if len(writers) != 0 {
var openWriters = len(writers)
fs.Debugf(f.Path(), "Truncating %d file handles", len(writers)) fs.Debugf(f.Path(), "Truncating %d file handles", len(writers))
for _, h := range writers { for _, h := range writers {
truncateErr := h.Truncate(size) 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 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 // if o is nil it isn't valid yet