diff --git a/curiosrc/seal/task_trees.go b/curiosrc/seal/task_trees.go index 8a178bd903f..7994c354aad 100644 --- a/curiosrc/seal/task_trees.go +++ b/curiosrc/seal/task_trees.go @@ -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) { - // todo reserve storage - id := ids[0] return &id, nil } diff --git a/storage/paths/local.go b/storage/paths/local.go index ccb41c2a2bb..b5689eb5d46 100644 --- a/storage/paths/local.go +++ b/storage/paths/local.go @@ -61,24 +61,25 @@ type statExistingSectorForReservation struct { 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() - stat, err := ls.Stat(p.local) + stat, err = ls.Stat(p.local) 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 + 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) used, err := ls.DiskUsage(sp) if err == os.ErrNotExist { p, ferr := tempFetchDest(sp, false) if ferr != nil { - return ferr + return 0, ferr } used, err = ls.DiskUsage(p) @@ -90,18 +91,19 @@ func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservat if !os.IsNotExist(err) { log.Warnf("getting disk usage of '%s': %+v", p.sectorPath(id, fileType), err) } - return nil + return 0, nil } - stat.Reserved -= used - return nil + return used, nil } for id, ft := range p.reservations { for _, fileType := range ft.AllSet() { - if err := accountExistingFiles(id, fileType); err != nil { - return fsutil.FsStat{}, err + onDisk, err := accountExistingFiles(id, fileType) + if err != nil { + return fsutil.FsStat{}, 0, err } + stat.Reserved -= onDisk } } for _, reservation := range newReserve { @@ -111,9 +113,11 @@ func (p *path) stat(ls LocalStorage, newReserve ...statExistingSectorForReservat continue } - if err := accountExistingFiles(reservation.id, fileType); err != nil { - return fsutil.FsStat{}, err + onDisk, err := accountExistingFiles(reservation.id, fileType) + 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 { used, err := ls.DiskUsage(p.local) if err != nil { - return fsutil.FsStat{}, err + return fsutil.FsStat{}, 0, err } 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)) } - return stat, err + return stat, newReserveOnDisk, err } 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{}, } - fst, err := out.stat(st.localStorage) + fst, _, err := out.stat(st.localStorage) if err != nil { return err } @@ -280,7 +284,7 @@ func (st *Local) Redeclare(ctx context.Context, filterId *storiface.ID, dropMiss 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 { return err } @@ -404,7 +408,7 @@ func (st *Local) reportStorage(ctx context.Context) { toReport := map[storiface.ID]storiface.HealthReport{} for id, p := range st.paths { - stat, err := p.stat(st.localStorage) + stat, _, err := p.stat(st.localStorage) r := storiface.HealthReport{Stat: stat} if err != nil { r.Err = err.Error() @@ -445,14 +449,19 @@ func (st *Local) Reserve(ctx context.Context, sid storiface.SectorRef, ft storif 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 { return nil, xerrors.Errorf("getting local storage stat: %w", err) } 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)) } @@ -798,7 +807,8 @@ func (st *Local) FsStat(ctx context.Context, id storiface.ID) (fsutil.FsStat, er 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) {