diff options
author | Brian Behlendorf <[email protected]> | 2011-05-25 13:56:40 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-05-31 12:17:27 -0700 |
commit | e95b3bdcbbc64ea502349413234e7c71563e7115 (patch) | |
tree | 50792f2a3b7a27d6a65e6f7428e0831e99a92b6f | |
parent | 5b8c7bbcea7ad9ecd5f329d2d736cba8402ee781 (diff) |
Fix stack ddt_class_contains()
Stack usage for ddt_class_contains() reduced from 524 bytes to 68
bytes. This large stack allocation significantly contributed to
the likelyhood of a stack overflow when scrubbing/resilvering
dedup pools.
-rw-r--r-- | module/zfs/ddt.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/module/zfs/ddt.c b/module/zfs/ddt.c index 49428d109..7279f1d5d 100644 --- a/module/zfs/ddt.c +++ b/module/zfs/ddt.c @@ -891,7 +891,7 @@ boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class, const blkptr_t *bp) { ddt_t *ddt; - ddt_entry_t dde; + ddt_entry_t *dde; enum ddt_type type; enum ddt_class class; @@ -902,14 +902,20 @@ ddt_class_contains(spa_t *spa, enum ddt_class max_class, const blkptr_t *bp) return (B_TRUE); ddt = spa->spa_ddt[BP_GET_CHECKSUM(bp)]; + dde = kmem_alloc(sizeof(ddt_entry_t), KM_SLEEP); - ddt_key_fill(&dde.dde_key, bp); + ddt_key_fill(&(dde->dde_key), bp); - for (type = 0; type < DDT_TYPES; type++) - for (class = 0; class <= max_class; class++) - if (ddt_object_lookup(ddt, type, class, &dde) == 0) + for (type = 0; type < DDT_TYPES; type++) { + for (class = 0; class <= max_class; class++) { + if (ddt_object_lookup(ddt, type, class, dde) == 0) { + kmem_free(dde, sizeof(ddt_entry_t)); return (B_TRUE); + } + } + } + kmem_free(dde, sizeof(ddt_entry_t)); return (B_FALSE); } |