mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-08 15:41:15 +02:00
When every volume is full, a chunk upload fails only after the assign retry budget, the failed chunk's data is dropped, and the mount kept accepting writes anyway. cp would crawl for hours pushing the rest of the file through a pipeline that could not persist it, and only close() reported an error - a generic EIO. Poison the file handle on the first failed chunk upload so subsequent writes fail immediately, and map "no writable volumes" / "no free volumes" upload errors to ENOSPC so the writing process aborts with "No space left on device". Also guard lastErr with a mutex: it was written concurrently by uploader goroutines, and keep the first error so later failures do not mask the root cause.
32 lines
1.1 KiB
Go
32 lines
1.1 KiB
Go
package mount
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
// Once a chunk upload fails its data is gone, so the handle must reject
|
|
// further writes instead of buffering the rest of the file — against a full
|
|
// cluster that turned cp into an hours-long crawl that only errored at close.
|
|
func TestChunkedDirtyPagesFailWritesAfterUploadError(t *testing.T) {
|
|
fh := &FileHandle{wfs: &WFS{option: &Option{}}}
|
|
pages := newMemoryChunkPages(fh, 1024)
|
|
defer pages.Destroy()
|
|
pages.hasWrites = true
|
|
|
|
uploadErr := errors.New("assign volume failure: no writable volumes")
|
|
pages.setLastError(uploadErr)
|
|
|
|
if err := pages.AddPage(0, []byte("x"), true, 1); !errors.Is(err, uploadErr) {
|
|
t.Fatalf("AddPage after upload failure = %v, want sticky %v", err, uploadErr)
|
|
}
|
|
if err := pages.FlushData(); !errors.Is(err, uploadErr) {
|
|
t.Fatalf("FlushData after upload failure = %v, want wrapped %v", err, uploadErr)
|
|
}
|
|
// First failure wins; later errors must not mask the root cause.
|
|
pages.setLastError(errors.New("later error"))
|
|
if err := pages.LastError(); !errors.Is(err, uploadErr) {
|
|
t.Fatalf("LastError = %v, want first error %v", err, uploadErr)
|
|
}
|
|
}
|