diff options
-rw-r--r-- | drivers/md/dm-raid1.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 2375709a392c..6b0fc1670929 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -376,16 +376,18 @@ static void rh_inc(struct region_hash *rh, region_t region) | |||
376 | read_lock(&rh->hash_lock); | 376 | read_lock(&rh->hash_lock); |
377 | reg = __rh_find(rh, region); | 377 | reg = __rh_find(rh, region); |
378 | 378 | ||
379 | spin_lock_irq(&rh->region_lock); | ||
379 | atomic_inc(®->pending); | 380 | atomic_inc(®->pending); |
380 | 381 | ||
381 | spin_lock_irq(&rh->region_lock); | ||
382 | if (reg->state == RH_CLEAN) { | 382 | if (reg->state == RH_CLEAN) { |
383 | rh->log->type->mark_region(rh->log, reg->key); | ||
384 | |||
385 | reg->state = RH_DIRTY; | 383 | reg->state = RH_DIRTY; |
386 | list_del_init(®->list); /* take off the clean list */ | 384 | list_del_init(®->list); /* take off the clean list */ |
387 | } | 385 | spin_unlock_irq(&rh->region_lock); |
388 | spin_unlock_irq(&rh->region_lock); | 386 | |
387 | rh->log->type->mark_region(rh->log, reg->key); | ||
388 | } else | ||
389 | spin_unlock_irq(&rh->region_lock); | ||
390 | |||
389 | 391 | ||
390 | read_unlock(&rh->hash_lock); | 392 | read_unlock(&rh->hash_lock); |
391 | } | 393 | } |
@@ -408,21 +410,17 @@ static void rh_dec(struct region_hash *rh, region_t region) | |||
408 | reg = __rh_lookup(rh, region); | 410 | reg = __rh_lookup(rh, region); |
409 | read_unlock(&rh->hash_lock); | 411 | read_unlock(&rh->hash_lock); |
410 | 412 | ||
413 | spin_lock_irqsave(&rh->region_lock, flags); | ||
411 | if (atomic_dec_and_test(®->pending)) { | 414 | if (atomic_dec_and_test(®->pending)) { |
412 | spin_lock_irqsave(&rh->region_lock, flags); | ||
413 | if (atomic_read(®->pending)) { /* check race */ | ||
414 | spin_unlock_irqrestore(&rh->region_lock, flags); | ||
415 | return; | ||
416 | } | ||
417 | if (reg->state == RH_RECOVERING) { | 415 | if (reg->state == RH_RECOVERING) { |
418 | list_add_tail(®->list, &rh->quiesced_regions); | 416 | list_add_tail(®->list, &rh->quiesced_regions); |
419 | } else { | 417 | } else { |
420 | reg->state = RH_CLEAN; | 418 | reg->state = RH_CLEAN; |
421 | list_add(®->list, &rh->clean_regions); | 419 | list_add(®->list, &rh->clean_regions); |
422 | } | 420 | } |
423 | spin_unlock_irqrestore(&rh->region_lock, flags); | ||
424 | should_wake = 1; | 421 | should_wake = 1; |
425 | } | 422 | } |
423 | spin_unlock_irqrestore(&rh->region_lock, flags); | ||
426 | 424 | ||
427 | if (should_wake) | 425 | if (should_wake) |
428 | wake(); | 426 | wake(); |