fix: paths/local: Fix on-disk storage accounting in new reservations (#11825)
This commit is contained in:
parent
a24028c3c0
commit
fd64e38b39
@ -211,8 +211,6 @@ func (t *TreesTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TreesTask) CanAccept(ids []harmonytask.TaskID, engine *harmonytask.TaskEngine) (*harmonytask.TaskID, error) {
|
func (t *TreesTask) CanAccept(ids []harmonytask.TaskID, engine *harmonytask.TaskEngine) (*harmonytask.TaskID, error) {
|
||||||
// todo reserve storage
|
|
||||||
|
|
||||||
id := ids[0]
|
id := ids[0]
|
||||||
return &id, nil
|
return &id, nil
|
||||||
}
|
}
|
||||||
|
@ -61,24 +61,25 @@ type statExistingSectorForReservation struct {
|
|||||||
ft storiface.SectorFileType
|
ft storiface.SectorFileType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservation) (fsutil.FsStat, error) {
|
func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservation) (stat fsutil.FsStat, newResvOnDisk int64, err error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
stat, err := ls.Stat(p.local)
|
stat, err = ls.Stat(p.local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fsutil.FsStat{}, xerrors.Errorf("stat %s: %w", p.local, err)
|
return fsutil.FsStat{}, 0, xerrors.Errorf("stat %s: %w", p.local, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stat.Reserved = p.reserved
|
stat.Reserved = p.reserved
|
||||||
|
var newReserveOnDisk int64
|
||||||
|
|
||||||
accountExistingFiles := func(id abi.SectorID, fileType storiface.SectorFileType) error {
|
accountExistingFiles := func(id abi.SectorID, fileType storiface.SectorFileType) (int64, error) {
|
||||||
sp := p.sectorPath(id, fileType)
|
sp := p.sectorPath(id, fileType)
|
||||||
|
|
||||||
used, err := ls.DiskUsage(sp)
|
used, err := ls.DiskUsage(sp)
|
||||||
if err == os.ErrNotExist {
|
if err == os.ErrNotExist {
|
||||||
p, ferr := tempFetchDest(sp, false)
|
p, ferr := tempFetchDest(sp, false)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return 0, ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
used, err = ls.DiskUsage(p)
|
used, err = ls.DiskUsage(p)
|
||||||
@ -90,18 +91,19 @@ func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservat
|
|||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
log.Warnf("getting disk usage of '%s': %+v", p.sectorPath(id, fileType), err)
|
log.Warnf("getting disk usage of '%s': %+v", p.sectorPath(id, fileType), err)
|
||||||
}
|
}
|
||||||
return nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
stat.Reserved -= used
|
return used, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for id, ft := range p.reservations {
|
for id, ft := range p.reservations {
|
||||||
for _, fileType := range ft.AllSet() {
|
for _, fileType := range ft.AllSet() {
|
||||||
if err := accountExistingFiles(id, fileType); err != nil {
|
onDisk, err := accountExistingFiles(id, fileType)
|
||||||
return fsutil.FsStat{}, err
|
if err != nil {
|
||||||
|
return fsutil.FsStat{}, 0, err
|
||||||
}
|
}
|
||||||
|
stat.Reserved -= onDisk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, reservation := range newReserve {
|
for _, reservation := range newReserve {
|
||||||
@ -111,9 +113,11 @@ func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservat
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := accountExistingFiles(reservation.id, fileType); err != nil {
|
onDisk, err := accountExistingFiles(reservation.id, fileType)
|
||||||
return fsutil.FsStat{}, err
|
if err != nil {
|
||||||
|
return fsutil.FsStat{}, 0, err
|
||||||
}
|
}
|
||||||
|
newReserveOnDisk += onDisk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +134,7 @@ func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservat
|
|||||||
if p.maxStorage > 0 {
|
if p.maxStorage > 0 {
|
||||||
used, err := ls.DiskUsage(p.local)
|
used, err := ls.DiskUsage(p.local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fsutil.FsStat{}, err
|
return fsutil.FsStat{}, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
stat.Max = int64(p.maxStorage)
|
stat.Max = int64(p.maxStorage)
|
||||||
@ -150,7 +154,7 @@ func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservat
|
|||||||
log.Warnw("slow storage stat", "took", time.Now().Sub(start), "reservations", len(p.reservations))
|
log.Warnw("slow storage stat", "took", time.Now().Sub(start), "reservations", len(p.reservations))
|
||||||
}
|
}
|
||||||
|
|
||||||
return stat, err
|
return stat, newReserveOnDisk, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *path) sectorPath(sid abi.SectorID, fileType storiface.SectorFileType) string {
|
func (p *path) sectorPath(sid abi.SectorID, fileType storiface.SectorFileType) string {
|
||||||
@ -198,7 +202,7 @@ func (st *Local) OpenPath(ctx context.Context, p string) error {
|
|||||||
reservations: map[abi.SectorID]storiface.SectorFileType{},
|
reservations: map[abi.SectorID]storiface.SectorFileType{},
|
||||||
}
|
}
|
||||||
|
|
||||||
fst, err := out.stat(st.localStorage)
|
fst, _, err := out.stat(st.localStorage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -282,7 +286,7 @@ func (st *Local) Redeclare(ctx context.Context, filterId *storiface.ID, dropMiss
|
|||||||
return xerrors.Errorf("unmarshalling storage metadata for %s: %w", p.local, err)
|
return xerrors.Errorf("unmarshalling storage metadata for %s: %w", p.local, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fst, err := p.stat(st.localStorage)
|
fst, _, err := p.stat(st.localStorage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -408,7 +412,7 @@ func (st *Local) reportStorage(ctx context.Context) {
|
|||||||
|
|
||||||
toReport := map[storiface.ID]storiface.HealthReport{}
|
toReport := map[storiface.ID]storiface.HealthReport{}
|
||||||
for id, p := range st.paths {
|
for id, p := range st.paths {
|
||||||
stat, err := p.stat(st.localStorage)
|
stat, _, err := p.stat(st.localStorage)
|
||||||
r := storiface.HealthReport{Stat: stat}
|
r := storiface.HealthReport{Stat: stat}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err.Error()
|
r.Err = err.Error()
|
||||||
@ -449,14 +453,19 @@ func (st *Local) Reserve(ctx context.Context, sid storiface.SectorRef, ft storif
|
|||||||
return nil, errPathNotFound
|
return nil, errPathNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
stat, err := p.stat(st.localStorage, statExistingSectorForReservation{sid.ID, fileType})
|
stat, resvOnDisk, err := p.stat(st.localStorage, statExistingSectorForReservation{sid.ID, fileType})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting local storage stat: %w", err)
|
return nil, xerrors.Errorf("getting local storage stat: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
overhead := int64(overheadTab[fileType]) * int64(ssize) / storiface.FSOverheadDen
|
overhead := int64(overheadTab[fileType]) * int64(ssize) / storiface.FSOverheadDen
|
||||||
|
|
||||||
if stat.Available < overhead {
|
if overhead-resvOnDisk < 0 {
|
||||||
|
log.Errorw("negative overhead vs on-disk data", "overhead", overhead, "on-disk", resvOnDisk, "id", id, "sector", sid, "fileType", fileType)
|
||||||
|
resvOnDisk = overhead
|
||||||
|
}
|
||||||
|
|
||||||
|
if stat.Available < overhead-resvOnDisk {
|
||||||
return nil, storiface.Err(storiface.ErrTempAllocateSpace, xerrors.Errorf("can't reserve %d bytes in '%s' (id:%s), only %d available", overhead, p.local, id, stat.Available))
|
return nil, storiface.Err(storiface.ErrTempAllocateSpace, xerrors.Errorf("can't reserve %d bytes in '%s' (id:%s), only %d available", overhead, p.local, id, stat.Available))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +832,8 @@ func (st *Local) FsStat(ctx context.Context, id storiface.ID) (fsutil.FsStat, er
|
|||||||
return fsutil.FsStat{}, errPathNotFound
|
return fsutil.FsStat{}, errPathNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.stat(st.localStorage)
|
stat, _, err := p.stat(st.localStorage)
|
||||||
|
return stat, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *Local) GenerateSingleVanillaProof(ctx context.Context, minerID abi.ActorID, si storiface.PostSectorChallenge, ppt abi.RegisteredPoStProof) ([]byte, error) {
|
func (st *Local) GenerateSingleVanillaProof(ctx context.Context, minerID abi.ActorID, si storiface.PostSectorChallenge, ppt abi.RegisteredPoStProof) ([]byte, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user