• I
    Btrfs: fix the dev-replace suspend sequence · 539f358a
    Ilya Dryomov 提交于
    Replace progresses strictly from lower to higher offsets, and the
    progress is tracked in chunks, by storing the physical offset of the
    dev_extent which is being copied in the cursor_left field of
    btrfs_dev_replace_item.  When we are done copying the chunk,
    left_cursor is updated to point one byte past the dev_extent, so that
    on resume we can skip the dev_extents that have already been copied.
    
    There is a major bug (which goes all the way back to the inception of
    dev-replace in 3.8) in the way left_cursor is bumped: the bump is done
    unconditionally, without any regard to the scrub_chunk return value.
    On suspend (and also on any kind of error) scrub_chunk returns early,
    i.e. without completing the copy.  This leads to us skipping the chunk
    that hasn't been fully copied yet when resuming.
    
    Fix this by doing the cursor_left update only if scrub_chunk ret is 0.
    (On suspend scrub_chunk returns with -ECANCELED, so this fix covers
    both suspend and error cases.)
    
    Cc: Stefan Behrens <sbehrens@giantdisaster.de>
    Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
    Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
    Signed-off-by: NChris Mason <chris.mason@fusionio.com>
    539f358a
scrub.c 91.6 KB