aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2009-12-10 18:52:28 -0500
committerAlasdair G Kergon <agk@redhat.com>2009-12-10 18:52:28 -0500
commit9eaae8ffbc340fc034fed1e5d0dc9ca0e943f817 (patch)
treeb40361de2cde4ecd14f569a82b18df87f7f9cbc7 /drivers
parentc2f3d24b783fda20618b73d65678eb5dfae31a5d (diff)
dm snapshot: make bio optional in __origin_write
To support the merging of snapshots back into their origin we need to trigger exceptions in other snapshots not being merged without any incoming bio on the origin device. The bio parameter to __origin_write() becomes optional and the sector needs supplying separately. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-snap.c23
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 *---------------------------------------------------------------*/
1470static 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 */
1481static 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;