MFV r294812: 6434 sa_find_sizes() may compute wrong SA header size
Reviewed-by: Ned Bass <bass6@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Andriy Gapon <avg@freebsd.org> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Author: James Pan <jiaming.pan@yahoo.com> illumos/illumos-gate@3502ed6e7c
This commit is contained in:
parent
7a16fdf1bd
commit
71d7abc46e
@ -547,10 +547,9 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
{
|
||||
int var_size = 0;
|
||||
int i;
|
||||
int j = -1;
|
||||
int full_space;
|
||||
int hdrsize;
|
||||
boolean_t done = B_FALSE;
|
||||
int extra_hdrsize;
|
||||
|
||||
if (buftype == SA_BONUS && sa->sa_force_spill) {
|
||||
*total = 0;
|
||||
@ -561,10 +560,9 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
|
||||
*index = -1;
|
||||
*total = 0;
|
||||
*will_spill = B_FALSE;
|
||||
|
||||
if (buftype == SA_BONUS)
|
||||
*will_spill = B_FALSE;
|
||||
|
||||
extra_hdrsize = 0;
|
||||
hdrsize = (SA_BONUSTYPE_FROM_DB(db) == DMU_OT_ZNODE) ? 0 :
|
||||
sizeof (sa_hdr_phys_t);
|
||||
|
||||
@ -576,8 +574,8 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
|
||||
*total = P2ROUNDUP(*total, 8);
|
||||
*total += attr_desc[i].sa_length;
|
||||
if (done)
|
||||
goto next;
|
||||
if (*will_spill)
|
||||
continue;
|
||||
|
||||
is_var_sz = (SA_REGISTERED_LEN(sa, attr_desc[i].sa_attr) == 0);
|
||||
if (is_var_sz) {
|
||||
@ -585,21 +583,28 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
}
|
||||
|
||||
if (is_var_sz && var_size > 1) {
|
||||
if (P2ROUNDUP(hdrsize + sizeof (uint16_t), 8) +
|
||||
/*
|
||||
* Don't worry that the spill block might overflow.
|
||||
* It will be resized if needed in sa_build_layouts().
|
||||
*/
|
||||
if (buftype == SA_SPILL ||
|
||||
P2ROUNDUP(hdrsize + sizeof (uint16_t), 8) +
|
||||
*total < full_space) {
|
||||
/*
|
||||
* Account for header space used by array of
|
||||
* optional sizes of variable-length attributes.
|
||||
* Record the index in case this increase needs
|
||||
* to be reversed due to spill-over.
|
||||
* Record the extra header size in case this
|
||||
* increase needs to be reversed due to
|
||||
* spill-over.
|
||||
*/
|
||||
hdrsize += sizeof (uint16_t);
|
||||
j = i;
|
||||
if (*index != -1)
|
||||
extra_hdrsize += sizeof (uint16_t);
|
||||
} else {
|
||||
done = B_TRUE;
|
||||
*index = i;
|
||||
if (buftype == SA_BONUS)
|
||||
*will_spill = B_TRUE;
|
||||
ASSERT(buftype == SA_BONUS);
|
||||
if (*index == -1)
|
||||
*index = i;
|
||||
*will_spill = B_TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -614,22 +619,15 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_t *attr_desc, int attr_count,
|
||||
(*total + P2ROUNDUP(hdrsize, 8)) >
|
||||
(full_space - sizeof (blkptr_t))) {
|
||||
*index = i;
|
||||
done = B_TRUE;
|
||||
}
|
||||
|
||||
next:
|
||||
if ((*total + P2ROUNDUP(hdrsize, 8)) > full_space &&
|
||||
buftype == SA_BONUS)
|
||||
*will_spill = B_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* j holds the index of the last variable-sized attribute for
|
||||
* which hdrsize was increased. Reverse the increase if that
|
||||
* attribute will be relocated to the spill block.
|
||||
*/
|
||||
if (*will_spill && j == *index)
|
||||
hdrsize -= sizeof (uint16_t);
|
||||
if (*will_spill)
|
||||
hdrsize -= extra_hdrsize;
|
||||
|
||||
hdrsize = P2ROUNDUP(hdrsize, 8);
|
||||
return (hdrsize);
|
||||
|
Loading…
Reference in New Issue
Block a user