Btrfs: fix the dev-replace suspend sequence
authorIlya Dryomov <idryomov@gmail.com>
Mon, 7 Oct 2013 10:42:57 +0000 (13:42 +0300)
committerChris Mason <chris.mason@fusionio.com>
Tue, 12 Nov 2013 02:55:36 +0000 (21:55 -0500)
commit539f358a30d5113bad81c41a2e7ba8770d6c9f6e
tree6b033dcb841d21d40a659196fba358437aa1b04d
parent778ba82b1796e75e719a52679ae431371ca73988
Btrfs: fix the dev-replace suspend sequence

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: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/scrub.c