• Mikulas Patocka's avatar
    dm snapshot: sort by chunk size to fix race · 6d45d93e
    Mikulas Patocka authored
    Avoid a race causing corruption when snapshots of the same origin have
    different chunk sizes by sorting the internal list of snapshots by chunk
    size, largest first.
      https://bugzilla.redhat.com/show_bug.cgi?id=182659
    
    For example, let's have two snapshots with different chunk sizes. The
    first snapshot (1) has small chunk size and the second snapshot (2) has
    large chunk size.  Let's have chunks A, B, C in these snapshots:
    snapshot1: ====A====   ====B====
    snapshot2: ==========C==========
    
    (Chunk size is a power of 2. Chunks are aligned.)
    
    A write to the origin at a position within A and C comes along. It
    triggers reallocation of A, then reallocation of C and links them
    together using A as the 'primary' exception.
    
    Then another write to the origin comes along at a position within B and
    C.  It creates pending exception for B.  C already has a reallocation in
    progress and it already has a primary exception (A), so nothing is done
    to it: B and C are not linked.
    
    If the reallocation of B finishes before the reallocation of C, because
    there is no link with the pending exception for C it does not know to
    wait for it and, the second write is dispatched to the origin and causes
    data corruption in the chunk C in snapshot2.
    
    To avoid this situation, we maintain snapshots sorted in descending
    order of chunk size.  This leads to a guaranteed ordering on the links
    between the pending exceptions and avoids the problem explained above -
    both A and B now get linked to C.
    
    Cc: stable@kernel.org
    Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
    Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
    6d45d93e
dm-snap.c 33.8 KB