Skip to content

Commit 54a0339

Browse files
committed
when checksum is 'none' (refactoring)
* for fear of compiler-optimized nil deref * none-hash: remove encoding.BinaryMarshaler interface * separately, limit chunk-manifest's metadata entry size <= 4K Signed-off-by: Alex Aizman <alex.aizman@gmail.com>
1 parent 2c2afc1 commit 54a0339

File tree

12 files changed

+76
-61
lines changed

12 files changed

+76
-61
lines changed

ais/bucketmeta.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ func loadBMD(mpaths fs.MPI, path string) (mainBMD *bucketMD) {
430430
mainBMD = bmd
431431
continue
432432
}
433-
if mainBMD.cksum.IsEmpty() {
433+
if cos.NoneC(mainBMD.cksum) {
434434
cos.ExitLogf("BMD is not checksummed (%q): %v", mpath, mainBMD)
435435
}
436436
if mainBMD.cksum.Equal(bmd.cksum) {

ais/etlmeta.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func loadEtlMD(mpaths fs.MPI, path string) (mainEtlMD *etlMD) {
284284
mainEtlMD = etlMD
285285
continue
286286
}
287-
if mainEtlMD.cksum.IsEmpty() {
287+
if cos.NoneC(mainEtlMD.cksum) {
288288
cos.ExitLogf("EtlMD is not checksummed (%q): %v", mpath, mainEtlMD)
289289
}
290290
if mainEtlMD.cksum.Equal(etlMD.cksum) {

ais/test/object_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func TestAppendObject(t *testing.T) {
292292
writer := bytes.NewBuffer(nil)
293293
getArgs := api.GetArgs{Writer: writer}
294294
oah, err := api.GetObjectWithValidation(baseParams, bck, objName, &getArgs)
295-
if !cksum.IsEmpty() {
295+
if !cos.NoneH(cksum) {
296296
tassert.CheckFatal(t, err)
297297
}
298298
tassert.Errorf(

ais/tgtobj.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ func (poi *putOI) write() (buf []byte, slab *memsys.Slab, lmfh cos.LomWriter, er
489489
// not using `ReadFrom` of the `*os.File` -
490490
// ultimately, https://github.com/golang/go/blob/master/src/internal/poll/copy_file_range_linux.go#L100
491491
written, err = cos.CopyBuffer(lmfh, poi.r, buf)
492-
case !poi.cksumToUse.IsEmpty() && !poi.validateCksum(ckconf):
492+
case !cos.NoneC(poi.cksumToUse) && !poi.validateCksum(ckconf):
493493
// if the corresponding validation is not configured/enabled we just go ahead
494494
// and use the checksum that has arrived with the object
495495
poi.lom.SetCksum(poi.cksumToUse)
@@ -499,7 +499,7 @@ func (poi *putOI) write() (buf []byte, slab *memsys.Slab, lmfh cos.LomWriter, er
499499
writers := make([]io.Writer, 0, 3)
500500
cksums.store = cos.NewCksumHash(ckconf.Type) // always according to the bucket
501501
writers = append(writers, cksums.store.H)
502-
if !poi.skipVC && !poi.cksumToUse.IsEmpty() && poi.validateCksum(ckconf) {
502+
if !poi.skipVC && !cos.NoneC(poi.cksumToUse) && poi.validateCksum(ckconf) {
503503
cksums.expct = poi.cksumToUse
504504
if poi.cksumToUse.Type() == cksums.store.Type() {
505505
cksums.compt = cksums.store
@@ -1450,7 +1450,7 @@ func (a *apndOI) flush() (int, error) {
14501450
debug.Assert(a.hdl.partialCksum != nil)
14511451
a.hdl.partialCksum.Finalize()
14521452
partialCksum := a.hdl.partialCksum.Clone()
1453-
if !a.cksum.IsEmpty() && !partialCksum.Equal(a.cksum) {
1453+
if !cos.NoneC(a.cksum) && !partialCksum.Equal(a.cksum) {
14541454
return http.StatusInternalServerError, cos.NewErrDataCksum(partialCksum, a.cksum)
14551455
}
14561456

ais/tpromote.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func (t *target) _promLocal(params *core.PromoteParams, lom *core.LOM) (fileSize
109109
}
110110
}
111111

112-
if params.Cksum != nil && cksum != nil && !cksum.IsEmpty() {
112+
if params.Cksum != nil && !cos.NoneH(cksum) {
113113
if !cksum.Equal(params.Cksum) {
114114
return 0, 0, cos.NewErrDataCksum(
115115
cksum.Clone(),

cmn/cos/cksum.go

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const (
4444
)
4545

4646
type (
47-
noopHash struct{}
47+
noneHash struct{}
4848

4949
// in-cluster checksum validation (compare with cmn.ErrInvalidCksum)
5050
ErrBadCksum struct {
@@ -77,16 +77,21 @@ var checksums = StrSet{
7777
ChecksumSHA512: {},
7878
}
7979

80-
// interface guard
81-
var (
82-
_ hash.Hash = (*noopHash)(nil)
83-
_ encoding.BinaryUnmarshaler = (*noopHash)(nil)
84-
_ encoding.BinaryUnmarshaler = (*noopHash)(nil)
80+
var NoneCksum = NewCksum(ChecksumNone, "")
8581

86-
_ io.Writer = (*CksumHashSize)(nil)
87-
)
82+
func NoneC(ck *Cksum) bool {
83+
if ck == nil {
84+
return true
85+
}
86+
return ck.ty == "" || ck.ty == ChecksumNone || ck.value == ""
87+
}
8888

89-
var NoneCksum = NewCksum(ChecksumNone, "")
89+
func NoneH(ck *CksumHash) bool {
90+
if ck == nil {
91+
return true
92+
}
93+
return NoneC(&ck.Cksum)
94+
}
9095

9196
///////////////
9297
// CksumHash //
@@ -121,7 +126,7 @@ func (ck *CksumHash) Init(ty string) {
121126
ck.ty = ty
122127
switch ty {
123128
case ChecksumNone, "":
124-
ck.ty, ck.H = ChecksumNone, newNoopHash()
129+
ck.ty, ck.H = ChecksumNone, &noneHash{}
125130
case ChecksumOneXxh:
126131
ck.H = onexxh.New64()
127132
case ChecksumCesXxh:
@@ -153,6 +158,11 @@ func (ck *CksumHash) Finalize() {
153158
// CksumHashSize //
154159
///////////////////
155160

161+
// interface guard
162+
var (
163+
_ io.Writer = (*CksumHashSize)(nil)
164+
)
165+
156166
func (ck *CksumHashSize) Write(b []byte) (n int, err error) {
157167
n, err = ck.H.Write(b)
158168
ck.Size += int64(n)
@@ -163,10 +173,6 @@ func (ck *CksumHashSize) Write(b []byte) (n int, err error) {
163173
// Cksum //
164174
///////////
165175

166-
func (ck *Cksum) IsEmpty() bool {
167-
return ck == nil || ck.ty == "" || ck.ty == ChecksumNone || ck.value == ""
168-
}
169-
170176
func NewCksum(ty, value string) *Cksum {
171177
if err := ValidateCksumType(ty, true /*empty OK*/); err != nil {
172178
AssertMsg(false, err.Error())
@@ -179,8 +185,8 @@ func NewCksum(ty, value string) *Cksum {
179185

180186
// NOTE [caution]: empty checksums are also equal (compare with lom.EqCksum and friends)
181187
func (ck *Cksum) Equal(to *Cksum) bool {
182-
if ck.IsEmpty() || to.IsEmpty() {
183-
return ck.IsEmpty() == to.IsEmpty()
188+
if a, b := NoneC(ck), NoneC(to); a || b {
189+
return a && b
184190
}
185191
return ck.ty == to.ty && ck.value == to.value
186192
}
@@ -258,17 +264,23 @@ func ValidateCksumType(ty string, emptyOK ...bool) (err error) {
258264
}
259265

260266
//
261-
// noopHash
267+
// noneHash
262268
//
263269

264-
func newNoopHash() hash.Hash { return &noopHash{} }
265-
func (*noopHash) Write(b []byte) (int, error) { return len(b), nil }
266-
func (*noopHash) Sum([]byte) []byte { return nil }
267-
func (*noopHash) Reset() {}
268-
func (*noopHash) Size() int { return 0 }
269-
func (*noopHash) BlockSize() int { return KiB }
270-
func (*noopHash) MarshalBinary() ([]byte, error) { return nil, nil }
271-
func (*noopHash) UnmarshalBinary([]byte) error { return nil }
270+
// interface guard
271+
var (
272+
_ hash.Hash = (*noneHash)(nil)
273+
_ encoding.BinaryMarshaler = (*noneHash)(nil) // usage: append object (to serialize append handle)
274+
)
275+
276+
func (*noneHash) Write(b []byte) (int, error) { return len(b), nil }
277+
func (*noneHash) Sum([]byte) []byte { return nil }
278+
func (*noneHash) Reset() {}
279+
func (*noneHash) Size() int { return 0 }
280+
func (*noneHash) BlockSize() int { return KiB }
281+
282+
func (*noneHash) MarshalBinary() ([]byte, error) { return nil, nil }
283+
func (*noneHash) UnmarshalBinary([]byte) error { return nil }
272284

273285
//
274286
// errors

cmn/objattrs.go

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (oa *ObjAttrs) Checksum() *cos.Cksum { return oa.Cksum }
111111
func (oa *ObjAttrs) SetCksum(ty, val string) { oa.Cksum = cos.NewCksum(ty, val) }
112112

113113
func (oa *ObjAttrs) EqCksum(cksum *cos.Cksum) bool {
114-
return !oa.Cksum.IsEmpty() && oa.Cksum.Equal(cksum)
114+
return !cos.NoneC(oa.Cksum) && oa.Cksum.Equal(cksum)
115115
}
116116

117117
func (oa *ObjAttrs) Version(_ ...bool) string {
@@ -189,7 +189,7 @@ func ToHeader(oah cos.OAH, hdr http.Header, size int64, cksums ...*cos.Cksum) {
189189
} else {
190190
cksum = oah.Checksum()
191191
}
192-
if !cksum.IsEmpty() {
192+
if !cos.NoneC(cksum) {
193193
hdr.Set(apc.HdrObjCksumType, cksum.Ty())
194194
hdr.Set(apc.HdrObjCksumVal, cksum.Val())
195195
}
@@ -270,12 +270,12 @@ func (oa *ObjAttrs) CheckEq(rem cos.OAH) error {
270270
sameEtag bool
271271
sameCksum bool
272272
)
273-
// size check
273+
// 1. size
274274
if remSize := rem.Lsize(true); oa.Size != 0 && remSize != 0 && oa.Size != remSize {
275275
return fmt.Errorf("size %d != %d remote", oa.Size, remSize)
276276
}
277277

278-
// Cloud version check (NOTE: ais own version is currently a non-unique sequence number)
278+
// 2. version (note that ais own version is a simple sequence number)
279279
if remMeta, ok := rem.GetCustomKey(VersionObjMD); ok && remMeta != "" {
280280
if locMeta, ok := oa.GetCustomKey(VersionObjMD); ok && locMeta != "" {
281281
if remMeta != locMeta {
@@ -286,32 +286,28 @@ func (oa *ObjAttrs) CheckEq(rem cos.OAH) error {
286286
}
287287
}
288288

289-
// checksum check
290-
if a, b := rem.Checksum(), oa.Cksum; a != nil && b != nil {
291-
cksumType := a.Ty()
292-
if !a.IsEmpty() && !b.IsEmpty() && cksumType == b.Ty() {
289+
// 3. checksum
290+
if a := rem.Checksum(); !cos.NoneC(a) {
291+
b := oa.Cksum
292+
if !cos.NoneC(b) {
293+
ty := a.Ty()
293294
if !a.Equal(b) {
294-
return fmt.Errorf("%s checksum %s != %s remote", cksumType, b, a)
295+
return fmt.Errorf("%s checksum %s != %s remote", ty, b, a)
295296
}
296297
cksumVal = a.Val()
297-
298-
// [NOTE]
299-
// unless overridden via feature flag
300-
// trust two checksums, namely md5 and xxhash, that are _not_ cryptographically secure
301-
302298
switch {
303299
case Rom.Features().IsSet(feat.TrustCryptoSafeChecksums):
304-
sameCksum = (cksumType == cos.ChecksumSHA256 || cksumType == cos.ChecksumSHA512)
300+
sameCksum = (ty == cos.ChecksumSHA256 || ty == cos.ChecksumSHA512)
305301
default:
306-
debug.Assert(cksumType != cos.ChecksumNone)
307-
sameCksum = cksumType != cos.ChecksumCRC32C
302+
// NOTE trust non-cryptographic checksums except crc (unless overridden by feature flag)
303+
debug.Assert(ty != cos.ChecksumNone)
304+
sameCksum = ty != cos.ChecksumCRC32C
308305
}
309-
310306
count++
311307
}
312308
}
313309

314-
// custom MD: ETag check (ignoring enclosing quotes)
310+
// 4. custom MD: ETag check (ignoring enclosing quotes)
315311
if remMeta, ok := rem.GetCustomKey(ETag); ok && remMeta != "" {
316312
if locMeta, ok := oa.GetCustomKey(ETag); ok && locMeta != "" {
317313
if !_eqIgnoreQuotes(remMeta, locMeta) {
@@ -324,7 +320,7 @@ func (oa *ObjAttrs) CheckEq(rem cos.OAH) error {
324320
}
325321
}
326322
}
327-
// custom MD: CRC check
323+
// 4.1. custom MD: CRC
328324
if remMeta, ok := rem.GetCustomKey(CRC32CObjMD); ok && remMeta != "" {
329325
if locMeta, ok := oa.GetCustomKey(CRC32CObjMD); ok && locMeta != "" {
330326
if remMeta != locMeta {
@@ -336,7 +332,7 @@ func (oa *ObjAttrs) CheckEq(rem cos.OAH) error {
336332
}
337333
}
338334

339-
// custom MD: MD5 check iff count < 2
335+
// 4.2. custom MD: MD5 iff count < 2
340336
// (ETag ambiguity, see: https://docs.aws.amazon.com/AmazonS3/latest/API/API_Object.htm)
341337
if !sameEtag {
342338
if remMeta, ok := rem.GetCustomKey(MD5ObjMD); ok && remMeta != "" {

core/lcopy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ func (lom *LOM) copy2fqn(dst *LOM, buf []byte) (err error) {
278278
srcCksum = lom.Checksum()
279279
cksumType = cos.ChecksumNone
280280
)
281-
if !srcCksum.IsEmpty() {
281+
if !cos.NoneC(srcCksum) {
282282
cksumType = srcCksum.Ty()
283283
}
284284
if dst.isMirror(lom) && lom.md.copies != nil {

core/lom.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func (lom *LOM) SetSize(size int64) { lom.md.Size = size }
171171
func (lom *LOM) Checksum() *cos.Cksum { return lom.md.Cksum }
172172
func (lom *LOM) SetCksum(cksum *cos.Cksum) { lom.md.Cksum = cksum }
173173
func (lom *LOM) EqCksum(cksum *cos.Cksum) bool {
174-
return !lom.md.Cksum.IsEmpty() && lom.md.Cksum.Equal(cksum)
174+
return !cos.NoneC(lom.md.Cksum) && lom.md.Cksum.Equal(cksum)
175175
}
176176

177177
func (lom *LOM) Atime() time.Time { return time.Unix(0, lom.md.Atime) }
@@ -331,13 +331,13 @@ recomp:
331331
if cksumType == cos.ChecksumNone { // as far as do-no-checksum-checking bucket rules
332332
return nil
333333
}
334-
if !lom.md.Cksum.IsEmpty() {
334+
if !cos.NoneC(lom.md.Cksum) {
335335
cksumType = lom.md.Cksum.Ty() // takes precedence on the other hand
336336
}
337337
if cksums.comp, err = lom.ComputeCksum(cksumType, locked); err != nil {
338338
return err
339339
}
340-
if lom.md.Cksum.IsEmpty() { // store computed
340+
if cos.NoneC(lom.md.Cksum) { // store computed
341341
lom.md.Cksum = cksums.comp.Clone()
342342
if !lom.loaded() {
343343
lom.SetAtimeUnix(time.Now().UnixNano())

core/ufest.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ const (
3737
iniChunksCap = 16
3838

3939
maxChunkSize = 5 * cos.GiB
40-
maxMetaKeys = 1000
40+
41+
maxMetaKeys = 1000
42+
maxMetaEntryLen = 4 * cos.KiB
4143
)
4244

4345
const (
@@ -108,6 +110,11 @@ func (u *Ufest) SetMeta(md map[string]string) error {
108110
if l := len(md); l > maxMetaKeys {
109111
return fmt.Errorf("%s: number of metadata entries %d exceeds %d limit", utag, l, maxMetaKeys)
110112
}
113+
for k, v := range md {
114+
if len(k) > maxMetaEntryLen || len(v) > maxMetaEntryLen {
115+
return fmt.Errorf("%s: metadata entry too large (%d, %d, %d)", utag, len(k), len(v), maxMetaEntryLen)
116+
}
117+
}
111118
u.mdmap = md
112119
return nil
113120
}
@@ -419,7 +426,7 @@ func _packStr(w io.Writer, s string) {
419426
}
420427

421428
func _packCksum(w io.Writer, cksum *cos.Cksum) {
422-
if cksum == nil || cksum.IsEmpty() {
429+
if cos.NoneC(cksum) {
423430
_packStr(w, "")
424431
return
425432
}

0 commit comments

Comments
 (0)