hammer2 - Fix hammer2_chain and dedup issues
commitf48e8306e8407bd47866b4b7fdcc997f18351f9f
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 26 Aug 2017 04:37:00 +0000 (25 21:37 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 26 Aug 2017 04:37:00 +0000 (25 21:37 -0700)
tree00ae3181ccf096a0333e458dc35ce2f12f0c1b10
parentc67b840b96dbd9d96905d9088ead0876770c7663
hammer2 - Fix hammer2_chain and dedup issues

* Fix races in hammer2_chain_drop().  A concurrent re-reference of the
  chain can race the dio teardown and generally cause havoc.  Generally
  fixed by acquiring the chain's mutex during the teardown.

* Due to mechanics changes in recent commits, chain data will always
  be dropped prior to the last ref drop, so replace checks in the
  lastdrop code with assertions that the chain data has already been
  dropped.  (Chain data is always dropped on the last unlock in order
  to be able to release the struct buf).

* The last dedup change closed one timing hole but opened up another one.
  There are two timing issues.  One is the time gap between the allocation
  of a block verses setting of bits in the DIO that indicate the block is
  good for dedup.  The second is the time gap between setting the bits and
  actually populating the DIO with the de-dup data.

  What could happen is that another thread could sneak in after the bits
  are set but before the data is populated and match a dedup against old
  previously freed data.  The old data then gets wiped away by the new
  data and the filesystem becomes corrupted.

  Fixed by adding a second bitmap to the DIO.  One indicates that the DIO
  is valid from an allocation perspective, the second indicates that the
  DIO is valid from a dedup perspective.  The dedup is not allowed unless
  both bitmaps indicate validity.

* Remove DIO dedup deletions in situations where a modified chain is
  discarded or replaced.  For example, if a file is deleted.  The data,
  in fact, is still perfectly dedupable since the underlying block
  allocation remains intact.
sys/vfs/hammer2/hammer2.h
sys/vfs/hammer2/hammer2_chain.c
sys/vfs/hammer2/hammer2_io.c
sys/vfs/hammer2/hammer2_strategy.c