Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 260986
b: refs/heads/master
c: 8478955
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown committed Jul 27, 2011
1 parent c443ef5 commit 27bda02
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 101 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c8ac1803ff0af5aa614587ac0c66d46b7a3bdfcc
refs/heads/master: 84789554e96c0263ad8aa9be91397ece1f88c768
161 changes: 61 additions & 100 deletions trunk/drivers/md/raid5.c
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
/*
* Select the parity disk based on the user selected algorithm.
*/
pd_idx = qd_idx = ~0;
pd_idx = qd_idx = -1;
switch(conf->level) {
case 4:
pd_idx = data_disks;
Expand Down Expand Up @@ -2903,7 +2903,6 @@ static int handle_stripe5(struct stripe_head *sh, struct stripe_head_state *s)
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
struct r5dev *dev;
int prexor;

/* Now to look around and see what can be done */
rcu_read_lock();
Expand Down Expand Up @@ -3026,56 +3025,6 @@ static int handle_stripe5(struct stripe_head *sh, struct stripe_head_state *s)
(s->syncing && (s->uptodate + s->compute < disks)) || s->expanding)
handle_stripe_fill(sh, s, disks);

/* Now we check to see if any write operations have recently
* completed
*/
prexor = 0;
if (sh->reconstruct_state == reconstruct_state_prexor_drain_result)
prexor = 1;
if (sh->reconstruct_state == reconstruct_state_drain_result ||
sh->reconstruct_state == reconstruct_state_prexor_drain_result) {
sh->reconstruct_state = reconstruct_state_idle;

/* All the 'written' buffers and the parity block are ready to
* be written back to disk
*/
BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags));
for (i = disks; i--; ) {
dev = &sh->dev[i];
if (test_bit(R5_LOCKED, &dev->flags) &&
(i == sh->pd_idx || dev->written)) {
pr_debug("Writing block %d\n", i);
set_bit(R5_Wantwrite, &dev->flags);
if (prexor)
continue;
if (!test_bit(R5_Insync, &dev->flags) ||
(i == sh->pd_idx && s->failed == 0))
set_bit(STRIPE_INSYNC, &sh->state);
}
}
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
s->dec_preread_active = 1;
}

/* Now to consider new write requests and what else, if anything
* should be read. We do not handle new writes when:
* 1/ A 'write' operation (copy+xor) is already in flight.
* 2/ A 'check' operation is in flight, as it may clobber the parity
* block.
*/
if (s->to_write && !sh->reconstruct_state && !sh->check_state)
handle_stripe_dirtying(conf, sh, s, disks);

/* maybe we need to check and possibly fix the parity for this stripe
* Any reads will already have been scheduled, so we just see if enough
* data is available. The parity check is held off while parity
* dependent operations are in flight.
*/
if (sh->check_state ||
(s->syncing && s->locked == 0 &&
!test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
!test_bit(STRIPE_INSYNC, &sh->state)))
handle_parity_checks5(conf, sh, s, disks);
return 0;
}

Expand Down Expand Up @@ -3217,54 +3166,6 @@ static int handle_stripe6(struct stripe_head *sh, struct stripe_head_state *s)
(s->syncing && (s->uptodate + s->compute < disks)) || s->expanding)
handle_stripe_fill(sh, s, disks);

/* Now we check to see if any write operations have recently
* completed
*/
if (sh->reconstruct_state == reconstruct_state_drain_result) {

sh->reconstruct_state = reconstruct_state_idle;
/* All the 'written' buffers and the parity blocks are ready to
* be written back to disk
*/
BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags));
BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[qd_idx].flags));
for (i = disks; i--; ) {
dev = &sh->dev[i];
if (test_bit(R5_LOCKED, &dev->flags) &&
(i == sh->pd_idx || i == qd_idx ||
dev->written)) {
pr_debug("Writing block %d\n", i);
BUG_ON(!test_bit(R5_UPTODATE, &dev->flags));
set_bit(R5_Wantwrite, &dev->flags);
if (!test_bit(R5_Insync, &dev->flags) ||
((i == sh->pd_idx || i == qd_idx) &&
s->failed == 0))
set_bit(STRIPE_INSYNC, &sh->state);
}
}
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
s->dec_preread_active = 1;
}

/* Now to consider new write requests and what else, if anything
* should be read. We do not handle new writes when:
* 1/ A 'write' operation (copy+gen_syndrome) is already in flight.
* 2/ A 'check' operation is in flight, as it may clobber the parity
* block.
*/
if (s->to_write && !sh->reconstruct_state && !sh->check_state)
handle_stripe_dirtying(conf, sh, s, disks);

/* maybe we need to check and possibly fix the parity for this stripe
* Any reads will already have been scheduled, so we just see if enough
* data is available. The parity check is held off while parity
* dependent operations are in flight.
*/
if (sh->check_state ||
(s->syncing && s->locked == 0 &&
!test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
!test_bit(STRIPE_INSYNC, &sh->state)))
handle_parity_checks6(conf, sh, s, disks);
return 0;
}

Expand All @@ -3273,6 +3174,8 @@ static void handle_stripe(struct stripe_head *sh)
struct stripe_head_state s;
int done;
int i;
int prexor;
int disks = sh->disks;
raid5_conf_t *conf = sh->raid_conf;

clear_bit(STRIPE_HANDLE, &sh->state);
Expand Down Expand Up @@ -3310,6 +3213,64 @@ static void handle_stripe(struct stripe_head *sh)
if (done)
goto finish;

/* Now we check to see if any write operations have recently
* completed
*/
prexor = 0;
if (sh->reconstruct_state == reconstruct_state_prexor_drain_result)
prexor = 1;
if (sh->reconstruct_state == reconstruct_state_drain_result ||
sh->reconstruct_state == reconstruct_state_prexor_drain_result) {
sh->reconstruct_state = reconstruct_state_idle;

/* All the 'written' buffers and the parity block are ready to
* be written back to disk
*/
BUG_ON(!test_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags));
BUG_ON(sh->qd_idx >= 0 &&
!test_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags));
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
if (test_bit(R5_LOCKED, &dev->flags) &&
(i == sh->pd_idx || i == sh->qd_idx ||
dev->written)) {
pr_debug("Writing block %d\n", i);
set_bit(R5_Wantwrite, &dev->flags);
if (prexor)
continue;
if (!test_bit(R5_Insync, &dev->flags) ||
((i == sh->pd_idx || i == sh->qd_idx) &&
s.failed == 0))
set_bit(STRIPE_INSYNC, &sh->state);
}
}
if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state))
s.dec_preread_active = 1;
}

/* Now to consider new write requests and what else, if anything
* should be read. We do not handle new writes when:
* 1/ A 'write' operation (copy+xor) is already in flight.
* 2/ A 'check' operation is in flight, as it may clobber the parity
* block.
*/
if (s.to_write && !sh->reconstruct_state && !sh->check_state)
handle_stripe_dirtying(conf, sh, &s, disks);

/* maybe we need to check and possibly fix the parity for this stripe
* Any reads will already have been scheduled, so we just see if enough
* data is available. The parity check is held off while parity
* dependent operations are in flight.
*/
if (sh->check_state ||
(s.syncing && s.locked == 0 &&
!test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
!test_bit(STRIPE_INSYNC, &sh->state))) {
if (conf->level == 6)
handle_parity_checks6(conf, sh, &s, disks);
else
handle_parity_checks5(conf, sh, &s, disks);
}

if (s.syncing && s.locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
Expand Down

0 comments on commit 27bda02

Please sign in to comment.