aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlasdair G Kergon <agk@redhat.com>2006-10-03 04:15:31 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-03 11:04:15 -0400
commit695368ac3302174531429a90d55c3f7f9b83906e (patch)
tree515457b78ec2bf95dab7f5b614284ccecda8afbd
parent4b832e8de22726206eb886f6dbff47a0f3fe5168 (diff)
[PATCH] dm snapshot: fix freeing pending exception
If a snapshot became invalid while there are outstanding pending_exceptions, when pending_complete() processes each one it forgets to remove the corresponding exception from its exception table before freeing it. Fix this by moving the 'out:' label up one statement so that remove_exception() is always called. Then __invalidate_exception() no longer needs to call it and its 'pe' argument become superfluous. Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/dm-snap.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 638c8d90da0e..5281e0094072 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -631,8 +631,7 @@ static void error_bios(struct bio *bio)
631 } 631 }
632} 632}
633 633
634static void __invalidate_snapshot(struct dm_snapshot *s, 634static void __invalidate_snapshot(struct dm_snapshot *s, int err)
635 struct pending_exception *pe, int err)
636{ 635{
637 if (!s->valid) 636 if (!s->valid)
638 return; 637 return;
@@ -642,9 +641,6 @@ static void __invalidate_snapshot(struct dm_snapshot *s,
642 else if (err == -ENOMEM) 641 else if (err == -ENOMEM)
643 DMERR("Invalidating snapshot: Unable to allocate exception."); 642 DMERR("Invalidating snapshot: Unable to allocate exception.");
644 643
645 if (pe)
646 remove_exception(&pe->e);
647
648 if (s->store.drop_snapshot) 644 if (s->store.drop_snapshot)
649 s->store.drop_snapshot(&s->store); 645 s->store.drop_snapshot(&s->store);
650 646
@@ -701,7 +697,7 @@ static void pending_complete(struct pending_exception *pe, int success)
701 if (!success) { 697 if (!success) {
702 /* Read/write error - snapshot is unusable */ 698 /* Read/write error - snapshot is unusable */
703 down_write(&s->lock); 699 down_write(&s->lock);
704 __invalidate_snapshot(s, pe, -EIO); 700 __invalidate_snapshot(s, -EIO);
705 error = 1; 701 error = 1;
706 goto out; 702 goto out;
707 } 703 }
@@ -709,7 +705,7 @@ static void pending_complete(struct pending_exception *pe, int success)
709 e = alloc_exception(); 705 e = alloc_exception();
710 if (!e) { 706 if (!e) {
711 down_write(&s->lock); 707 down_write(&s->lock);
712 __invalidate_snapshot(s, pe, -ENOMEM); 708 __invalidate_snapshot(s, -ENOMEM);
713 error = 1; 709 error = 1;
714 goto out; 710 goto out;
715 } 711 }
@@ -727,9 +723,9 @@ static void pending_complete(struct pending_exception *pe, int success)
727 * in-flight exception from the list. 723 * in-flight exception from the list.
728 */ 724 */
729 insert_exception(&s->complete, e); 725 insert_exception(&s->complete, e);
730 remove_exception(&pe->e);
731 726
732 out: 727 out:
728 remove_exception(&pe->e);
733 snapshot_bios = bio_list_get(&pe->snapshot_bios); 729 snapshot_bios = bio_list_get(&pe->snapshot_bios);
734 origin_bios = put_pending_exception(pe); 730 origin_bios = put_pending_exception(pe);
735 731
@@ -909,7 +905,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
909 if (bio_rw(bio) == WRITE) { 905 if (bio_rw(bio) == WRITE) {
910 pe = __find_pending_exception(s, bio); 906 pe = __find_pending_exception(s, bio);
911 if (!pe) { 907 if (!pe) {
912 __invalidate_snapshot(s, pe, -ENOMEM); 908 __invalidate_snapshot(s, -ENOMEM);
913 r = -EIO; 909 r = -EIO;
914 goto out_unlock; 910 goto out_unlock;
915 } 911 }
@@ -1035,7 +1031,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
1035 1031
1036 pe = __find_pending_exception(snap, bio); 1032 pe = __find_pending_exception(snap, bio);
1037 if (!pe) { 1033 if (!pe) {
1038 __invalidate_snapshot(snap, pe, -ENOMEM); 1034 __invalidate_snapshot(snap, -ENOMEM);
1039 goto next_snapshot; 1035 goto next_snapshot;
1040 } 1036 }
1041 1037