fix: getPoolIdx decouple from top level options (#11512)

top-level options shouldn't be passed down for
GetObjectInfo() while verifying the objects in
different pools, this is to make sure that
we always get the value from the pool where
the object exists.
master
Harshavardhana 4 years ago committed by GitHub
parent 682482459d
commit cbf4bb62e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      cmd/bucket-replication.go
  2. 1
      cmd/erasure-object.go
  3. 35
      cmd/erasure-server-pool.go

@ -714,9 +714,7 @@ func replicateObject(ctx context.Context, objInfo ObjectInfo, objectAPI ObjectLa
} }
// This lower level implementation is necessary to avoid write locks from CopyObject. // This lower level implementation is necessary to avoid write locks from CopyObject.
poolIdx, err := z.getPoolIdx(ctx, bucket, object, ObjectOptions{ poolIdx, err := z.getPoolIdx(ctx, bucket, object, objInfo.Size)
VersionID: objInfo.VersionID,
}, objInfo.Size)
if err != nil { if err != nil {
logger.LogIf(ctx, fmt.Errorf("Unable to update replication metadata for %s/%s(%s): %w", bucket, objInfo.Name, objInfo.VersionID, err)) logger.LogIf(ctx, fmt.Errorf("Unable to update replication metadata for %s/%s(%s): %w", bucket, objInfo.Name, objInfo.VersionID, err))
} else { } else {

@ -460,6 +460,7 @@ func (er erasureObjects) getObjectInfo(ctx context.Context, bucket, object strin
// Make sure to return object info to provide extra information. // Make sure to return object info to provide extra information.
return objInfo, toObjectErr(errMethodNotAllowed, bucket, object) return objInfo, toObjectErr(errMethodNotAllowed, bucket, object)
} }
if fi.Deleted { if fi.Deleted {
if opts.VersionID == "" || opts.DeleteMarker { if opts.VersionID == "" || opts.DeleteMarker {
return objInfo, toObjectErr(errFileNotFound, bucket, object) return objInfo, toObjectErr(errFileNotFound, bucket, object)

@ -246,31 +246,26 @@ func (z *erasureServerPools) getServerPoolsAvailableSpace(ctx context.Context, s
// getPoolIdx returns the found previous object and its corresponding pool idx, // getPoolIdx returns the found previous object and its corresponding pool idx,
// if none are found falls back to most available space pool. // if none are found falls back to most available space pool.
func (z *erasureServerPools) getPoolIdx(ctx context.Context, bucket, object string, opts ObjectOptions, size int64) (idx int, err error) { func (z *erasureServerPools) getPoolIdx(ctx context.Context, bucket, object string, size int64) (idx int, err error) {
if z.SinglePool() { if z.SinglePool() {
return 0, nil return 0, nil
} }
for i, pool := range z.serverPools { for i, pool := range z.serverPools {
objInfo, err := pool.GetObjectInfo(ctx, bucket, object, opts) objInfo, err := pool.GetObjectInfo(ctx, bucket, object, ObjectOptions{})
switch err.(type) { if err != nil && !isErrObjectNotFound(err) {
case VersionNotFound:
// VersionId not found, versionId was specified
case ObjectNotFound:
// VersionId was not specified but found delete marker or no versions exist.
case MethodNotAllowed:
// VersionId was specified but found delete marker
default:
// All other unhandled errors return right here.
if err != nil {
return -1, err return -1, err
} }
if isErrObjectNotFound(err) {
// No object exists or its a delete marker,
// check objInfo to confirm.
if objInfo.DeleteMarker && objInfo.Name != "" {
return i, nil
} }
// delete marker not specified means no versions // objInfo is not valid, truly the object doesn't
// exist continue to next pool. // exist proceed to next pool.
if !objInfo.DeleteMarker && err != nil {
continue continue
} }
// Success case and when DeleteMarker is true return. // object exists at this pool.
return i, nil return i, nil
} }
@ -604,7 +599,7 @@ func (z *erasureServerPools) PutObject(ctx context.Context, bucket string, objec
return z.serverPools[0].PutObject(ctx, bucket, object, data, opts) return z.serverPools[0].PutObject(ctx, bucket, object, data, opts)
} }
idx, err := z.getPoolIdx(ctx, bucket, object, opts, data.Size()) idx, err := z.getPoolIdx(ctx, bucket, object, data.Size())
if err != nil { if err != nil {
return ObjectInfo{}, err return ObjectInfo{}, err
} }
@ -625,7 +620,7 @@ func (z *erasureServerPools) DeleteObject(ctx context.Context, bucket string, ob
} }
// We don't know the size here set 1GiB atleast. // We don't know the size here set 1GiB atleast.
idx, err := z.getPoolIdx(ctx, bucket, object, opts, 1<<30) idx, err := z.getPoolIdx(ctx, bucket, object, 1<<30)
if err != nil { if err != nil {
return objInfo, err return objInfo, err
} }
@ -676,7 +671,7 @@ func (z *erasureServerPools) CopyObject(ctx context.Context, srcBucket, srcObjec
cpSrcDstSame := isStringEqual(pathJoin(srcBucket, srcObject), pathJoin(dstBucket, dstObject)) cpSrcDstSame := isStringEqual(pathJoin(srcBucket, srcObject), pathJoin(dstBucket, dstObject))
poolIdx, err := z.getPoolIdx(ctx, dstBucket, dstObject, dstOpts, srcInfo.Size) poolIdx, err := z.getPoolIdx(ctx, dstBucket, dstObject, srcInfo.Size)
if err != nil { if err != nil {
return objInfo, err return objInfo, err
} }
@ -860,7 +855,7 @@ func (z *erasureServerPools) NewMultipartUpload(ctx context.Context, bucket, obj
} }
// We don't know the exact size, so we ask for at least 1GiB file. // We don't know the exact size, so we ask for at least 1GiB file.
idx, err := z.getPoolIdx(ctx, bucket, object, opts, 1<<30) idx, err := z.getPoolIdx(ctx, bucket, object, 1<<30)
if err != nil { if err != nil {
return "", err return "", err
} }

Loading…
Cancel
Save