|
@@ -362,7 +362,7 @@ static void raid5_unplug_device(struct request_queue *q);
|
|
|
|
|
|
static struct stripe_head *
|
|
static struct stripe_head *
|
|
get_active_stripe(raid5_conf_t *conf, sector_t sector,
|
|
get_active_stripe(raid5_conf_t *conf, sector_t sector,
|
|
- int previous, int noblock)
|
|
|
|
|
|
+ int previous, int noblock, int noquiesce)
|
|
{
|
|
{
|
|
struct stripe_head *sh;
|
|
struct stripe_head *sh;
|
|
|
|
|
|
@@ -372,7 +372,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector,
|
|
|
|
|
|
do {
|
|
do {
|
|
wait_event_lock_irq(conf->wait_for_stripe,
|
|
wait_event_lock_irq(conf->wait_for_stripe,
|
|
- conf->quiesce == 0,
|
|
|
|
|
|
+ conf->quiesce == 0 || noquiesce,
|
|
conf->device_lock, /* nothing */);
|
|
conf->device_lock, /* nothing */);
|
|
sh = __find_stripe(conf, sector, conf->generation - previous);
|
|
sh = __find_stripe(conf, sector, conf->generation - previous);
|
|
if (!sh) {
|
|
if (!sh) {
|
|
@@ -2671,7 +2671,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
|
|
sector_t bn = compute_blocknr(sh, i, 1);
|
|
sector_t bn = compute_blocknr(sh, i, 1);
|
|
sector_t s = raid5_compute_sector(conf, bn, 0,
|
|
sector_t s = raid5_compute_sector(conf, bn, 0,
|
|
&dd_idx, NULL);
|
|
&dd_idx, NULL);
|
|
- sh2 = get_active_stripe(conf, s, 0, 1);
|
|
|
|
|
|
+ sh2 = get_active_stripe(conf, s, 0, 1, 1);
|
|
if (sh2 == NULL)
|
|
if (sh2 == NULL)
|
|
/* so far only the early blocks of this stripe
|
|
/* so far only the early blocks of this stripe
|
|
* have been requested. When later blocks
|
|
* have been requested. When later blocks
|
|
@@ -2944,7 +2944,7 @@ static bool handle_stripe5(struct stripe_head *sh)
|
|
/* Finish reconstruct operations initiated by the expansion process */
|
|
/* Finish reconstruct operations initiated by the expansion process */
|
|
if (sh->reconstruct_state == reconstruct_state_result) {
|
|
if (sh->reconstruct_state == reconstruct_state_result) {
|
|
struct stripe_head *sh2
|
|
struct stripe_head *sh2
|
|
- = get_active_stripe(conf, sh->sector, 1, 1);
|
|
|
|
|
|
+ = get_active_stripe(conf, sh->sector, 1, 1, 1);
|
|
if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
|
|
if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
|
|
/* sh cannot be written until sh2 has been read.
|
|
/* sh cannot be written until sh2 has been read.
|
|
* so arrange for sh to be delayed a little
|
|
* so arrange for sh to be delayed a little
|
|
@@ -3189,7 +3189,7 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
|
|
|
|
|
|
if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
|
|
if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
|
|
struct stripe_head *sh2
|
|
struct stripe_head *sh2
|
|
- = get_active_stripe(conf, sh->sector, 1, 1);
|
|
|
|
|
|
+ = get_active_stripe(conf, sh->sector, 1, 1, 1);
|
|
if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
|
|
if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
|
|
/* sh cannot be written until sh2 has been read.
|
|
/* sh cannot be written until sh2 has been read.
|
|
* so arrange for sh to be delayed a little
|
|
* so arrange for sh to be delayed a little
|
|
@@ -3675,7 +3675,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
|
|
(unsigned long long)logical_sector);
|
|
(unsigned long long)logical_sector);
|
|
|
|
|
|
sh = get_active_stripe(conf, new_sector, previous,
|
|
sh = get_active_stripe(conf, new_sector, previous,
|
|
- (bi->bi_rw&RWA_MASK));
|
|
|
|
|
|
+ (bi->bi_rw&RWA_MASK), 0);
|
|
if (sh) {
|
|
if (sh) {
|
|
if (unlikely(previous)) {
|
|
if (unlikely(previous)) {
|
|
/* expansion might have moved on while waiting for a
|
|
/* expansion might have moved on while waiting for a
|
|
@@ -3873,7 +3873,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
|
|
for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
|
|
for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
|
|
int j;
|
|
int j;
|
|
int skipped = 0;
|
|
int skipped = 0;
|
|
- sh = get_active_stripe(conf, stripe_addr+i, 0, 0);
|
|
|
|
|
|
+ sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1);
|
|
set_bit(STRIPE_EXPANDING, &sh->state);
|
|
set_bit(STRIPE_EXPANDING, &sh->state);
|
|
atomic_inc(&conf->reshape_stripes);
|
|
atomic_inc(&conf->reshape_stripes);
|
|
/* If any of this stripe is beyond the end of the old
|
|
/* If any of this stripe is beyond the end of the old
|
|
@@ -3922,7 +3922,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
|
|
if (last_sector >= mddev->dev_sectors)
|
|
if (last_sector >= mddev->dev_sectors)
|
|
last_sector = mddev->dev_sectors - 1;
|
|
last_sector = mddev->dev_sectors - 1;
|
|
while (first_sector <= last_sector) {
|
|
while (first_sector <= last_sector) {
|
|
- sh = get_active_stripe(conf, first_sector, 1, 0);
|
|
|
|
|
|
+ sh = get_active_stripe(conf, first_sector, 1, 0, 1);
|
|
set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
|
|
set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
|
|
set_bit(STRIPE_HANDLE, &sh->state);
|
|
set_bit(STRIPE_HANDLE, &sh->state);
|
|
release_stripe(sh);
|
|
release_stripe(sh);
|
|
@@ -4022,9 +4022,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
|
|
|
|
|
|
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
|
|
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
|
|
|
|
|
|
- sh = get_active_stripe(conf, sector_nr, 0, 1);
|
|
|
|
|
|
+ sh = get_active_stripe(conf, sector_nr, 0, 1, 0);
|
|
if (sh == NULL) {
|
|
if (sh == NULL) {
|
|
- sh = get_active_stripe(conf, sector_nr, 0, 0);
|
|
|
|
|
|
+ sh = get_active_stripe(conf, sector_nr, 0, 0, 0);
|
|
/* make sure we don't swamp the stripe cache if someone else
|
|
/* make sure we don't swamp the stripe cache if someone else
|
|
* is trying to get access
|
|
* is trying to get access
|
|
*/
|
|
*/
|
|
@@ -4086,7 +4086,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
|
|
/* already done this stripe */
|
|
/* already done this stripe */
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- sh = get_active_stripe(conf, sector, 0, 1);
|
|
|
|
|
|
+ sh = get_active_stripe(conf, sector, 0, 1, 0);
|
|
|
|
|
|
if (!sh) {
|
|
if (!sh) {
|
|
/* failed to get a stripe - must wait */
|
|
/* failed to get a stripe - must wait */
|