The byteoffset calculation was skewed to double include
the offset value calculated. The double calculation
happens if the starting ordinal is part of the head
sequence block. This error in calculation could result
in duplicate but getting allocated eventually propogating
to ipam and vni id allocations
Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
| ... | ... |
@@ -497,7 +497,10 @@ func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
|
| 497 | 497 |
// Derive the this sequence offsets |
| 498 | 498 |
byteOffset := byteStart - inBlockBytePos |
| 499 | 499 |
bitOffset := inBlockBytePos*8 + bitStart |
| 500 |
- |
|
| 500 |
+ var firstOffset uint64 |
|
| 501 |
+ if current == head {
|
|
| 502 |
+ firstOffset = byteOffset |
|
| 503 |
+ } |
|
| 501 | 504 |
for current != nil {
|
| 502 | 505 |
if current.block != blockMAX {
|
| 503 | 506 |
bytePos, bitPos, err := current.getAvailableBit(bitOffset) |
| ... | ... |
@@ -505,7 +508,8 @@ func getFirstAvailable(head *sequence, start uint64) (uint64, uint64, error) {
|
| 505 | 505 |
} |
| 506 | 506 |
// Moving to next block: Reset bit offset. |
| 507 | 507 |
bitOffset = 0 |
| 508 |
- byteOffset += current.count * blockBytes |
|
| 508 |
+ byteOffset += (current.count * blockBytes) - firstOffset |
|
| 509 |
+ firstOffset = 0 |
|
| 509 | 510 |
current = current.next |
| 510 | 511 |
} |
| 511 | 512 |
return invalidPos, invalidPos, ErrNoBitAvailable |