]> git.proxmox.com Git - mirror_zfs-debian.git/commitdiff
Fix stack ddt_zap_lookup()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 25 May 2011 21:13:18 +0000 (14:13 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 31 May 2011 19:17:27 +0000 (12:17 -0700)
Stack usage for ddt_zap_lookup() reduced from 368 bytes to 120
bytes.  This large stack allocation significantly contributed to
the likelyhood of a stack overflow when scrubbing/resilvering
dedup pools.

module/zfs/ddt_zap.c

index d6a991c7c19ee040942a48a2550f216a14bbb4ab..280bff35a0b8c5d87d50b525e03b9bd2134152e6 100644 (file)
@@ -58,14 +58,16 @@ ddt_zap_destroy(objset_t *os, uint64_t object, dmu_tx_t *tx)
 static int
 ddt_zap_lookup(objset_t *os, uint64_t object, ddt_entry_t *dde)
 {
-       uchar_t cbuf[sizeof (dde->dde_phys) + 1];
+       uchar_t *cbuf;
        uint64_t one, csize;
        int error;
 
+       cbuf = kmem_alloc(sizeof (dde->dde_phys) + 1, KM_SLEEP);
+
        error = zap_length_uint64(os, object, (uint64_t *)&dde->dde_key,
            DDT_KEY_WORDS, &one, &csize);
        if (error)
-               return (error);
+               goto out;
 
        ASSERT(one == 1);
        ASSERT(csize <= sizeof (cbuf));
@@ -73,11 +75,13 @@ ddt_zap_lookup(objset_t *os, uint64_t object, ddt_entry_t *dde)
        error = zap_lookup_uint64(os, object, (uint64_t *)&dde->dde_key,
            DDT_KEY_WORDS, 1, csize, cbuf);
        if (error)
-               return (error);
+               goto out;
 
        ddt_decompress(cbuf, dde->dde_phys, csize, sizeof (dde->dde_phys));
+out:
+       kmem_free(cbuf, sizeof (dde->dde_phys) + 1);
 
-       return (0);
+       return (error);
 }
 
 static void