PutObjectPart caches part to cache multipart path.
(ctx context.Context, bucket, object, uploadID string, partID int, data io.Reader, size int64, opts ObjectOptions)
| 1309 | |
| 1310 | // PutObjectPart caches part to cache multipart path. |
| 1311 | func (c *diskCache) PutObjectPart(ctx context.Context, bucket, object, uploadID string, partID int, data io.Reader, size int64, opts ObjectOptions) (partInfo PartInfo, err error) { |
| 1312 | oi := PartInfo{} |
| 1313 | if !c.diskSpaceAvailable(size) { |
| 1314 | io.Copy(io.Discard, data) |
| 1315 | return oi, errDiskFull |
| 1316 | } |
| 1317 | cachePath := getMultipartCacheSHADir(c.dir, bucket, object) |
| 1318 | uploadIDDir := path.Join(cachePath, uploadID) |
| 1319 | |
| 1320 | partIDLock := c.NewNSLockFn(pathJoin(uploadIDDir, strconv.Itoa(partID))) |
| 1321 | lkctx, err := partIDLock.GetLock(ctx, globalOperationTimeout) |
| 1322 | if err != nil { |
| 1323 | return oi, err |
| 1324 | } |
| 1325 | |
| 1326 | ctx = lkctx.Context() |
| 1327 | defer partIDLock.Unlock(lkctx) |
| 1328 | meta, _, _, err := c.statCache(ctx, uploadIDDir) |
| 1329 | // Case where object not yet cached |
| 1330 | if err != nil { |
| 1331 | return oi, err |
| 1332 | } |
| 1333 | |
| 1334 | if !c.diskSpaceAvailable(size) { |
| 1335 | return oi, errDiskFull |
| 1336 | } |
| 1337 | reader := data |
| 1338 | actualSize := uint64(size) |
| 1339 | if globalCacheKMS != nil { |
| 1340 | reader, err = newCachePartEncryptReader(ctx, bucket, object, partID, data, size, meta.Meta) |
| 1341 | if err != nil { |
| 1342 | return oi, err |
| 1343 | } |
| 1344 | actualSize, _ = sio.EncryptedSize(uint64(size)) |
| 1345 | } |
| 1346 | n, md5sum, err := c.bitrotWriteToCache(uploadIDDir, fmt.Sprintf("part.%d", partID), reader, actualSize) |
| 1347 | if IsErr(err, baseErrs...) { |
| 1348 | // take the cache drive offline |
| 1349 | c.setOffline() |
| 1350 | } |
| 1351 | if err != nil { |
| 1352 | return oi, err |
| 1353 | } |
| 1354 | |
| 1355 | if actualSize != uint64(n) { |
| 1356 | return oi, IncompleteBody{Bucket: bucket, Object: object} |
| 1357 | } |
| 1358 | var md5hex string |
| 1359 | if md5bytes, err := base64.StdEncoding.DecodeString(md5sum); err == nil { |
| 1360 | md5hex = hex.EncodeToString(md5bytes) |
| 1361 | } |
| 1362 | |
| 1363 | pInfo := PartInfo{ |
| 1364 | PartNumber: partID, |
| 1365 | ETag: md5hex, |
| 1366 | Size: n, |
| 1367 | ActualSize: int64(actualSize), |
| 1368 | LastModified: UTCNow(), |
nothing calls this directly
no test coverage detected