The new iobarrier implementation in raid1 (which keeps normal writes and resync activity separate) counts every request what is not before the current resync point in either next_window_requests or current_window_requests. It flags that the request is counted by setting ->start_next_window. allow_barrier follows this model exactly and decrements one of the *_window_requests if and only if ->start_next_window is set. However wait_barrier(), which increments *_window_requests uses a slightly different test for setting -.start_next_window (which is set from the return value of this function). So there is a possibility of the counts getting out of sync, and this leads to the resync hanging. So change wait_barrier() to return a non-zero value in exactly the same cases that it increments *_window_requests. But was introduced in 3.13-rc1.
Unified · Split
| @@ -924,9 +924,8 @@ static sector_t wait_barrier(struct r1conf *conf, struct bio *bio) · 923 unmodified lines | ||
| 924 | 924 | conf->next_window_requests++; |
| 925 | 925 | else |
| 926 | 926 | conf->current_window_requests++; |
| 927 | − } | |
| 928 | − if (bio->bi_sector >= conf->start_next_window) | |
| 929 | 927 | sector = conf->start_next_window; |
| 928 | + } | |
| 930 | 929 | } |
| 931 | 930 | |
| 932 | 931 | conf->nr_pending++; |