Skip to content

Commit f1d9f56

Browse files
committed
xs/tcb: re-chunk when destination bucket has a different chunk config
* since commit `15e325`, the TCB behaves as follows: * the remote portion of objects is persisted according to the dest bucket's chunk config, as `poi.size` is properly set via `coi.send`. * the local portion of objects, however, is still copied directly via `lom.Copy2FQN`, ignoring the dest bucket's chunk config. * this patch adds the `coi._chunk` branch to handle this case, triggered only when source and destination chunk configs differ. Signed-off-by: Tony Chen <a122774007@gmail.com>
1 parent a3691e3 commit f1d9f56

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

ais/tgtobj.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func (poi *putOI) chunk(chunkSize int64) (ecode int, err error) {
181181
uploadID string
182182
)
183183

184+
debug.Assertf(poi.size > 0, "poi.size is required in chunk, object name: %s", poi.lom.Cname())
184185
if uploadID, err = poi.t.ups.start(poi.oreq, lom, poi.coldGET); err != nil {
185186
poi.t.ups.abort(poi.oreq, lom, uploadID)
186187
return http.StatusInternalServerError, err
@@ -1681,6 +1682,7 @@ func (coi *coi) do(t *target, dm *bundle.DM, lom *core.LOM) (res xs.CoiRes) {
16811682
if err := dst.InitBck(coi.BckTo.Bucket()); err != nil {
16821683
return xs.CoiRes{Err: err}
16831684
}
1685+
dstMaxMonoSize := dst.Bprops().Chunks.MaxMonolithicSize
16841686

16851687
switch {
16861688
// no-op
@@ -1703,6 +1705,9 @@ func (coi *coi) do(t *target, dm *bundle.DM, lom *core.LOM) (res xs.CoiRes) {
17031705
if cmn.Rom.V(5, cos.ModAIS) {
17041706
nlog.Infoln("copying", lom.String(), "=>", dst.String(), "is a no-op (resilvering with a single mountpath?)")
17051707
}
1708+
case lom.Bprops().Chunks.MaxMonolithicSize != dstMaxMonoSize && lom.Lsize() > int64(dstMaxMonoSize):
1709+
// source and destination buckets have different chunks config => rechunk if the source exceeds the destination's limit
1710+
res = coi._chunk(t, lom, dst, int64(dst.Bprops().Chunks.ChunkSize))
17061711
default:
17071712
// fast path: destination is _this_ target
17081713
// (note coi.send(=> another target) above)
@@ -1793,6 +1798,7 @@ func (coi *coi) _writer(t *target, lom, dst *core.LOM, args *core.ETLArgs) (res
17931798
// An option for _not_ storing the object _in_ the cluster would be a _feature_ that can be
17941799
// further debated.
17951800
func (coi *coi) _reader(t *target, dm *bundle.DM, lom, dst *core.LOM, args *core.ETLArgs) (res xs.CoiRes) {
1801+
debug.Assertf(coi.GetROC != nil, "coi.GetROC is nil in _reader, object name: %s", coi.ObjnameTo)
17961802
resp := coi.GetROC(lom, coi.LatestVer, coi.Sync, args)
17971803
if resp.Err != nil {
17981804
return xs.CoiRes{Ecode: resp.Ecode, Err: resp.Err}
@@ -1864,6 +1870,31 @@ func (coi *coi) _regular(t *target, lom, dst *core.LOM, lcopy bool) (res xs.CoiR
18641870
return res
18651871
}
18661872

1873+
func (coi *coi) _chunk(t *target, lom, dst *core.LOM, dstChunkSize int64) (res xs.CoiRes) {
1874+
resp := lom.GetROC(coi.LatestVer, coi.Sync)
1875+
if resp.Err != nil {
1876+
return xs.CoiRes{Ecode: resp.Ecode, Err: resp.Err}
1877+
}
1878+
poi := allocPOI()
1879+
defer freePOI(poi)
1880+
{
1881+
poi.t = t
1882+
poi.lom = dst
1883+
poi.r = resp.R
1884+
poi.size = lom.Lsize()
1885+
poi.xctn = coi.Xact // on behalf of
1886+
poi.owt = coi.OWT
1887+
poi.config = coi.Config
1888+
}
1889+
ecode, err := poi.chunk(dstChunkSize)
1890+
if err != nil {
1891+
return xs.CoiRes{Ecode: ecode, Err: err}
1892+
}
1893+
res.Lsize = poi.lom.Lsize()
1894+
1895+
return res
1896+
}
1897+
18671898
// send object => designated target
18681899
// * source is a LOM or a reader (that may be reading from remote)
18691900
// * one of the two equivalent transmission mechanisms: PUT or transport Send

0 commit comments

Comments
 (0)