forked from TrueCloudLab/frostfs-node
[#1175] storage engine: Return status error on Inhume of locked object
Make `StorageEngine.Inhume` to forward first encountered `apistatus.ObjectLocked` error during shard processing. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
545861d1bc
commit
97b6ec8150
1 changed files with 29 additions and 9 deletions
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
|
||||||
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
|
||||||
)
|
)
|
||||||
|
@ -50,6 +51,9 @@ var errInhumeFailure = errors.New("inhume operation failed")
|
||||||
// Inhume calls metabase. Inhume method to mark object as removed. It won't be
|
// Inhume calls metabase. Inhume method to mark object as removed. It won't be
|
||||||
// removed physically from shard until `Delete` operation.
|
// removed physically from shard until `Delete` operation.
|
||||||
//
|
//
|
||||||
|
// Allows inhuming non-locked objects only. Returns apistatus.ObjectLocked
|
||||||
|
// if at least one object is locked.
|
||||||
|
//
|
||||||
// Returns an error if executions are blocked (see BlockExecution).
|
// Returns an error if executions are blocked (see BlockExecution).
|
||||||
func (e *StorageEngine) Inhume(prm *InhumePrm) (res *InhumeRes, err error) {
|
func (e *StorageEngine) Inhume(prm *InhumePrm) (res *InhumeRes, err error) {
|
||||||
err = e.execIfNotBlocked(func() error {
|
err = e.execIfNotBlocked(func() error {
|
||||||
|
@ -74,10 +78,14 @@ func (e *StorageEngine) inhume(prm *InhumePrm) (*InhumeRes, error) {
|
||||||
shPrm.MarkAsGarbage(prm.addrs[i])
|
shPrm.MarkAsGarbage(prm.addrs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := e.inhumeAddr(prm.addrs[i], shPrm, true)
|
switch e.inhumeAddr(prm.addrs[i], shPrm, true) {
|
||||||
if !ok {
|
case 1:
|
||||||
ok = e.inhumeAddr(prm.addrs[i], shPrm, false)
|
return nil, apistatus.ObjectLocked{}
|
||||||
if !ok {
|
case 0:
|
||||||
|
switch e.inhumeAddr(prm.addrs[i], shPrm, false) {
|
||||||
|
case 1:
|
||||||
|
return nil, apistatus.ObjectLocked{}
|
||||||
|
case 0:
|
||||||
return nil, errInhumeFailure
|
return nil, errInhumeFailure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,8 +94,13 @@ func (e *StorageEngine) inhume(prm *InhumePrm) (*InhumeRes, error) {
|
||||||
return new(InhumeRes), nil
|
return new(InhumeRes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *StorageEngine) inhumeAddr(addr *addressSDK.Address, prm *shard.InhumePrm, checkExists bool) (ok bool) {
|
// Returns:
|
||||||
|
// 0 - fail
|
||||||
|
// 1 - object locked
|
||||||
|
// 2 - ok
|
||||||
|
func (e *StorageEngine) inhumeAddr(addr *addressSDK.Address, prm *shard.InhumePrm, checkExists bool) (status uint8) {
|
||||||
root := false
|
root := false
|
||||||
|
var errLocked apistatus.ObjectLocked
|
||||||
|
|
||||||
e.iterateOverSortedShards(addr, func(_ int, sh hashedShard) (stop bool) {
|
e.iterateOverSortedShards(addr, func(_ int, sh hashedShard) (stop bool) {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -105,7 +118,7 @@ func (e *StorageEngine) inhumeAddr(addr *addressSDK.Address, prm *shard.InhumePr
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, object.ErrAlreadyRemoved) {
|
if errors.Is(err, object.ErrAlreadyRemoved) {
|
||||||
// inhumed once - no need to be inhumed again
|
// inhumed once - no need to be inhumed again
|
||||||
ok = true
|
status = 2
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +137,18 @@ func (e *StorageEngine) inhumeAddr(addr *addressSDK.Address, prm *shard.InhumePr
|
||||||
_, err := sh.Inhume(prm)
|
_, err := sh.Inhume(prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.reportShardError(sh, "could not inhume object in shard", err)
|
e.reportShardError(sh, "could not inhume object in shard", err)
|
||||||
} else {
|
|
||||||
ok = true
|
if errors.As(err, &errLocked) {
|
||||||
|
status = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return err == nil
|
status = 2
|
||||||
|
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue