aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/dbuf.c
diff options
context:
space:
mode:
authorPaul Zuchowski <[email protected]>2019-03-06 12:50:55 -0500
committerBrian Behlendorf <[email protected]>2019-03-06 09:50:55 -0800
commita73e8fdb93d24b885f0c38202a34da51013d674a (patch)
treece23108be9aee5f492375ce034e836769654e15b /module/zfs/dbuf.c
parent96ebc5a1a4cc57806882e4e9b38c49ba8a5bdfda (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.c18
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);