aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/ddt_zap.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2011-05-25 14:13:18 -0700
committerBrian Behlendorf <[email protected]>2011-05-31 12:17:27 -0700
commit5b8c7bbcea7ad9ecd5f329d2d736cba8402ee781 (patch)
tree259951fd113559e14c324c8d45b3c6e00e20bc29 /module/zfs/ddt_zap.c
parentc7f8f831a463e9d7d16e43323b71d9e9e187a4c7 (diff)
Fix stack ddt_zap_lookup()
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.
Diffstat (limited to 'module/zfs/ddt_zap.c')
-rw-r--r--module/zfs/ddt_zap.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/module/zfs/ddt_zap.c b/module/zfs/ddt_zap.c
index d6a991c7c..280bff35a 100644
--- a/module/zfs/ddt_zap.c
+++ b/module/zfs/ddt_zap.c
@@ -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