diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm-snap.c | 155 |
1 files changed, 49 insertions, 106 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 446827f98236..c01e0dafec3c 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -142,28 +142,6 @@ struct dm_snap_pending_exception { | |||
142 | struct bio_list origin_bios; | 142 | struct bio_list origin_bios; |
143 | struct bio_list snapshot_bios; | 143 | struct bio_list snapshot_bios; |
144 | 144 | ||
145 | /* | ||
146 | * Short-term queue of pending exceptions prior to submission. | ||
147 | */ | ||
148 | struct list_head list; | ||
149 | |||
150 | /* | ||
151 | * The primary pending_exception is the one that holds | ||
152 | * the ref_count and the list of origin_bios for a | ||
153 | * group of pending_exceptions. It is always last to get freed. | ||
154 | * These fields get set up when writing to the origin. | ||
155 | */ | ||
156 | struct dm_snap_pending_exception *primary_pe; | ||
157 | |||
158 | /* | ||
159 | * Number of pending_exceptions processing this chunk. | ||
160 | * When this drops to zero we must complete the origin bios. | ||
161 | * If incrementing or decrementing this, hold pe->snap->lock for | ||
162 | * the sibling concerned and not pe->primary_pe->snap->lock unless | ||
163 | * they are the same. | ||
164 | */ | ||
165 | atomic_t ref_count; | ||
166 | |||
167 | /* Pointer back to snapshot context */ | 145 | /* Pointer back to snapshot context */ |
168 | struct dm_snapshot *snap; | 146 | struct dm_snapshot *snap; |
169 | 147 | ||
@@ -1019,6 +997,26 @@ static void flush_queued_bios(struct work_struct *work) | |||
1019 | flush_bios(queued_bios); | 997 | flush_bios(queued_bios); |
1020 | } | 998 | } |
1021 | 999 | ||
1000 | static int do_origin(struct dm_dev *origin, struct bio *bio); | ||
1001 | |||
1002 | /* | ||
1003 | * Flush a list of buffers. | ||
1004 | */ | ||
1005 | static void retry_origin_bios(struct dm_snapshot *s, struct bio *bio) | ||
1006 | { | ||
1007 | struct bio *n; | ||
1008 | int r; | ||
1009 | |||
1010 | while (bio) { | ||
1011 | n = bio->bi_next; | ||
1012 | bio->bi_next = NULL; | ||
1013 | r = do_origin(s->origin, bio); | ||
1014 | if (r == DM_MAPIO_REMAPPED) | ||
1015 | generic_make_request(bio); | ||
1016 | bio = n; | ||
1017 | } | ||
1018 | } | ||
1019 | |||
1022 | /* | 1020 | /* |
1023 | * Error a list of buffers. | 1021 | * Error a list of buffers. |
1024 | */ | 1022 | */ |
@@ -1052,39 +1050,6 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) | |||
1052 | dm_table_event(s->ti->table); | 1050 | dm_table_event(s->ti->table); |
1053 | } | 1051 | } |
1054 | 1052 | ||
1055 | static void get_pending_exception(struct dm_snap_pending_exception *pe) | ||
1056 | { | ||
1057 | atomic_inc(&pe->ref_count); | ||
1058 | } | ||
1059 | |||
1060 | static struct bio *put_pending_exception(struct dm_snap_pending_exception *pe) | ||
1061 | { | ||
1062 | struct dm_snap_pending_exception *primary_pe; | ||
1063 | struct bio *origin_bios = NULL; | ||
1064 | |||
1065 | primary_pe = pe->primary_pe; | ||
1066 | |||
1067 | /* | ||
1068 | * If this pe is involved in a write to the origin and | ||
1069 | * it is the last sibling to complete then release | ||
1070 | * the bios for the original write to the origin. | ||
1071 | */ | ||
1072 | if (primary_pe && | ||
1073 | atomic_dec_and_test(&primary_pe->ref_count)) { | ||
1074 | origin_bios = bio_list_get(&primary_pe->origin_bios); | ||
1075 | free_pending_exception(primary_pe); | ||
1076 | } | ||
1077 | |||
1078 | /* | ||
1079 | * Free the pe if it's not linked to an origin write or if | ||
1080 | * it's not itself a primary pe. | ||
1081 | */ | ||
1082 | if (!primary_pe || primary_pe != pe) | ||
1083 | free_pending_exception(pe); | ||
1084 | |||
1085 | return origin_bios; | ||
1086 | } | ||
1087 | |||
1088 | static void pending_complete(struct dm_snap_pending_exception *pe, int success) | 1053 | static void pending_complete(struct dm_snap_pending_exception *pe, int success) |
1089 | { | 1054 | { |
1090 | struct dm_exception *e; | 1055 | struct dm_exception *e; |
@@ -1129,7 +1094,8 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) | |||
1129 | out: | 1094 | out: |
1130 | dm_remove_exception(&pe->e); | 1095 | dm_remove_exception(&pe->e); |
1131 | snapshot_bios = bio_list_get(&pe->snapshot_bios); | 1096 | snapshot_bios = bio_list_get(&pe->snapshot_bios); |
1132 | origin_bios = put_pending_exception(pe); | 1097 | origin_bios = bio_list_get(&pe->origin_bios); |
1098 | free_pending_exception(pe); | ||
1133 | 1099 | ||
1134 | up_write(&s->lock); | 1100 | up_write(&s->lock); |
1135 | 1101 | ||
@@ -1139,7 +1105,7 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) | |||
1139 | else | 1105 | else |
1140 | flush_bios(snapshot_bios); | 1106 | flush_bios(snapshot_bios); |
1141 | 1107 | ||
1142 | flush_bios(origin_bios); | 1108 | retry_origin_bios(s, origin_bios); |
1143 | } | 1109 | } |
1144 | 1110 | ||
1145 | static void commit_callback(void *context, int success) | 1111 | static void commit_callback(void *context, int success) |
@@ -1226,8 +1192,6 @@ __find_pending_exception(struct dm_snapshot *s, | |||
1226 | pe->e.old_chunk = chunk; | 1192 | pe->e.old_chunk = chunk; |
1227 | bio_list_init(&pe->origin_bios); | 1193 | bio_list_init(&pe->origin_bios); |
1228 | bio_list_init(&pe->snapshot_bios); | 1194 | bio_list_init(&pe->snapshot_bios); |
1229 | pe->primary_pe = NULL; | ||
1230 | atomic_set(&pe->ref_count, 0); | ||
1231 | pe->started = 0; | 1195 | pe->started = 0; |
1232 | 1196 | ||
1233 | if (s->store->type->prepare_exception(s->store, &pe->e)) { | 1197 | if (s->store->type->prepare_exception(s->store, &pe->e)) { |
@@ -1235,7 +1199,6 @@ __find_pending_exception(struct dm_snapshot *s, | |||
1235 | return NULL; | 1199 | return NULL; |
1236 | } | 1200 | } |
1237 | 1201 | ||
1238 | get_pending_exception(pe); | ||
1239 | dm_insert_exception(&s->pending, &pe->e); | 1202 | dm_insert_exception(&s->pending, &pe->e); |
1240 | 1203 | ||
1241 | return pe; | 1204 | return pe; |
@@ -1492,16 +1455,16 @@ static int snapshot_iterate_devices(struct dm_target *ti, | |||
1492 | static int __origin_write(struct list_head *snapshots, sector_t sector, | 1455 | static int __origin_write(struct list_head *snapshots, sector_t sector, |
1493 | struct bio *bio) | 1456 | struct bio *bio) |
1494 | { | 1457 | { |
1495 | int r = DM_MAPIO_REMAPPED, first = 0; | 1458 | int r = DM_MAPIO_REMAPPED; |
1496 | struct dm_snapshot *snap; | 1459 | struct dm_snapshot *snap; |
1497 | struct dm_exception *e; | 1460 | struct dm_exception *e; |
1498 | struct dm_snap_pending_exception *pe, *next_pe, *primary_pe = NULL; | 1461 | struct dm_snap_pending_exception *pe; |
1462 | struct dm_snap_pending_exception *pe_to_start_now = NULL; | ||
1463 | struct dm_snap_pending_exception *pe_to_start_last = NULL; | ||
1499 | chunk_t chunk; | 1464 | chunk_t chunk; |
1500 | LIST_HEAD(pe_queue); | ||
1501 | 1465 | ||
1502 | /* Do all the snapshots on this origin */ | 1466 | /* Do all the snapshots on this origin */ |
1503 | list_for_each_entry (snap, snapshots, list) { | 1467 | list_for_each_entry (snap, snapshots, list) { |
1504 | |||
1505 | down_write(&snap->lock); | 1468 | down_write(&snap->lock); |
1506 | 1469 | ||
1507 | /* Only deal with valid and active snapshots */ | 1470 | /* Only deal with valid and active snapshots */ |
@@ -1522,9 +1485,6 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, | |||
1522 | * Check exception table to see if block | 1485 | * Check exception table to see if block |
1523 | * is already remapped in this snapshot | 1486 | * is already remapped in this snapshot |
1524 | * and trigger an exception if not. | 1487 | * and trigger an exception if not. |
1525 | * | ||
1526 | * ref_count is initialised to 1 so pending_complete() | ||
1527 | * won't destroy the primary_pe while we're inside this loop. | ||
1528 | */ | 1488 | */ |
1529 | e = dm_lookup_exception(&snap->complete, chunk); | 1489 | e = dm_lookup_exception(&snap->complete, chunk); |
1530 | if (e) | 1490 | if (e) |
@@ -1554,60 +1514,43 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, | |||
1554 | } | 1514 | } |
1555 | } | 1515 | } |
1556 | 1516 | ||
1557 | if (!primary_pe) { | 1517 | r = DM_MAPIO_SUBMITTED; |
1558 | /* | ||
1559 | * Either every pe here has same | ||
1560 | * primary_pe or none has one yet. | ||
1561 | */ | ||
1562 | if (pe->primary_pe) | ||
1563 | primary_pe = pe->primary_pe; | ||
1564 | else { | ||
1565 | primary_pe = pe; | ||
1566 | first = 1; | ||
1567 | } | ||
1568 | |||
1569 | if (bio) | ||
1570 | bio_list_add(&primary_pe->origin_bios, bio); | ||
1571 | 1518 | ||
1572 | r = DM_MAPIO_SUBMITTED; | 1519 | /* |
1573 | } | 1520 | * If an origin bio was supplied, queue it to wait for the |
1521 | * completion of this exception, and start this one last, | ||
1522 | * at the end of the function. | ||
1523 | */ | ||
1524 | if (bio) { | ||
1525 | bio_list_add(&pe->origin_bios, bio); | ||
1526 | bio = NULL; | ||
1574 | 1527 | ||
1575 | if (!pe->primary_pe) { | 1528 | if (!pe->started) { |
1576 | pe->primary_pe = primary_pe; | 1529 | pe->started = 1; |
1577 | get_pending_exception(primary_pe); | 1530 | pe_to_start_last = pe; |
1531 | } | ||
1578 | } | 1532 | } |
1579 | 1533 | ||
1580 | if (!pe->started) { | 1534 | if (!pe->started) { |
1581 | pe->started = 1; | 1535 | pe->started = 1; |
1582 | list_add_tail(&pe->list, &pe_queue); | 1536 | pe_to_start_now = pe; |
1583 | } | 1537 | } |
1584 | 1538 | ||
1585 | next_snapshot: | 1539 | next_snapshot: |
1586 | up_write(&snap->lock); | 1540 | up_write(&snap->lock); |
1587 | } | ||
1588 | 1541 | ||
1589 | if (!primary_pe) | 1542 | if (pe_to_start_now) { |
1590 | return r; | 1543 | start_copy(pe_to_start_now); |
1591 | 1544 | pe_to_start_now = NULL; | |
1592 | /* | 1545 | } |
1593 | * If this is the first time we're processing this chunk and | ||
1594 | * ref_count is now 1 it means all the pending exceptions | ||
1595 | * got completed while we were in the loop above, so it falls to | ||
1596 | * us here to remove the primary_pe and submit any origin_bios. | ||
1597 | */ | ||
1598 | |||
1599 | if (first && atomic_dec_and_test(&primary_pe->ref_count)) { | ||
1600 | flush_bios(bio_list_get(&primary_pe->origin_bios)); | ||
1601 | free_pending_exception(primary_pe); | ||
1602 | /* If we got here, pe_queue is necessarily empty. */ | ||
1603 | return r; | ||
1604 | } | 1546 | } |
1605 | 1547 | ||
1606 | /* | 1548 | /* |
1607 | * Now that we have a complete pe list we can start the copying. | 1549 | * Submit the exception against which the bio is queued last, |
1550 | * to give the other exceptions a head start. | ||
1608 | */ | 1551 | */ |
1609 | list_for_each_entry_safe(pe, next_pe, &pe_queue, list) | 1552 | if (pe_to_start_last) |
1610 | start_copy(pe); | 1553 | start_copy(pe_to_start_last); |
1611 | 1554 | ||
1612 | return r; | 1555 | return r; |
1613 | } | 1556 | } |