Fix a bug in sa_find_sizes() which could lead to panic:

When calculating space needed for SA_BONUS buffers,
hdrsize is always rounded up to next 8-aligned boundary.
However, in two places the round up was done against
sum of 'total' plus hdrsize.  On the other hand,
hdrsize increments by 4 each time, which means in
certain conditions, we would end up returning with
will_spill == 0 and (total + hdrsize) larger than
full_space, leading to a failed assertion because
it's invalid for dmu_set_bonus.

Sponsored by:	iXsystems, Inc.
Reviewed by:	mm
MFC after:	3 days
This commit is contained in:
Xin LI 2011-10-17 22:23:27 +00:00
parent 6b15a26aa6
commit 4aadb12e0b

View File

@ -605,14 +605,14 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
* and spill buffer.
*/
if (buftype == SA_BONUS && *index == -1 &&
P2ROUNDUP(*total + hdrsize, 8) >
(*total + P2ROUNDUP(hdrsize, 8)) >
(full_space - sizeof (blkptr_t))) {
*index = i;
done = B_TRUE;
}
next:
if (P2ROUNDUP(*total + hdrsize, 8) > full_space &&
if ((*total + P2ROUNDUP(hdrsize, 8)) > full_space &&
buftype == SA_BONUS)
*will_spill = B_TRUE;
}