mirror of
https://github.com/pgsty/minio.git
synced 2026-07-20 20:50:22 +03:00
fix: inlined objects don't need to honor long locks (#17039)
This commit is contained in:
+28
-19
@@ -183,7 +183,7 @@ func (er erasureObjects) CopyObject(ctx context.Context, srcBucket, srcObject, d
|
||||
|
||||
// GetObjectNInfo - returns object info and an object
|
||||
// Read(Closer). When err != nil, the returned reader is always nil.
|
||||
func (er erasureObjects) GetObjectNInfo(ctx context.Context, bucket, object string, rs *HTTPRangeSpec, h http.Header, lockType LockType, opts ObjectOptions) (gr *GetObjectReader, err error) {
|
||||
func (er erasureObjects) GetObjectNInfo(ctx context.Context, bucket, object string, rs *HTTPRangeSpec, h http.Header, opts ObjectOptions) (gr *GetObjectReader, err error) {
|
||||
auditObjectErasureSet(ctx, object, &er)
|
||||
|
||||
// This is a special call attempted first to check for SOS-API calls.
|
||||
@@ -203,25 +203,26 @@ func (er erasureObjects) GetObjectNInfo(ctx context.Context, bucket, object stri
|
||||
}()
|
||||
|
||||
// Acquire lock
|
||||
if lockType != noLock {
|
||||
if !opts.NoLock {
|
||||
lock := er.NewNSLock(bucket, object)
|
||||
switch lockType {
|
||||
case writeLock:
|
||||
lkctx, err := lock.GetLock(ctx, globalOperationTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx = lkctx.Context()
|
||||
nsUnlocker = func() { lock.Unlock(lkctx) }
|
||||
case readLock:
|
||||
lkctx, err := lock.GetRLock(ctx, globalOperationTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx = lkctx.Context()
|
||||
nsUnlocker = func() { lock.RUnlock(lkctx) }
|
||||
lkctx, err := lock.GetRLock(ctx, globalOperationTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx = lkctx.Context()
|
||||
|
||||
// Release lock when the metadata is verified, and reader
|
||||
// is ready to be read.
|
||||
//
|
||||
// This is possible to be lock free because
|
||||
// - xl.meta for inlined objects has already read the data
|
||||
// into memory, any mutation on xl.meta subsequently is
|
||||
// inconsequential to the overall read operation.
|
||||
// - xl.meta metadata is still verified for quorum under lock()
|
||||
// however writing the response doesn't need to serialize
|
||||
// concurrent writers
|
||||
unlockOnDefer = true
|
||||
nsUnlocker = func() { lock.RUnlock(lkctx) }
|
||||
}
|
||||
|
||||
fi, metaArr, onlineDisks, err := er.getObjectFileInfo(ctx, bucket, object, opts, true)
|
||||
@@ -265,6 +266,7 @@ func (er erasureObjects) GetObjectNInfo(ctx context.Context, bucket, object stri
|
||||
ObjInfo: objInfo,
|
||||
}, toObjectErr(errMethodNotAllowed, bucket, object)
|
||||
}
|
||||
|
||||
if objInfo.IsRemote() {
|
||||
gr, err := getTransitionedObjectReader(ctx, bucket, object, rs, h, objInfo, opts)
|
||||
if err != nil {
|
||||
@@ -278,7 +280,10 @@ func (er erasureObjects) GetObjectNInfo(ctx context.Context, bucket, object stri
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unlockOnDefer = false
|
||||
|
||||
if unlockOnDefer {
|
||||
unlockOnDefer = fi.InlineData()
|
||||
}
|
||||
|
||||
pr, pw := xioutil.WaitPipe()
|
||||
go func() {
|
||||
@@ -291,7 +296,11 @@ func (er erasureObjects) GetObjectNInfo(ctx context.Context, bucket, object stri
|
||||
pr.CloseWithError(nil)
|
||||
}
|
||||
|
||||
return fn(pr, h, pipeCloser, nsUnlocker)
|
||||
if !unlockOnDefer {
|
||||
return fn(pr, h, pipeCloser, nsUnlocker)
|
||||
}
|
||||
|
||||
return fn(pr, h, pipeCloser)
|
||||
}
|
||||
|
||||
func (er erasureObjects) getObjectWithFileInfo(ctx context.Context, bucket, object string, startOffset int64, length int64, writer io.Writer, fi FileInfo, metaArr []FileInfo, onlineDisks []StorageAPI) error {
|
||||
|
||||
Reference in New Issue
Block a user