dm thin: fix a race condition between discarding and provisioning a block
authorJoe Thornber <ejt@redhat.com>
Fri, 1 Jul 2016 13:00:02 +0000 (14:00 +0100)
committerMike Snitzer <snitzer@redhat.com>
Wed, 20 Jul 2016 16:43:35 +0000 (12:43 -0400)
commit2a0fbffb1e50939a969d5efe495667a3aa0f72f7
tree9d7dead9be062d72613d20bb3a98499054f81d1f
parente7e0f730477dea190fbc18c2d93338dacee82cea
dm thin: fix a race condition between discarding and provisioning a block

The discard passdown was being issued after the block was unmapped,
which meant the block could be reprovisioned whilst the passdown discard
was still in flight.

We can only identify unshared blocks (safe to do a passdown a discard
to) once they're unmapped and their ref count hits zero.  Block ref
counts are now used to guard against concurrent allocation of these
blocks that are being discarded.  So now we unmap the block, issue
passdown discards, and the immediately increment ref counts for regions
that have been discarded via passed down (this is safe because
allocation occurs within the same thread).  We then decrement ref counts
once the passdown discard IO is complete -- signaling these blocks may
now be allocated.

This fixes the potential for corruption that was reported here:
https://www.redhat.com/archives/dm-devel/2016-June/msg00311.html

Reported-by: Dennis Yang <dennisyang@qnap.com>
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin-metadata.h
drivers/md/dm-thin.c