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 | } |
