diff --git a/cmd/frostfs-node/config.go b/cmd/frostfs-node/config.go index 8286bc7d7..2d6d8c2c2 100644 --- a/cmd/frostfs-node/config.go +++ b/cmd/frostfs-node/config.go @@ -796,6 +796,7 @@ func (c *cfg) getSubstorageOpts(shCfg shardCfg) []blobstor.SubStorage { Policy: func(_ *objectSDK.Object, data []byte) bool { return uint64(len(data)) < shCfg.smallSizeObjectLimit }, + SupportsStorageID: true, }) case fstree.Type: fstreeOpts := []fstree.Option{ diff --git a/pkg/local_object_storage/blobstor/blobstor.go b/pkg/local_object_storage/blobstor/blobstor.go index d2a2338a3..2dfcbf15f 100644 --- a/pkg/local_object_storage/blobstor/blobstor.go +++ b/pkg/local_object_storage/blobstor/blobstor.go @@ -13,8 +13,9 @@ import ( // SubStorage represents single storage component with some storage policy. type SubStorage struct { - Storage common.Storage - Policy func(*objectSDK.Object, []byte) bool + Storage common.Storage + Policy func(*objectSDK.Object, []byte) bool + SupportsStorageID bool } // BlobStor represents FrostFS local BLOB storage. diff --git a/pkg/local_object_storage/blobstor/blobstor_test.go b/pkg/local_object_storage/blobstor/blobstor_test.go index f1d567da7..7b90f359a 100644 --- a/pkg/local_object_storage/blobstor/blobstor_test.go +++ b/pkg/local_object_storage/blobstor/blobstor_test.go @@ -27,6 +27,7 @@ func defaultTestStorages(p string, smallSizeLimit uint64) ([]SubStorage, *testst Policy: func(_ *objectSDK.Object, data []byte) bool { return uint64(len(data)) <= smallSizeLimit }, + SupportsStorageID: true, }, { Storage: largeFileStorage, @@ -121,6 +122,7 @@ func TestBlobstor_needsCompression(t *testing.T) { Policy: func(_ *objectSDK.Object, data []byte) bool { return uint64(len(data)) < smallSizeLimit }, + SupportsStorageID: true, }, { Storage: fstree.New(fstree.WithPath(dir)), diff --git a/pkg/local_object_storage/blobstor/control.go b/pkg/local_object_storage/blobstor/control.go index 4b8a36de8..7b9b0554b 100644 --- a/pkg/local_object_storage/blobstor/control.go +++ b/pkg/local_object_storage/blobstor/control.go @@ -6,6 +6,7 @@ import ( "fmt" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "go.uber.org/zap" ) @@ -77,3 +78,25 @@ func (b *BlobStor) Close() error { } return firstErr } + +func (b *BlobStor) selectStorages(storageID []byte) []common.Storage { + var res []common.Storage + if storageID == nil { + for idx := range b.storage { + res = append(res, b.storage[idx].Storage) + } + } else if len(storageID) > 0 { + for idx := range b.storage { + if b.storage[idx].SupportsStorageID { + res = append(res, b.storage[idx].Storage) + } + } + } else { + for idx := range b.storage { + if !b.storage[idx].SupportsStorageID { + res = append(res, b.storage[idx].Storage) + } + } + } + return res +} diff --git a/pkg/local_object_storage/blobstor/delete.go b/pkg/local_object_storage/blobstor/delete.go index 8930980a6..37cbf8742 100644 --- a/pkg/local_object_storage/blobstor/delete.go +++ b/pkg/local_object_storage/blobstor/delete.go @@ -6,8 +6,10 @@ import ( "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" + apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) @@ -31,32 +33,16 @@ func (b *BlobStor) Delete(ctx context.Context, prm common.DeletePrm) (common.Del b.modeMtx.RLock() defer b.modeMtx.RUnlock() - if prm.StorageID == nil { - for i := range b.storage { - res, err := b.storage[i].Storage.Delete(ctx, prm) - if err == nil || !client.IsErrObjectNotFound(err) { - if err == nil { - success = true - logOp(b.log, deleteOp, prm.Address, b.storage[i].Storage.Type(), prm.StorageID) - } - return res, err + for _, storage := range b.selectStorages(prm.StorageID) { + res, err := storage.Delete(ctx, prm) + if err == nil || !client.IsErrObjectNotFound(err) { + if err == nil { + success = true + logOp(b.log, deleteOp, prm.Address, storage.Type(), prm.StorageID) } + return res, err } } - var st common.Storage - - if len(prm.StorageID) == 0 { - st = b.storage[len(b.storage)-1].Storage - } else { - st = b.storage[0].Storage - } - - res, err := st.Delete(ctx, prm) - if err == nil { - success = true - logOp(b.log, deleteOp, prm.Address, st.Type(), prm.StorageID) - } - - return res, err + return common.DeleteRes{}, logicerr.Wrap(new(apistatus.ObjectNotFound)) } diff --git a/pkg/local_object_storage/blobstor/exists.go b/pkg/local_object_storage/blobstor/exists.go index 03dad392a..6a442de34 100644 --- a/pkg/local_object_storage/blobstor/exists.go +++ b/pkg/local_object_storage/blobstor/exists.go @@ -36,29 +36,9 @@ func (b *BlobStor) Exists(ctx context.Context, prm common.ExistsPrm) (common.Exi b.modeMtx.RLock() defer b.modeMtx.RUnlock() - if prm.StorageID != nil { - if len(prm.StorageID) == 0 { - res, err := b.storage[len(b.storage)-1].Storage.Exists(ctx, prm) - exists = err == nil && res.Exists - return res, err - } - res, err := b.storage[0].Storage.Exists(ctx, prm) - exists = err == nil && res.Exists - return res, err - } - - // If there was an error during existence check below, - // it will be returned unless object was found in blobovnicza. - // Otherwise, it is logged and the latest error is returned. - // FSTree | Blobovnicza | Behaviour - // found | (not tried) | return true, nil - // not found | any result | return the result - // error | found | log the error, return true, nil - // error | not found | return the error - // error | error | log the first error, return the second var errors []error - for i := range b.storage { - res, err := b.storage[i].Storage.Exists(ctx, prm) + for _, storage := range b.selectStorages(prm.StorageID) { + res, err := storage.Exists(ctx, prm) if err == nil && res.Exists { exists = true return res, nil diff --git a/pkg/local_object_storage/blobstor/get.go b/pkg/local_object_storage/blobstor/get.go index 00ed18d7b..0ae849786 100644 --- a/pkg/local_object_storage/blobstor/get.go +++ b/pkg/local_object_storage/blobstor/get.go @@ -36,20 +36,12 @@ func (b *BlobStor) Get(ctx context.Context, prm common.GetPrm) (res common.GetRe b.modeMtx.RLock() defer b.modeMtx.RUnlock() - if prm.StorageID == nil { - for i := range b.storage { - res, err = b.storage[i].Storage.Get(ctx, prm) - if err == nil || !client.IsErrObjectNotFound(err) { - return res, err - } + for _, storage := range b.selectStorages(prm.StorageID) { + res, err = storage.Get(ctx, prm) + if err == nil || !client.IsErrObjectNotFound(err) { + return res, err } + } - return common.GetRes{}, logicerr.Wrap(new(apistatus.ObjectNotFound)) - } - if len(prm.StorageID) == 0 { - res, err = b.storage[len(b.storage)-1].Storage.Get(ctx, prm) - } else { - res, err = b.storage[0].Storage.Get(ctx, prm) - } - return res, err + return common.GetRes{}, logicerr.Wrap(new(apistatus.ObjectNotFound)) } diff --git a/pkg/local_object_storage/blobstor/get_range.go b/pkg/local_object_storage/blobstor/get_range.go index 50abd19fa..6e3e4a280 100644 --- a/pkg/local_object_storage/blobstor/get_range.go +++ b/pkg/local_object_storage/blobstor/get_range.go @@ -38,20 +38,12 @@ func (b *BlobStor) GetRange(ctx context.Context, prm common.GetRangePrm) (res co b.modeMtx.RLock() defer b.modeMtx.RUnlock() - if prm.StorageID == nil { - for i := range b.storage { - res, err = b.storage[i].Storage.GetRange(ctx, prm) - if err == nil || !client.IsErrObjectNotFound(err) { - return res, err - } + for _, storage := range b.selectStorages(prm.StorageID) { + res, err = storage.GetRange(ctx, prm) + if err == nil || !client.IsErrObjectNotFound(err) { + return res, err } + } - return common.GetRangeRes{}, logicerr.Wrap(new(apistatus.ObjectNotFound)) - } - if len(prm.StorageID) == 0 { - res, err = b.storage[len(b.storage)-1].Storage.GetRange(ctx, prm) - } else { - res, err = b.storage[0].Storage.GetRange(ctx, prm) - } - return res, err + return common.GetRangeRes{}, logicerr.Wrap(new(apistatus.ObjectNotFound)) } diff --git a/pkg/local_object_storage/engine/engine_test.go b/pkg/local_object_storage/engine/engine_test.go index 934bea8bb..c26be0647 100644 --- a/pkg/local_object_storage/engine/engine_test.go +++ b/pkg/local_object_storage/engine/engine_test.go @@ -148,6 +148,7 @@ func newStorages(root string, smallSize uint64) []blobstor.SubStorage { Policy: func(_ *objectSDK.Object, data []byte) bool { return uint64(len(data)) < smallSize }, + SupportsStorageID: true, }, { Storage: fstree.New( @@ -176,6 +177,7 @@ func newTestStorages(root string, smallSize uint64) ([]blobstor.SubStorage, *tes Policy: func(_ *objectSDK.Object, data []byte) bool { return uint64(len(data)) < smallSize }, + SupportsStorageID: true, }, { Storage: largeFileStorage, diff --git a/pkg/local_object_storage/shard/gc_internal_test.go b/pkg/local_object_storage/shard/gc_internal_test.go index 332cdf5be..0b6904bd6 100644 --- a/pkg/local_object_storage/shard/gc_internal_test.go +++ b/pkg/local_object_storage/shard/gc_internal_test.go @@ -43,6 +43,7 @@ func Test_ObjectNotFoundIfNotDeletedFromMetabase(t *testing.T) { Policy: func(_ *objectSDK.Object, data []byte) bool { return len(data) <= 1<<20 }, + SupportsStorageID: true, }, { Storage: fstree.New( diff --git a/pkg/local_object_storage/shard/lock_test.go b/pkg/local_object_storage/shard/lock_test.go index ca6b0ca38..c53c0c9e9 100644 --- a/pkg/local_object_storage/shard/lock_test.go +++ b/pkg/local_object_storage/shard/lock_test.go @@ -41,6 +41,7 @@ func TestShard_Lock(t *testing.T) { Policy: func(_ *objectSDK.Object, data []byte) bool { return len(data) <= 1<<20 }, + SupportsStorageID: true, }, { Storage: fstree.New( diff --git a/pkg/local_object_storage/shard/range_test.go b/pkg/local_object_storage/shard/range_test.go index a8bc83307..0be713b3f 100644 --- a/pkg/local_object_storage/shard/range_test.go +++ b/pkg/local_object_storage/shard/range_test.go @@ -89,6 +89,7 @@ func testShardGetRange(t *testing.T, hasWriteCache bool) { Policy: func(_ *objectSDK.Object, data []byte) bool { return len(data) <= smallObjectSize }, + SupportsStorageID: true, }, { Storage: fstree.New( diff --git a/pkg/local_object_storage/shard/shard_test.go b/pkg/local_object_storage/shard/shard_test.go index 9da9eb6b8..6fa36af2c 100644 --- a/pkg/local_object_storage/shard/shard_test.go +++ b/pkg/local_object_storage/shard/shard_test.go @@ -79,6 +79,7 @@ func newCustomShard(t testing.TB, enableWriteCache bool, o shardOptions) *Shard Policy: func(_ *objectSDK.Object, data []byte) bool { return len(data) <= 1<<20 }, + SupportsStorageID: true, }, { Storage: fstree.New(