Skip to content

Commit

Permalink
Fix a race condition in dbuf_dirty().
Browse files Browse the repository at this point in the history
We need to wait for pending I/O to finish before trying to clear the
dirty record's override state.

This problem occurs when multiple threads call dbuf_dirty() for the
same dbuf object while it is currently being synced via dmu_sync()
but hasn't reached dmu_sync_done() yet:

  zfs: allocating allocated segment(offset=323629568 size=78336)
  SPLError: 2283:0:(spl-err.c:48:vpanic()) SPL PANIC

Issue openzfs#541
  • Loading branch information
gunnarbeutner committed Oct 30, 2012
1 parent e8fd45a commit 86d68d3
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions module/zfs/dbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,10 @@ dbuf_dirty(dmu_buf_impl_t *db, dmu_tx_t *tx)
DB_DNODE_EXIT(db);

if (db->db_level == 0 && db->db_blkid != DMU_BONUS_BLKID) {
/* Wait for pending I/O. */
while (dr->dt.dl.dr_override_state == DR_IN_DMU_SYNC)
cv_wait(&db->db_changed, &db->db_mtx);

/*
* If this buffer has already been written out,
* we now need to reset its state.
Expand Down

0 comments on commit 86d68d3

Please sign in to comment.