svn commit: r294813 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Alexander Motin mav at FreeBSD.org
Tue Jan 26 13:03:02 UTC 2016


Author: mav
Date: Tue Jan 26 13:03:01 2016
New Revision: 294813
URL: https://svnweb.freebsd.org/changeset/base/294813

Log:
  MFV r294812: 6434 sa_find_sizes() may compute wrong SA header size
  
  Reviewed-by: Ned Bass <bass6 at llnl.gov>
  Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
  Reviewed by: Andriy Gapon <avg at freebsd.org>
  Reviewed by: Matthew Ahrens <mahrens at delphix.com>
  Approved by: Robert Mustacchi <rm at joyent.com>
  Author: James Pan <jiaming.pan at yahoo.com>
  
  illumos/illumos-gate at 3502ed6e7cb3f3d2e781960ab8fe465fdc884834

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
Directory Properties:
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c	Tue Jan 26 13:02:16 2016	(r294812)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c	Tue Jan 26 13:03:01 2016	(r294813)
@@ -547,10 +547,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;
-	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_
 
 	*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_
 
 		*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_
 		}
 
 		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_
 		    (*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);


More information about the svn-src-head mailing list