diff --git a/pkg/local_object_storage/blobstor/blobovniczatree/put.go b/pkg/local_object_storage/blobstor/blobovniczatree/put.go index 37f6760cb..2f11f6f49 100644 --- a/pkg/local_object_storage/blobstor/blobovniczatree/put.go +++ b/pkg/local_object_storage/blobstor/blobovniczatree/put.go @@ -26,8 +26,9 @@ func (b *Blobovniczas) Put(prm common.PutPrm) (common.PutRes, error) { putPrm.SetMarshaledObject(prm.RawData) var ( - fn func(string) (bool, error) - id *blobovnicza.ID + fn func(string) (bool, error) + id *blobovnicza.ID + allFull = true ) fn = func(p string) (bool, error) { @@ -59,6 +60,7 @@ func (b *Blobovniczas) Put(prm common.PutPrm) (common.PutRes, error) { return fn(p) } + allFull = false b.log.Debug("could not put object to active blobovnicza", zap.String("path", filepath.Join(p, u64ToHexString(active.ind))), zap.String("error", err.Error()), @@ -77,6 +79,9 @@ func (b *Blobovniczas) Put(prm common.PutPrm) (common.PutRes, error) { if err := b.iterateDeepest(prm.Address, fn); err != nil { return common.PutRes{}, err } else if id == nil { + if allFull { + return common.PutRes{}, common.ErrNoSpace + } return common.PutRes{}, errPutFailed } diff --git a/pkg/local_object_storage/blobstor/common/errors.go b/pkg/local_object_storage/blobstor/common/errors.go index 205c98aac..8581e7877 100644 --- a/pkg/local_object_storage/blobstor/common/errors.go +++ b/pkg/local_object_storage/blobstor/common/errors.go @@ -5,3 +5,6 @@ import "errors" // ErrReadOnly MUST be returned for modifying operations when the storage was opened // in readonly mode. var ErrReadOnly = errors.New("opened as read-only") + +// ErrNoSpace MUST be returned when there is no space to put an object on the device. +var ErrNoSpace = errors.New("no free space") diff --git a/pkg/local_object_storage/blobstor/fstree/fstree.go b/pkg/local_object_storage/blobstor/fstree/fstree.go index 25674d640..a2ab55c45 100644 --- a/pkg/local_object_storage/blobstor/fstree/fstree.go +++ b/pkg/local_object_storage/blobstor/fstree/fstree.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "strings" + "syscall" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/compression" @@ -236,7 +237,15 @@ func (t *FSTree) Put(prm common.PutPrm) (common.PutRes, error) { if !prm.DontCompress { prm.RawData = t.Compress(prm.RawData) } - return common.PutRes{StorageID: []byte{}}, os.WriteFile(p, prm.RawData, t.Permissions) + + err := os.WriteFile(p, prm.RawData, t.Permissions) + if err != nil { + var pe *fs.PathError + if errors.As(err, &pe) && pe.Err == syscall.ENOSPC { + err = common.ErrNoSpace + } + } + return common.PutRes{StorageID: []byte{}}, err } // PutStream puts executes handler on a file opened for write.