mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-22 22:11:39 +02:00
The max volume count subtracted each volume's remaining room from the free disk space, except when the master had preallocation turned on, in which case it subtracted nothing. That is wrong for a disk that mixes preallocated and plain volumes, and on platforms where preallocation is not supported. Use the larger of the .dat file's size and its allocated blocks, in the Go and the Rust volume server, so a preallocated volume counts as full and a plain one keeps its remaining room reserved. Fixes #5778 Co-authored-by: Dan Foster <4570306+danfoster@users.noreply.github.com>
54 lines
1.6 KiB
Go
54 lines
1.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/backend"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
|
|
)
|
|
|
|
func TestUnUsedSpaceCountsPreallocatedVolumesAsFull(t *testing.T) {
|
|
const volumeSizeLimit = 1 << 20
|
|
dir := t.TempDir()
|
|
|
|
preallocated, err := backend.CreateVolumeFile(filepath.Join(dir, "1.dat"), volumeSizeLimit, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer preallocated.Close()
|
|
fi, err := preallocated.(*backend.DiskFile).File.Stat()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if allocatedSize(fi) < volumeSizeLimit {
|
|
t.Skipf("filesystem at %s does not support fallocate", dir)
|
|
}
|
|
|
|
plainFile, err := os.Create(filepath.Join(dir, "2.dat"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := plainFile.Write(make([]byte, 4096)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
plain := backend.NewDiskFile(plainFile)
|
|
defer plain.Close()
|
|
fi, err = plainFile.Stat()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// The filesystem may round a small file up to a larger allocation unit.
|
|
plainSize := max(uint64(fi.Size()), allocatedSize(fi))
|
|
|
|
diskLocation := DiskLocation{Directory: dir, IdxDirectory: dir}
|
|
diskLocation.volumes = make(map[needle.VolumeId]*Volume)
|
|
diskLocation.SetVolume(1, &Volume{Id: 1, dir: dir, dirIdx: dir, DataBackend: preallocated, nm: &mockNeedleMapper{}})
|
|
diskLocation.SetVolume(2, &Volume{Id: 2, dir: dir, dirIdx: dir, DataBackend: plain, nm: &mockNeedleMapper{}})
|
|
|
|
if got, want := diskLocation.UnUsedSpace(volumeSizeLimit), volumeSizeLimit-plainSize; got != want {
|
|
t.Errorf("unUsedSpace = %d, want %d", got, want)
|
|
}
|
|
}
|