Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Oct 2012 18:54:01 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r241267 - stable/8/sys/boot/zfs
Message-ID:  <201210061854.q96Is1XS019596@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Sat Oct  6 18:54:01 2012
New Revision: 241267
URL: http://svn.freebsd.org/changeset/base/241267

Log:
  MFC r240347: zfs boot: fix/replace fzap_rlookup implementation

Modified:
  stable/8/sys/boot/zfs/zfsimpl.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/boot/   (props changed)

Modified: stable/8/sys/boot/zfs/zfsimpl.c
==============================================================================
--- stable/8/sys/boot/zfs/zfsimpl.c	Sat Oct  6 18:53:48 2012	(r241266)
+++ stable/8/sys/boot/zfs/zfsimpl.c	Sat Oct  6 18:54:01 2012	(r241267)
@@ -1516,9 +1516,7 @@ fzap_rlookup(const spa_t *spa, const dno
 	int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
 	zap_phys_t zh = *(zap_phys_t *) zap_scratch;
 	fat_zap_t z;
-	uint64_t *ptrtbl;
-	uint64_t hash;
-	int rc;
+	int i, j;
 
 	if (zh.zap_magic != ZAP_MAGIC)
 		return (EIO);
@@ -1527,59 +1525,34 @@ fzap_rlookup(const spa_t *spa, const dno
 	z.zap_phys = (zap_phys_t *) zap_scratch;
 
 	/*
-	 * Figure out where the pointer table is and read it in if necessary.
+	 * This assumes that the leaf blocks start at block 1. The
+	 * documentation isn't exactly clear on this.
 	 */
-	if (zh.zap_ptrtbl.zt_blk) {
-		rc = dnode_read(spa, dnode, zh.zap_ptrtbl.zt_blk * bsize,
-			       zap_scratch, bsize);
-		if (rc)
-			return (rc);
-		ptrtbl = (uint64_t *) zap_scratch;
-	} else {
-		ptrtbl = &ZAP_EMBEDDED_PTRTBL_ENT(&z, 0);
-	}
-
-	hash = zap_hash(zh.zap_salt, name);
-
 	zap_leaf_t zl;
 	zl.l_bs = z.zap_block_shift;
+	for (i = 0; i < zh.zap_num_leafs; i++) {
+		off_t off = (i + 1) << zl.l_bs;
 
-	off_t off = ptrtbl[hash >> (64 - zh.zap_ptrtbl.zt_shift)] << zl.l_bs;
-	zap_leaf_chunk_t *zc;
-
-	rc = dnode_read(spa, dnode, off, zap_scratch, bsize);
-	if (rc)
-		return (rc);
+		if (dnode_read(spa, dnode, off, zap_scratch, bsize))
+			return (EIO);
 
-	zl.l_phys = (zap_leaf_phys_t *) zap_scratch;
+		zl.l_phys = (zap_leaf_phys_t *) zap_scratch;
 
-	/*
-	 * Make sure this chunk matches our hash.
-	 */
-	if (zl.l_phys->l_hdr.lh_prefix_len > 0
-	    && zl.l_phys->l_hdr.lh_prefix
-	    != hash >> (64 - zl.l_phys->l_hdr.lh_prefix_len))
-		return (ENOENT);
+		for (j = 0; j < ZAP_LEAF_NUMCHUNKS(&zl); j++) {
+			zap_leaf_chunk_t *zc;
 
-	/*
-	 * Hash within the chunk to find our entry.
-	 */
-	int shift = (64 - ZAP_LEAF_HASH_SHIFT(&zl) - zl.l_phys->l_hdr.lh_prefix_len);
-	int h = (hash >> shift) & ((1 << ZAP_LEAF_HASH_SHIFT(&zl)) - 1);
-	h = zl.l_phys->l_hash[h];
-	if (h == 0xffff)
-		return (ENOENT);
-	zc = &ZAP_LEAF_CHUNK(&zl, h);
-	while (zc->l_entry.le_hash != hash) {
-		if (zc->l_entry.le_next == 0xffff) {
-			zc = 0;
-			break;
+			zc = &ZAP_LEAF_CHUNK(&zl, j);
+			if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
+				continue;
+			if (zc->l_entry.le_value_intlen != 8 ||
+			    zc->l_entry.le_value_numints != 1)
+				continue;
+
+			if (fzap_leaf_value(&zl, zc) == value) {
+				fzap_name_copy(&zl, zc, name);
+				return (0);
+			}
 		}
-		zc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_next);
-	}
-	if (fzap_leaf_value(&zl, zc) == value) {
-		fzap_name_copy(&zl, zc, name);
-		return (0);
 	}
 
 	return (ENOENT);



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