Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 186435
b: refs/heads/master
c: f070304
h: refs/heads/master
i:
  186433: 97eb02f
  186431: 4d345f0
v: v3
  • Loading branch information
Takahiro Yasui authored and Alasdair G Kergon committed Mar 6, 2010
1 parent 53ea9e2 commit 51fc596
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 19 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: 924e600d417ead9ef67043988055ba236f114718
refs/heads/master: f070304094edb8d516423e79edd27c97ec2020b0
41 changes: 23 additions & 18 deletions trunk/drivers/md/dm-raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,17 @@ static void map_region(struct dm_io_region *io, struct mirror *m,
static void hold_bio(struct mirror_set *ms, struct bio *bio)
{
/*
* If device is suspended, complete the bio.
* Lock is required to avoid race condition during suspend
* process.
*/
spin_lock_irq(&ms->lock);

if (atomic_read(&ms->suspend)) {
spin_unlock_irq(&ms->lock);

/*
* If device is suspended, complete the bio.
*/
if (dm_noflush_suspending(ms->ti))
bio_endio(bio, DM_ENDIO_REQUEUE);
else
Expand All @@ -478,7 +486,6 @@ static void hold_bio(struct mirror_set *ms, struct bio *bio)
/*
* Hold bio until the suspend is complete.
*/
spin_lock_irq(&ms->lock);
bio_list_add(&ms->holds, bio);
spin_unlock_irq(&ms->lock);
}
Expand Down Expand Up @@ -1260,6 +1267,20 @@ static void mirror_presuspend(struct dm_target *ti)

atomic_set(&ms->suspend, 1);

/*
* Process bios in the hold list to start recovery waiting
* for bios in the hold list. After the process, no bio has
* a chance to be added in the hold list because ms->suspend
* is set.
*/
spin_lock_irq(&ms->lock);
holds = ms->holds;
bio_list_init(&ms->holds);
spin_unlock_irq(&ms->lock);

while ((bio = bio_list_pop(&holds)))
hold_bio(ms, bio);

/*
* We must finish up all the work that we've
* generated (i.e. recovery work).
Expand All @@ -1280,22 +1301,6 @@ static void mirror_presuspend(struct dm_target *ti)
* we know that all of our I/O has been pushed.
*/
flush_workqueue(ms->kmirrord_wq);

/*
* Now set ms->suspend is set and the workqueue flushed, no more
* entries can be added to ms->hold list, so process it.
*
* Bios can still arrive concurrently with or after this
* presuspend function, but they cannot join the hold list
* because ms->suspend is set.
*/
spin_lock_irq(&ms->lock);
holds = ms->holds;
bio_list_init(&ms->holds);
spin_unlock_irq(&ms->lock);

while ((bio = bio_list_pop(&holds)))
hold_bio(ms, bio);
}

static void mirror_postsuspend(struct dm_target *ti)
Expand Down

0 comments on commit 51fc596

Please sign in to comment.