diff options
author | Brian Behlendorf <[email protected]> | 2011-05-25 14:13:18 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-05-31 12:17:27 -0700 |
commit | 5b8c7bbcea7ad9ecd5f329d2d736cba8402ee781 (patch) | |
tree | 259951fd113559e14c324c8d45b3c6e00e20bc29 /module | |
parent | c7f8f831a463e9d7d16e43323b71d9e9e187a4c7 (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')
-rw-r--r-- | module/zfs/ddt_zap.c | 12 |
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 |