diff options
author | Paul Zuchowski <[email protected]> | 2019-03-06 12:50:55 -0500 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-03-06 09:50:55 -0800 |
commit | a73e8fdb93d24b885f0c38202a34da51013d674a (patch) | |
tree | ce23108be9aee5f492375ce034e836769654e15b /module/zfs/dbuf.c | |
parent | 96ebc5a1a4cc57806882e4e9b38c49ba8a5bdfda (diff) |
Stack overflow in recursive bpobj_iterate_impl
The function bpobj_iterate_impl overflows the stack when bpobjs
are deeply nested. Rewrite the function to eliminate the recursion.
Reviewed-by: Serapheim Dimitropoulos <[email protected]>
Reviewed-by: Matt Ahrens <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Paul Zuchowski <[email protected]>
Closes #7674
Closes #7675
Closes #7908
Diffstat (limited to 'module/zfs/dbuf.c')
-rw-r--r-- | module/zfs/dbuf.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/module/zfs/dbuf.c b/module/zfs/dbuf.c index 9f3c9bfd5..28ff5fc7e 100644 --- a/module/zfs/dbuf.c +++ b/module/zfs/dbuf.c @@ -2311,6 +2311,23 @@ dmu_buf_will_dirty(dmu_buf_t *db_fake, dmu_tx_t *tx) DB_RF_MUST_SUCCEED | DB_RF_NOPREFETCH, tx); } +boolean_t +dmu_buf_is_dirty(dmu_buf_t *db_fake, dmu_tx_t *tx) +{ + dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake; + + mutex_enter(&db->db_mtx); + for (dbuf_dirty_record_t *dr = db->db_last_dirty; + dr != NULL && dr->dr_txg >= tx->tx_txg; dr = dr->dr_next) { + if (dr->dr_txg == tx->tx_txg) { + mutex_exit(&db->db_mtx); + return (B_TRUE); + } + } + mutex_exit(&db->db_mtx); + return (B_FALSE); +} + void dmu_buf_will_not_fill(dmu_buf_t *db_fake, dmu_tx_t *tx) { @@ -4564,6 +4581,7 @@ EXPORT_SYMBOL(dbuf_release_bp); EXPORT_SYMBOL(dbuf_dirty); EXPORT_SYMBOL(dmu_buf_set_crypt_params); EXPORT_SYMBOL(dmu_buf_will_dirty); +EXPORT_SYMBOL(dmu_buf_is_dirty); EXPORT_SYMBOL(dmu_buf_will_not_fill); EXPORT_SYMBOL(dmu_buf_will_fill); EXPORT_SYMBOL(dmu_buf_fill_done); |