diff options
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r-- | drivers/md/dm-snap.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index b5b9118c0636..5e553c50c215 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -1467,7 +1467,19 @@ static int snapshot_iterate_devices(struct dm_target *ti, | |||
1467 | /*----------------------------------------------------------------- | 1467 | /*----------------------------------------------------------------- |
1468 | * Origin methods | 1468 | * Origin methods |
1469 | *---------------------------------------------------------------*/ | 1469 | *---------------------------------------------------------------*/ |
1470 | static int __origin_write(struct list_head *snapshots, struct bio *bio) | 1470 | |
1471 | /* | ||
1472 | * If no exceptions need creating, DM_MAPIO_REMAPPED is returned and any | ||
1473 | * supplied bio was ignored. The caller may submit it immediately. | ||
1474 | * (No remapping actually occurs as the origin is always a direct linear | ||
1475 | * map.) | ||
1476 | * | ||
1477 | * If further exceptions are required, DM_MAPIO_SUBMITTED is returned | ||
1478 | * and any supplied bio is added to a list to be submitted once all | ||
1479 | * the necessary exceptions exist. | ||
1480 | */ | ||
1481 | static int __origin_write(struct list_head *snapshots, sector_t sector, | ||
1482 | struct bio *bio) | ||
1471 | { | 1483 | { |
1472 | int r = DM_MAPIO_REMAPPED, first = 0; | 1484 | int r = DM_MAPIO_REMAPPED, first = 0; |
1473 | struct dm_snapshot *snap; | 1485 | struct dm_snapshot *snap; |
@@ -1486,14 +1498,14 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1486 | goto next_snapshot; | 1498 | goto next_snapshot; |
1487 | 1499 | ||
1488 | /* Nothing to do if writing beyond end of snapshot */ | 1500 | /* Nothing to do if writing beyond end of snapshot */ |
1489 | if (bio->bi_sector >= dm_table_get_size(snap->ti->table)) | 1501 | if (sector >= dm_table_get_size(snap->ti->table)) |
1490 | goto next_snapshot; | 1502 | goto next_snapshot; |
1491 | 1503 | ||
1492 | /* | 1504 | /* |
1493 | * Remember, different snapshots can have | 1505 | * Remember, different snapshots can have |
1494 | * different chunk sizes. | 1506 | * different chunk sizes. |
1495 | */ | 1507 | */ |
1496 | chunk = sector_to_chunk(snap->store, bio->bi_sector); | 1508 | chunk = sector_to_chunk(snap->store, sector); |
1497 | 1509 | ||
1498 | /* | 1510 | /* |
1499 | * Check exception table to see if block | 1511 | * Check exception table to see if block |
@@ -1543,7 +1555,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) | |||
1543 | first = 1; | 1555 | first = 1; |
1544 | } | 1556 | } |
1545 | 1557 | ||
1546 | bio_list_add(&primary_pe->origin_bios, bio); | 1558 | if (bio) |
1559 | bio_list_add(&primary_pe->origin_bios, bio); | ||
1547 | 1560 | ||
1548 | r = DM_MAPIO_SUBMITTED; | 1561 | r = DM_MAPIO_SUBMITTED; |
1549 | } | 1562 | } |
@@ -1599,7 +1612,7 @@ static int do_origin(struct dm_dev *origin, struct bio *bio) | |||
1599 | down_read(&_origins_lock); | 1612 | down_read(&_origins_lock); |
1600 | o = __lookup_origin(origin->bdev); | 1613 | o = __lookup_origin(origin->bdev); |
1601 | if (o) | 1614 | if (o) |
1602 | r = __origin_write(&o->snapshots, bio); | 1615 | r = __origin_write(&o->snapshots, bio->bi_sector, bio); |
1603 | up_read(&_origins_lock); | 1616 | up_read(&_origins_lock); |
1604 | 1617 | ||
1605 | return r; | 1618 | return r; |