fix: incorrect context timeout during listPath() (#15509)

This PR cleans up the listing code for single drive
to ensure that we do not add an incorrect context
timeout, while resuming the listing.

fixes #15508
This commit is contained in:
Harshavardhana 2022-08-10 07:35:29 -07:00 committed by GitHub
parent 172e63dbb6
commit 74418b542a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -112,14 +112,14 @@ func (z *erasureServerPools) listPath(ctx context.Context, o *listPathOptions) (
if o.ID != "" && !o.Transient { if o.ID != "" && !o.Transient {
// Create or ping with handout... // Create or ping with handout...
rpc := globalNotificationSys.restClientFromHash(pathJoin(o.Bucket, o.Prefix)) rpc := globalNotificationSys.restClientFromHash(pathJoin(o.Bucket, o.Prefix))
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
var c *metacache var c *metacache
if rpc == nil { if rpc == nil {
resp := localMetacacheMgr.getBucket(ctx, o.Bucket).findCache(*o) resp := localMetacacheMgr.getBucket(ctx, o.Bucket).findCache(*o)
c = &resp c = &resp
} else { } else {
c, err = rpc.GetMetacacheListing(ctx, *o) rctx, cancel := context.WithTimeout(ctx, 5*time.Second)
c, err = rpc.GetMetacacheListing(rctx, *o)
cancel()
} }
if err != nil { if err != nil {
if errors.Is(err, context.Canceled) { if errors.Is(err, context.Canceled) {
@ -318,30 +318,8 @@ func (es *erasureSingle) listPath(ctx context.Context, o *listPathOptions) (entr
// //
// If we don't have a list id we must ask the server if it has a cache or create a new. // If we don't have a list id we must ask the server if it has a cache or create a new.
if o.ID != "" && !o.Transient { if o.ID != "" && !o.Transient {
// Create or ping with handout...
rpc := globalNotificationSys.restClientFromHash(pathJoin(o.Bucket, o.Prefix))
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
var c *metacache
if rpc == nil {
resp := localMetacacheMgr.getBucket(ctx, o.Bucket).findCache(*o) resp := localMetacacheMgr.getBucket(ctx, o.Bucket).findCache(*o)
c = &resp c := &resp
} else {
c, err = rpc.GetMetacacheListing(ctx, *o)
}
if err != nil {
if errors.Is(err, context.Canceled) {
// Context is canceled, return at once.
// request canceled, no entries to return
return entries, io.EOF
}
if !errors.Is(err, context.DeadlineExceeded) {
o.debugln("listPath: got error", err)
}
o.Transient = true
o.Create = false
o.ID = mustGetUUID()
} else {
if c.fileNotFound { if c.fileNotFound {
// No cache found, no entries found. // No cache found, no entries found.
return entries, io.EOF return entries, io.EOF
@ -363,14 +341,10 @@ func (es *erasureSingle) listPath(ctx context.Context, o *listPathOptions) (entr
return return
case <-t.C: case <-t.C:
meta.lastHandout = time.Now() meta.lastHandout = time.Now()
if rpc == nil {
meta, _ = localMetacacheMgr.updateCacheEntry(meta) meta, _ = localMetacacheMgr.updateCacheEntry(meta)
} }
meta, _ = rpc.UpdateMetacacheListing(ctx, meta)
}
}(*c) }(*c)
} }
}
// We have an existing list ID, continue streaming. // We have an existing list ID, continue streaming.
if o.Create { if o.Create {
@ -399,21 +373,7 @@ func (es *erasureSingle) listPath(ctx context.Context, o *listPathOptions) (entr
return entries, err return entries, err
} }
entries.truncate(0) entries.truncate(0)
go func() {
rpc := globalNotificationSys.restClientFromHash(pathJoin(o.Bucket, o.Prefix))
if rpc != nil {
ctx, cancel := context.WithTimeout(GlobalContext, 5*time.Second)
defer cancel()
c, err := rpc.GetMetacacheListing(ctx, *o)
if err == nil {
c.error = "no longer used"
c.status = scanStateError
rpc.UpdateMetacacheListing(ctx, *c)
}
}
}()
o.ID = "" o.ID = ""
if err != nil { if err != nil {
logger.LogIf(ctx, fmt.Errorf("Resuming listing from drives failed %w, proceeding to do raw listing", err)) logger.LogIf(ctx, fmt.Errorf("Resuming listing from drives failed %w, proceeding to do raw listing", err))
} }