diff --git a/weed/filer/leveldb2/leveldb2_store.go b/weed/filer/leveldb2/leveldb2_store.go index 6bb51a785a..5eb231f80f 100644 --- a/weed/filer/leveldb2/leveldb2_store.go +++ b/weed/filer/leveldb2/leveldb2_store.go @@ -6,6 +6,7 @@ import ( "crypto/md5" "fmt" "io" + "math" "os" "github.com/syndtr/goleveldb/leveldb" @@ -56,20 +57,29 @@ func (store *LevelDB2Store) buildOptions() *opt.Options { ReadOnly: store.ReadOnly, } if store.blockCacheSizeMB > 0 { - opts.BlockCacheCapacity = store.blockCacheSizeMB * 1024 * 1024 + opts.BlockCacheCapacity = scaled(store.blockCacheSizeMB, 1<<20) } if store.writeBufferSizeMB > 0 { - opts.WriteBuffer = store.writeBufferSizeMB * 1024 * 1024 + opts.WriteBuffer = scaled(store.writeBufferSizeMB, 1<<20) } if store.blockSizeKB > 0 { - opts.BlockSize = store.blockSizeKB * 1024 + opts.BlockSize = scaled(store.blockSizeKB, 1<<10) } if store.compactionTableSizeMB > 0 { - opts.CompactionTableSize = store.compactionTableSizeMB * 1024 * 1024 + opts.CompactionTableSize = scaled(store.compactionTableSizeMB, 1<<20) } return opts } +// scaled converts a size option to bytes, saturating instead of wrapping a +// huge value into a negative int on 32-bit builds. +func scaled(v, scale int) int { + if v > math.MaxInt/scale { + return math.MaxInt + } + return v * scale +} + func (store *LevelDB2Store) initialize(dir string, dbCount int) (err error) { glog.Infof("filer store leveldb2 dir: %s", dir) os.MkdirAll(dir, 0755) diff --git a/weed/filer/leveldb2/leveldb2_store_test.go b/weed/filer/leveldb2/leveldb2_store_test.go index b061eb0476..65d2de9f03 100644 --- a/weed/filer/leveldb2/leveldb2_store_test.go +++ b/weed/filer/leveldb2/leveldb2_store_test.go @@ -2,6 +2,7 @@ package leveldb import ( "context" + "math" "testing" "github.com/seaweedfs/seaweedfs/weed/filer" @@ -138,6 +139,18 @@ func TestInitializeDefaultOptions(t *testing.T) { } } +func TestScaledSaturates(t *testing.T) { + if got := scaled(math.MaxInt, 1<<20); got != math.MaxInt { + t.Errorf("expected saturation at %d, got %d", math.MaxInt, got) + } + if got := scaled(64, 1<<20); got != 64*1024*1024 { + t.Errorf("expected 64MiB, got %d", got) + } + if got := scaled(4, 1<<10); got != 4*1024 { + t.Errorf("expected 4KiB, got %d", got) + } +} + func TestEmptyRoot(t *testing.T) { testFiler := filer.NewFiler(pb.ServerDiscovery{}, nil, "", "", "", "", "", 255, nil) dir := t.TempDir()