diff --git a/cmd/erasure-multipart.go b/cmd/erasure-multipart.go index c92a051d3..c0b949b45 100644 --- a/cmd/erasure-multipart.go +++ b/cmd/erasure-multipart.go @@ -713,7 +713,7 @@ func (er erasureObjects) CompleteMultipartUpload(ctx context.Context, bucket str // Check if an object is present as one of the parent dir. // -- FIXME. (needs a new kind of lock). - if er.parentDirIsObject(ctx, bucket, path.Dir(object)) { + if opts.ParentIsObject != nil && opts.ParentIsObject(ctx, bucket, path.Dir(object)) { return oi, toObjectErr(errFileParentIsFile, bucket, object) } diff --git a/cmd/erasure-object.go b/cmd/erasure-object.go index b52490f43..e3f8fad22 100644 --- a/cmd/erasure-object.go +++ b/cmd/erasure-object.go @@ -579,7 +579,7 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st // Check if an object is present as one of the parent dir. // -- FIXME. (needs a new kind of lock). // -- FIXME (this also causes performance issue when disks are down). - if er.parentDirIsObject(ctx, bucket, path.Dir(object)) { + if opts.ParentIsObject != nil && opts.ParentIsObject(ctx, bucket, path.Dir(object)) { return ObjectInfo{}, toObjectErr(errFileParentIsFile, bucket, object) } diff --git a/cmd/erasure-sets.go b/cmd/erasure-sets.go index 2d3686776..97c523fb2 100644 --- a/cmd/erasure-sets.go +++ b/cmd/erasure-sets.go @@ -754,8 +754,13 @@ func (s *erasureSets) GetObject(ctx context.Context, bucket, object string, star return s.getHashedSet(object).GetObject(ctx, bucket, object, startOffset, length, writer, etag, opts) } +func (s *erasureSets) parentDirIsObject(ctx context.Context, bucket, parent string) bool { + return s.getHashedSet(parent).parentDirIsObject(ctx, bucket, parent) +} + // PutObject - writes an object to hashedSet based on the object name. func (s *erasureSets) PutObject(ctx context.Context, bucket string, object string, data *PutObjReader, opts ObjectOptions) (objInfo ObjectInfo, err error) { + opts.ParentIsObject = s.parentDirIsObject return s.getHashedSet(object).PutObject(ctx, bucket, object, data, opts) } @@ -1095,6 +1100,7 @@ func (s *erasureSets) AbortMultipartUpload(ctx context.Context, bucket, object, // CompleteMultipartUpload - completes a pending multipart transaction, on hashedSet based on object name. func (s *erasureSets) CompleteMultipartUpload(ctx context.Context, bucket, object, uploadID string, uploadedParts []CompletePart, opts ObjectOptions) (objInfo ObjectInfo, err error) { + opts.ParentIsObject = s.parentDirIsObject return s.getHashedSet(object).CompleteMultipartUpload(ctx, bucket, object, uploadID, uploadedParts, opts) } diff --git a/cmd/object-api-interface.go b/cmd/object-api-interface.go index ddb11a737..8700ed703 100644 --- a/cmd/object-api-interface.go +++ b/cmd/object-api-interface.go @@ -45,6 +45,8 @@ type ObjectOptions struct { UserDefined map[string]string // only set in case of POST/PUT operations PartNumber int // only useful in case of GetObject/HeadObject CheckPrecondFn CheckPreconditionFn // only set during GetObject/HeadObject/CopyObjectPart preconditional valuation + // Used to verify if parent is an object. + ParentIsObject func(ctx context.Context, bucket, parent string) bool } // BucketOptions represents bucket options for ObjectLayer bucket operations