diff options
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index e2943fb74056..e9e3308cb0a7 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -854,7 +854,7 @@ static void flush_pending_writes(struct r1conf *conf) | |||
| 854 | * there is no normal IO happeing. It must arrange to call | 854 | * there is no normal IO happeing. It must arrange to call |
| 855 | * lower_barrier when the particular background IO completes. | 855 | * lower_barrier when the particular background IO completes. |
| 856 | */ | 856 | */ |
| 857 | static void raise_barrier(struct r1conf *conf, sector_t sector_nr) | 857 | static sector_t raise_barrier(struct r1conf *conf, sector_t sector_nr) |
| 858 | { | 858 | { |
| 859 | int idx = sector_to_idx(sector_nr); | 859 | int idx = sector_to_idx(sector_nr); |
| 860 | 860 | ||
| @@ -885,13 +885,23 @@ static void raise_barrier(struct r1conf *conf, sector_t sector_nr) | |||
| 885 | * max resync count which allowed on current I/O barrier bucket. | 885 | * max resync count which allowed on current I/O barrier bucket. |
| 886 | */ | 886 | */ |
| 887 | wait_event_lock_irq(conf->wait_barrier, | 887 | wait_event_lock_irq(conf->wait_barrier, |
| 888 | !conf->array_frozen && | 888 | (!conf->array_frozen && |
| 889 | !atomic_read(&conf->nr_pending[idx]) && | 889 | !atomic_read(&conf->nr_pending[idx]) && |
| 890 | atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH, | 890 | atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH) || |
| 891 | test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery), | ||
| 891 | conf->resync_lock); | 892 | conf->resync_lock); |
| 892 | 893 | ||
| 894 | if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { | ||
| 895 | atomic_dec(&conf->barrier[idx]); | ||
| 896 | spin_unlock_irq(&conf->resync_lock); | ||
| 897 | wake_up(&conf->wait_barrier); | ||
| 898 | return -EINTR; | ||
| 899 | } | ||
| 900 | |||
| 893 | atomic_inc(&conf->nr_sync_pending); | 901 | atomic_inc(&conf->nr_sync_pending); |
| 894 | spin_unlock_irq(&conf->resync_lock); | 902 | spin_unlock_irq(&conf->resync_lock); |
| 903 | |||
| 904 | return 0; | ||
| 895 | } | 905 | } |
| 896 | 906 | ||
| 897 | static void lower_barrier(struct r1conf *conf, sector_t sector_nr) | 907 | static void lower_barrier(struct r1conf *conf, sector_t sector_nr) |
| @@ -1092,6 +1102,8 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio, | |||
| 1092 | goto skip_copy; | 1102 | goto skip_copy; |
| 1093 | } | 1103 | } |
| 1094 | 1104 | ||
| 1105 | behind_bio->bi_write_hint = bio->bi_write_hint; | ||
| 1106 | |||
| 1095 | while (i < vcnt && size) { | 1107 | while (i < vcnt && size) { |
| 1096 | struct page *page; | 1108 | struct page *page; |
| 1097 | int len = min_t(int, PAGE_SIZE, size); | 1109 | int len = min_t(int, PAGE_SIZE, size); |
| @@ -2662,9 +2674,12 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, | |||
| 2662 | 2674 | ||
| 2663 | bitmap_cond_end_sync(mddev->bitmap, sector_nr, | 2675 | bitmap_cond_end_sync(mddev->bitmap, sector_nr, |
| 2664 | mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high)); | 2676 | mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high)); |
| 2665 | r1_bio = raid1_alloc_init_r1buf(conf); | ||
| 2666 | 2677 | ||
| 2667 | raise_barrier(conf, sector_nr); | 2678 | |
| 2679 | if (raise_barrier(conf, sector_nr)) | ||
| 2680 | return 0; | ||
| 2681 | |||
| 2682 | r1_bio = raid1_alloc_init_r1buf(conf); | ||
| 2668 | 2683 | ||
| 2669 | rcu_read_lock(); | 2684 | rcu_read_lock(); |
| 2670 | /* | 2685 | /* |
