Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Feb 2013 14:29:38 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r246678 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201302111429.r1BETd3E025933@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Mon Feb 11 14:29:38 2013
New Revision: 246678
URL: http://svnweb.freebsd.org/changeset/base/246678

Log:
  MFV r246633:
  Import vendor bugfixes regarding SA rounding, header size and layout.
  This was already partially fixed by avg.
  
  Illumos ZFS issues:
    3512 rounding discrepancy in sa_find_sizes()
    3513 mismatch between SA header size and layout
  
  References:
    https://www.illumos.org/issues/3512
    https://www.illumos.org/issues/3513
  
  MFC after:	2 weeks

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	Mon Feb 11 14:27:32 2013	(r246677)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c	Mon Feb 11 14:29:38 2013	(r246678)
@@ -553,6 +553,7 @@ 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;
@@ -574,11 +575,13 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 	    sizeof (sa_hdr_phys_t);
 
 	full_space = (buftype == SA_BONUS) ? DN_MAX_BONUSLEN : db->db_size;
+	ASSERT(IS_P2ALIGNED(full_space, 8));
 
 	for (i = 0; i != attr_count; i++) {
 		boolean_t is_var_sz;
 
-		*total += P2ROUNDUP(attr_desc[i].sa_length, 8);
+		*total = P2ROUNDUP(*total, 8);
+		*total += attr_desc[i].sa_length;
 		if (done)
 			goto next;
 
@@ -590,7 +593,14 @@ sa_find_sizes(sa_os_t *sa, sa_bulk_attr_
 		if (is_var_sz && var_size > 1) {
 			if (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.
+				 */
 				hdrsize += sizeof (uint16_t);
+				j = i;
 			} else {
 				done = B_TRUE;
 				*index = i;
@@ -619,6 +629,14 @@ next:
 			*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);
+
 	hdrsize = P2ROUNDUP(hdrsize, 8);
 	return (hdrsize);
 }
@@ -709,6 +727,8 @@ sa_build_layouts(sa_handle_t *hdl, sa_bu
 	for (i = 0, len_idx = 0, hash = -1ULL; i != attr_count; i++) {
 		uint16_t length;
 
+		ASSERT(IS_P2ALIGNED(data_start, 8));
+		ASSERT(IS_P2ALIGNED(buf_space, 8));
 		attrs[i] = attr_desc[i].sa_attr;
 		length = SA_REGISTERED_LEN(sa, attrs[i]);
 		if (length == 0)
@@ -717,6 +737,7 @@ sa_build_layouts(sa_handle_t *hdl, sa_bu
 			VERIFY(length == attr_desc[i].sa_length);
 
 		if (buf_space < length) {  /* switch to spill buffer */
+			VERIFY(spilling);
 			VERIFY(bonustype == DMU_OT_SA);
 			if (buftype == SA_BONUS && !sa->sa_force_spill) {
 				sa_find_layout(hdl->sa_os, hash, attrs_start,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302111429.r1BETd3E025933>