Commit 69a2a4d9a5884a6f2d04a551308980d452b9b349
Committed by
Wolfgang Denk
1 parent
b9d51fbb18
Exists in
master
and in
54 other branches
disk/part.c: 'usb storage' avoiding overflow when output capacity
Before: Marvell>> usb storage Device 0: Vendor: StoreJet Rev: Prod: Transcend Type: Hard Disk Capacity: 28759.9 MB = 28.0 GB (488397168 x 512) After: Marvell>> usb storage Device 0: Vendor: StoreJet Rev: Prod: Transcend Type: Hard Disk Capacity: 238475.1 MB = 232.8 GB (488397168 x 512) Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
Showing 1 changed file with 23 additions and 5 deletions Side-by-side Diff
disk/part.c
... | ... | @@ -109,14 +109,31 @@ |
109 | 109 | /* |
110 | 110 | * reports device info to the user |
111 | 111 | */ |
112 | -void dev_print (block_dev_desc_t *dev_desc) | |
113 | -{ | |
112 | + | |
114 | 113 | #ifdef CONFIG_LBA48 |
115 | - uint64_t lba512; /* number of blocks if 512bytes block size */ | |
114 | +typedef uint64_t lba512_t; | |
116 | 115 | #else |
117 | - lbaint_t lba512; | |
116 | +typedef lbaint_t lba512_t; | |
118 | 117 | #endif |
119 | 118 | |
119 | +/* | |
120 | + * Overflowless variant of (block_count * mul_by / div_by) | |
121 | + * when div_by > mul_by | |
122 | + */ | |
123 | +static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by) | |
124 | +{ | |
125 | + lba512_t bc_quot, bc_rem; | |
126 | + | |
127 | + /* x * m / d == x / d * m + (x % d) * m / d */ | |
128 | + bc_quot = block_count / div_by; | |
129 | + bc_rem = block_count - div_by * bc_quot; | |
130 | + return bc_quot * mul_by + (bc_rem * mul_by) / div_by; | |
131 | +} | |
132 | + | |
133 | +void dev_print (block_dev_desc_t *dev_desc) | |
134 | +{ | |
135 | + lba512_t lba512; /* number of blocks if 512bytes block size */ | |
136 | + | |
120 | 137 | if (dev_desc->type == DEV_TYPE_UNKNOWN) { |
121 | 138 | puts ("not available\n"); |
122 | 139 | return; |
123 | 140 | |
... | ... | @@ -184,8 +201,9 @@ |
184 | 201 | lba = dev_desc->lba; |
185 | 202 | |
186 | 203 | lba512 = (lba * (dev_desc->blksz/512)); |
187 | - mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */ | |
188 | 204 | /* round to 1 digit */ |
205 | + mb = lba512_muldiv(lba512, 10, 2048); /* 2048 = (1024 * 1024) / 512 MB */ | |
206 | + | |
189 | 207 | mb_quot = mb / 10; |
190 | 208 | mb_rem = mb - (10 * mb_quot); |
191 | 209 |