dm snapshot: fix header corruption race on invalidation
commit30d026addc77ab55120db88f4e17acae217b9115
authorMikulas Patocka <mpatocka@redhat.com>
Fri, 4 Sep 2009 19:40:39 +0000 (4 20:40 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 15 Sep 2009 17:45:34 +0000 (15 10:45 -0700)
treec9f24e90b0160efdc8066a4c65aed25aea50fc72
parent008f14e7842214765ee1f535f003ca1aa72f7ee3
dm snapshot: fix header corruption race on invalidation

commit 61578dcd3fafe6babd72e8db32110cc0b630a432 upstream.

If a persistent snapshot fills up, a race can corrupt the on-disk header
which causes a crash on any future attempt to activate the snapshot
(typically while booting).  This patch fixes the race.

When the snapshot overflows, __invalidate_snapshot is called, which calls
snapshot store method drop_snapshot. It goes to persistent_drop_snapshot that
calls write_header. write_header constructs the new header in the "area"
location.

Concurrently, an existing kcopyd job may finish, call copy_callback
and commit_exception method, that goes to persistent_commit_exception.
persistent_commit_exception doesn't do locking, relying on the fact that
callbacks are single-threaded, but it can race with snapshot invalidation and
overwrite the header that is just being written while the snapshot is being
invalidated.

The result of this race is a corrupted header being written that can
lead to a crash on further reactivation (if chunk_size is zero in the
corrupted header).

The fix is to use separate memory areas for each.

See the bug: https://bugzilla.redhat.com/show_bug.cgi?id=461506

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/md/dm-snap-persistent.c