aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-snap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r--drivers/md/dm-snap.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 7401540086df..874f145431d8 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -49,6 +49,11 @@ struct pending_exception {
49 struct bio_list snapshot_bios; 49 struct bio_list snapshot_bios;
50 50
51 /* 51 /*
52 * Short-term queue of pending exceptions prior to submission.
53 */
54 struct list_head list;
55
56 /*
52 * Other pending_exceptions that are processing this 57 * Other pending_exceptions that are processing this
53 * chunk. When this list is empty, we know we can 58 * chunk. When this list is empty, we know we can
54 * complete the origins. 59 * complete the origins.
@@ -930,8 +935,9 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
930 int r = 1, first = 1; 935 int r = 1, first = 1;
931 struct dm_snapshot *snap; 936 struct dm_snapshot *snap;
932 struct exception *e; 937 struct exception *e;
933 struct pending_exception *pe, *last = NULL; 938 struct pending_exception *pe, *next_pe, *last = NULL;
934 chunk_t chunk; 939 chunk_t chunk;
940 LIST_HEAD(pe_queue);
935 941
936 /* Do all the snapshots on this origin */ 942 /* Do all the snapshots on this origin */
937 list_for_each_entry (snap, snapshots, list) { 943 list_for_each_entry (snap, snapshots, list) {
@@ -965,12 +971,19 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
965 snap->valid = 0; 971 snap->valid = 0;
966 972
967 } else { 973 } else {
968 if (last) 974 if (first) {
975 bio_list_add(&pe->origin_bios, bio);
976 r = 0;
977 first = 0;
978 }
979 if (last && list_empty(&pe->siblings))
969 list_merge(&pe->siblings, 980 list_merge(&pe->siblings,
970 &last->siblings); 981 &last->siblings);
971 982 if (!pe->started) {
983 pe->started = 1;
984 list_add_tail(&pe->list, &pe_queue);
985 }
972 last = pe; 986 last = pe;
973 r = 0;
974 } 987 }
975 } 988 }
976 989
@@ -980,24 +993,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
980 /* 993 /*
981 * Now that we have a complete pe list we can start the copying. 994 * Now that we have a complete pe list we can start the copying.
982 */ 995 */
983 if (last) { 996 list_for_each_entry_safe(pe, next_pe, &pe_queue, list)
984 pe = last; 997 start_copy(pe);
985 do {
986 down_write(&pe->snap->lock);
987 if (first)
988 bio_list_add(&pe->origin_bios, bio);
989 if (!pe->started) {
990 pe->started = 1;
991 up_write(&pe->snap->lock);
992 start_copy(pe);
993 } else
994 up_write(&pe->snap->lock);
995 first = 0;
996 pe = list_entry(pe->siblings.next,
997 struct pending_exception, siblings);
998
999 } while (pe != last);
1000 }
1001 998
1002 return r; 999 return r;
1003} 1000}