Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 40823
b: refs/heads/master
c: 3318404
h: refs/heads/master
i:
  40821: 0af7bb4
  40819: 2decabf
  40815: ef2864c
v: v3
  • Loading branch information
Jonathan E Brassow authored and Linus Torvalds committed Nov 9, 2006
1 parent e2d8235 commit 5f07555
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 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: 5d55fdf94998db1df9ee7f1def8806bfd0e5ff73
refs/heads/master: 33184048dc4f9d5550d3b6a88c8e0ff92033eb6e
22 changes: 21 additions & 1 deletion trunk/drivers/md/dm-raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

static struct workqueue_struct *_kmirrord_wq;
static struct work_struct _kmirrord_work;
static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);

static inline void wake(void)
{
Expand Down Expand Up @@ -83,6 +84,7 @@ struct region_hash {
struct list_head *buckets;

spinlock_t region_lock;
atomic_t recovery_in_flight;
struct semaphore recovery_count;
struct list_head clean_regions;
struct list_head quiesced_regions;
Expand Down Expand Up @@ -191,6 +193,7 @@ static int rh_init(struct region_hash *rh, struct mirror_set *ms,

spin_lock_init(&rh->region_lock);
sema_init(&rh->recovery_count, 0);
atomic_set(&rh->recovery_in_flight, 0);
INIT_LIST_HEAD(&rh->clean_regions);
INIT_LIST_HEAD(&rh->quiesced_regions);
INIT_LIST_HEAD(&rh->recovered_regions);
Expand Down Expand Up @@ -382,6 +385,8 @@ static void rh_update_states(struct region_hash *rh)
rh->log->type->clear_region(rh->log, reg->key);
rh->log->type->complete_resync_work(rh->log, reg->key, 1);
dispatch_bios(rh->ms, &reg->delayed_bios);
if (atomic_dec_and_test(&rh->recovery_in_flight))
wake_up_all(&_kmirrord_recovery_stopped);
up(&rh->recovery_count);
mempool_free(reg, rh->region_pool);
}
Expand Down Expand Up @@ -502,11 +507,21 @@ static int __rh_recovery_prepare(struct region_hash *rh)

static void rh_recovery_prepare(struct region_hash *rh)
{
while (!down_trylock(&rh->recovery_count))
/* Extra reference to avoid race with rh_stop_recovery */
atomic_inc(&rh->recovery_in_flight);

while (!down_trylock(&rh->recovery_count)) {
atomic_inc(&rh->recovery_in_flight);
if (__rh_recovery_prepare(rh) <= 0) {
atomic_dec(&rh->recovery_in_flight);
up(&rh->recovery_count);
break;
}
}

/* Drop the extra reference */
if (atomic_dec_and_test(&rh->recovery_in_flight))
wake_up_all(&_kmirrord_recovery_stopped);
}

/*
Expand Down Expand Up @@ -1177,6 +1192,11 @@ static void mirror_postsuspend(struct dm_target *ti)
struct dirty_log *log = ms->rh.log;

rh_stop_recovery(&ms->rh);

/* Wait for all I/O we generated to complete */
wait_event(_kmirrord_recovery_stopped,
!atomic_read(&ms->rh.recovery_in_flight));

if (log->type->suspend && log->type->suspend(log))
/* FIXME: need better error handling */
DMWARN("log suspend failed");
Expand Down

0 comments on commit 5f07555

Please sign in to comment.