Author: avg
Date: Sat Oct  6 18:53:48 2012
New Revision: 241266
URL: http://svn.freebsd.org/changeset/base/241266

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

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

Modified: stable/9/sys/boot/zfs/zfsimpl.c
==============================================================================
--- stable/9/sys/boot/zfs/zfsimpl.c     Sat Oct  6 18:52:06 2012        
(r241265)
+++ stable/9/sys/boot/zfs/zfsimpl.c     Sat Oct  6 18:53:48 2012        
(r241266)
@@ -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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to