diff options
| author | Liu Bo <bo.li.liu@oracle.com> | 2018-01-09 20:36:25 -0500 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2018-01-22 10:08:21 -0500 |
| commit | 7583d8d088ff2c323b1d4f15b191ca2c23d32558 (patch) | |
| tree | b43cabc0e98d36504ae3a786202491c48881f1f9 /fs/btrfs/raid56.c | |
| parent | 44ac474def527a9c595a88400f4717dacae03b8a (diff) | |
Btrfs: raid56: fix race between merge_bio and rbio_orig_end_io
Before rbio_orig_end_io() goes to free rbio, rbio may get merged with
more bios from other rbios and rbio->bio_list becomes non-empty,
in that case, these newly merged bios don't end properly.
Once unlock_stripe() is done, rbio->bio_list will not be updated any
more and we can call bio_endio() on all queued bios.
It should only happen in error-out cases, the normal path of recover
and full stripe write have already set RBIO_RMW_LOCKED_BIT to disable
merge before doing IO, so rbio_orig_end_io() called by them doesn't
have the above issue.
Reported-by: Jérôme Carretero <cJ-ko@zougloub.eu>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/raid56.c')
| -rw-r--r-- | fs/btrfs/raid56.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index 2f1ff7007280..dec0907dfb8a 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c | |||
| @@ -864,10 +864,17 @@ static void __free_raid_bio(struct btrfs_raid_bio *rbio) | |||
| 864 | kfree(rbio); | 864 | kfree(rbio); |
| 865 | } | 865 | } |
| 866 | 866 | ||
| 867 | static void free_raid_bio(struct btrfs_raid_bio *rbio) | 867 | static void rbio_endio_bio_list(struct bio *cur, blk_status_t err) |
| 868 | { | 868 | { |
| 869 | unlock_stripe(rbio); | 869 | struct bio *next; |
| 870 | __free_raid_bio(rbio); | 870 | |
| 871 | while (cur) { | ||
| 872 | next = cur->bi_next; | ||
| 873 | cur->bi_next = NULL; | ||
| 874 | cur->bi_status = err; | ||
| 875 | bio_endio(cur); | ||
| 876 | cur = next; | ||
| 877 | } | ||
| 871 | } | 878 | } |
| 872 | 879 | ||
| 873 | /* | 880 | /* |
| @@ -877,20 +884,26 @@ static void free_raid_bio(struct btrfs_raid_bio *rbio) | |||
| 877 | static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, blk_status_t err) | 884 | static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, blk_status_t err) |
| 878 | { | 885 | { |
| 879 | struct bio *cur = bio_list_get(&rbio->bio_list); | 886 | struct bio *cur = bio_list_get(&rbio->bio_list); |
| 880 | struct bio *next; | 887 | struct bio *extra; |
| 881 | 888 | ||
| 882 | if (rbio->generic_bio_cnt) | 889 | if (rbio->generic_bio_cnt) |
| 883 | btrfs_bio_counter_sub(rbio->fs_info, rbio->generic_bio_cnt); | 890 | btrfs_bio_counter_sub(rbio->fs_info, rbio->generic_bio_cnt); |
| 884 | 891 | ||
| 885 | free_raid_bio(rbio); | 892 | /* |
| 893 | * At this moment, rbio->bio_list is empty, however since rbio does not | ||
| 894 | * always have RBIO_RMW_LOCKED_BIT set and rbio is still linked on the | ||
| 895 | * hash list, rbio may be merged with others so that rbio->bio_list | ||
| 896 | * becomes non-empty. | ||
| 897 | * Once unlock_stripe() is done, rbio->bio_list will not be updated any | ||
| 898 | * more and we can call bio_endio() on all queued bios. | ||
| 899 | */ | ||
| 900 | unlock_stripe(rbio); | ||
| 901 | extra = bio_list_get(&rbio->bio_list); | ||
| 902 | __free_raid_bio(rbio); | ||
| 886 | 903 | ||
| 887 | while (cur) { | 904 | rbio_endio_bio_list(cur, err); |
| 888 | next = cur->bi_next; | 905 | if (extra) |
| 889 | cur->bi_next = NULL; | 906 | rbio_endio_bio_list(extra, err); |
| 890 | cur->bi_status = err; | ||
| 891 | bio_endio(cur); | ||
| 892 | cur = next; | ||
| 893 | } | ||
| 894 | } | 907 | } |
| 895 | 908 | ||
| 896 | /* | 909 | /* |
