--- sa.c.orig	2013-09-27 09:10:29.000000000 +0800
+++ sa.c	2013-11-16 19:39:16.000000000 +0800
@@ -552,9 +552,9 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 {
 	int var_size = 0;
 	int i;
-	int j = -1;
 	int full_space;
 	int hdrsize;
+	int extra_hdrsize;
 	boolean_t done = B_FALSE;
 
 	if (buftype == SA_BONUS && sa->sa_force_spill) {
@@ -570,6 +570,7 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 	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);
 
@@ -581,8 +582,10 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 
 		*total = P2ROUNDUP(*total, 8);
 		*total += attr_desc[i].sa_length;
-		if (done)
-			goto next;
+
+		if (buftype == SA_BONUS && *will_spill) {
+			continue;
+		}
 
 		is_var_sz = (SA_REGISTERED_LEN(sa, attr_desc[i].sa_attr) == 0);
 		if (is_var_sz) {
@@ -590,19 +593,26 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 		}
 
 		if (is_var_sz && var_size > 1) {
-			if (P2ROUNDUP(hdrsize + sizeof (uint16_t), 8) +
+			/* Don't worry the spill block will be overflowed,
+			 * we will resize the spill block later 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
+				 * Record the extra header size in case this increase needs
 				 * to be reversed due to spill-over.
 				 */
 				hdrsize += sizeof (uint16_t);
-				j = i;
+				if (done)
+					extra_hdrsize += sizeof (uint16_t);
 			} else {
-				done = B_TRUE;
-				*index = i;
+				if (!done) {
+					done = B_TRUE;
+					*index = i;
+				}
 				if (buftype == SA_BONUS)
 					*will_spill = B_TRUE;
 				continue;
@@ -622,19 +632,13 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 			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 (buftype == SA_BONUS && *will_spill)
+		hdrsize -= extra_hdrsize;
 
 	hdrsize = P2ROUNDUP(hdrsize, 8);
 	return (hdrsize);
