da2975a2f9
If an object is found in the Write-cache and is placed at the end of the in-memory cache, the memory counter update operation tries to dereference the index that is out of the sliced array. Moreover, even if panic does not appear, the counter is updated with the wrong value. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
74 lines
1.7 KiB
Go
74 lines
1.7 KiB
Go
package writecache
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
|
|
storagelog "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/internal/log"
|
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
// Delete removes object from write-cache.
|
|
//
|
|
// Returns an error of type apistatus.ObjectNotFound if object is missing in write-cache.
|
|
func (c *cache) Delete(addr oid.Address) error {
|
|
c.modeMtx.RLock()
|
|
defer c.modeMtx.RUnlock()
|
|
if c.readOnly() {
|
|
return ErrReadOnly
|
|
}
|
|
|
|
saddr := addr.EncodeToString()
|
|
|
|
// Check memory cache.
|
|
c.mtx.Lock()
|
|
for i := range c.mem {
|
|
if saddr == c.mem[i].addr {
|
|
c.curMemSize -= uint64(len(c.mem[i].data))
|
|
copy(c.mem[i:], c.mem[i+1:])
|
|
c.mem = c.mem[:len(c.mem)-1]
|
|
c.mtx.Unlock()
|
|
storagelog.Write(c.log, storagelog.AddressField(saddr), storagelog.OpField("in-mem DELETE"))
|
|
return nil
|
|
}
|
|
}
|
|
c.mtx.Unlock()
|
|
|
|
// Check disk cache.
|
|
var has int
|
|
_ = c.db.View(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(defaultBucket)
|
|
has = len(b.Get([]byte(saddr)))
|
|
return nil
|
|
})
|
|
|
|
if 0 < has {
|
|
err := c.db.Update(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(defaultBucket)
|
|
err := b.Delete([]byte(saddr))
|
|
return err
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
storagelog.Write(c.log, storagelog.AddressField(saddr), storagelog.OpField("db DELETE"))
|
|
c.objCounters.DecDB()
|
|
return nil
|
|
}
|
|
|
|
err := c.fsTree.Delete(addr)
|
|
if errors.Is(err, fstree.ErrFileNotFound) {
|
|
var errNotFound apistatus.ObjectNotFound
|
|
|
|
err = errNotFound
|
|
}
|
|
|
|
if err == nil {
|
|
storagelog.Write(c.log, storagelog.AddressField(saddr), storagelog.OpField("fstree DELETE"))
|
|
c.objCounters.DecFS()
|
|
}
|
|
|
|
return err
|
|
}
|