diff --git a/pkg/local_object_storage/engine/inhume.go b/pkg/local_object_storage/engine/inhume.go index 94bf1537b5..24fca3b396 100644 --- a/pkg/local_object_storage/engine/inhume.go +++ b/pkg/local_object_storage/engine/inhume.go @@ -1,6 +1,8 @@ package engine import ( + "errors" + objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard" "go.uber.org/zap" @@ -25,23 +27,56 @@ func (p *InhumePrm) WithTarget(addr, tombstone *objectSDK.Address) *InhumePrm { return p } +var errInhumeFailure = errors.New("inhume operation failed") + // Inhume calls metabase. Inhume method to mark object as removed. It won't be // removed physically from shard until `Delete` operation. func (e *StorageEngine) Inhume(prm *InhumePrm) (*InhumeRes, error) { shPrm := new(shard.InhumePrm).WithTarget(prm.addr, prm.tombstone) - e.iterateOverSortedShards(prm.addr, func(_ int, sh *shard.Shard) (stop bool) { - _, err := sh.Inhume(shPrm) + res := e.inhume(prm.addr, shPrm, true) + if res == nil { + res = e.inhume(prm.addr, shPrm, false) + if res == nil { + return nil, errInhumeFailure + } + } + + return res, nil +} + +func (e *StorageEngine) inhume(addr *objectSDK.Address, prm *shard.InhumePrm, checkExists bool) (res *InhumeRes) { + e.iterateOverSortedShards(addr, func(_ int, sh *shard.Shard) (stop bool) { + if checkExists { + exRes, err := sh.Exists(new(shard.ExistsPrm). + WithAddress(addr), + ) + if err != nil { + // TODO: smth wrong with shard, need to be processed + e.log.Warn("could not check for presents in shard", + zap.Stringer("shard", sh.ID()), + zap.String("error", err.Error()), + ) + + return + } else if !exRes.Exists() { + return + } + } + + _, err := sh.Inhume(prm) if err != nil { // TODO: smth wrong with shard, need to be processed e.log.Warn("could not inhume object in shard", zap.Stringer("shard", sh.ID()), zap.String("error", err.Error()), ) + } else { + res = new(InhumeRes) } - return false + return err == nil }) - return nil, nil + return }