kernel - Fix SMP races with vnode cluster fields
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 4 Dec 2013 01:42:46 +0000 (17:42 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 4 Dec 2013 02:03:48 +0000 (18:03 -0800)
commit38a4b3080c769f150fdc231473133e141c4a24f7
tree9f9e381276cb3f395bac62d7566c7cd97cada029
parent9e7329f3f45880c0e210960519ca7c3e01d746a3
kernel - Fix SMP races with vnode cluster fields

* The better concurrency we have due to the recent buffer cache work has
  revealed a SMP race in the vfs_cluster code.  Various fields used by
  cluster_write() can race and cause the wrong buffers to be clustered to
  the wrong disk offset, resulting in disk corruption.

* Rip the v_lastw, v_cstart, v_lasta, and v_clen fields out of struct vnode
  and replace with a global cluster state cache in vfs_cluster.c.

  The cache is implemented as a 512-entry hash table, 4-way set associative,
  and is more advanced than the original implementation in that it allows
  up to four different seek zones to be tracked on each vnode, instead of
  only one.  This should make buffered device I/O (used by filesystems)
  work better.

  Cache elements are heuristically locked with an atomic_swap_int().  If
  the code is unable to instantly acquire a lock on an element it will
  simply not cluster that particular I/O (instead of blocking).  Even though
  this is a global hash table, operations will have a tendancy to be
  localized to cache elements.

* Remove some manual clearing of fields in UFS's ffs_truncate() routine.
  It should have no material effect.
sys/kern/vfs_cluster.c
sys/sys/vnode.h
sys/vfs/ufs/ffs_inode.c