kernel - Change bundirty() location in I/O sequence
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 21 May 2015 05:18:41 +0000 (22:18 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 21 May 2015 05:18:41 +0000 (22:18 -0700)
commitffd3e597d368aae907e57dfbdaf3ea429482905f
tree3f08fe5f32e9d6b7b551bb65e52379556a892726
parent9450e8667e9c5fcfbc27c0174c83b4c9a7a42fda
kernel - Change bundirty() location in I/O sequence

* When doing a write BIO, do not bundirty() the buffer prior to issuing
  the vn_strategy().  Instead, bundirty() the buffer when the I/O
  is complete, primarily in bpdone().

  The I/O's data buffer is protected during the operation by vfs_busy_pages(),
  so related VM pages cannot be modified while the write is running.  And,
  of course, the buffer itself is locked exclusively for the duration of the
  opeartion.  Thus this change should NOT introduce any redirtying races.

* This change ensures that vp->v_rbdirty_tree remains non-empty until all
  related write I/Os have completed, removing a race condition for code
  which checks vp->v_rbdirty_tree to determine e.g. if a file requires
  synchronization or not.

  This race could cause problems because the system buffer flusher might
  be in the midst of flushing a buffer just as a filesystem decides to
  sync and starts checking vp->v_rbdirty_tree.

* This should theoretically fix a long-standing but difficult-to-reproduce
  bug in HAMMER1 where a backend flush occurs at an inopportune time.
sys/kern/vfs_bio.c
sys/kern/vfs_cluster.c
sys/kern/vfs_subr.c
sys/kern/vfs_sync.c