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.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 7a90fed033fe..5c067efc665f 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -468,7 +468,8 @@ static int calc_max_buckets(void)
468/* 468/*
469 * Allocate room for a suitable hash table. 469 * Allocate room for a suitable hash table.
470 */ 470 */
471static int init_hash_tables(struct dm_snapshot *s, chunk_t chunk_shift) 471static int init_hash_tables(struct dm_snapshot *s, chunk_t chunk_shift,
472 struct dm_dev *cow)
472{ 473{
473 sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; 474 sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets;
474 475
@@ -476,7 +477,7 @@ static int init_hash_tables(struct dm_snapshot *s, chunk_t chunk_shift)
476 * Calculate based on the size of the original volume or 477 * Calculate based on the size of the original volume or
477 * the COW volume... 478 * the COW volume...
478 */ 479 */
479 cow_dev_size = get_dev_size(s->cow->bdev); 480 cow_dev_size = get_dev_size(cow->bdev);
480 origin_dev_size = get_dev_size(s->origin->bdev); 481 origin_dev_size = get_dev_size(s->origin->bdev);
481 max_buckets = calc_max_buckets(); 482 max_buckets = calc_max_buckets();
482 483
@@ -516,7 +517,8 @@ static ulong round_up(ulong n, ulong size)
516 517
517static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg, 518static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
518 chunk_t *chunk_size, chunk_t *chunk_mask, 519 chunk_t *chunk_size, chunk_t *chunk_mask,
519 chunk_t *chunk_shift, char **error) 520 chunk_t *chunk_shift, struct dm_dev *cow,
521 char **error)
520{ 522{
521 unsigned long chunk_size_ulong; 523 unsigned long chunk_size_ulong;
522 char *value; 524 char *value;
@@ -545,7 +547,7 @@ static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
545 } 547 }
546 548
547 /* Validate the chunk size against the device block size */ 549 /* Validate the chunk size against the device block size */
548 if (chunk_size_ulong % (bdev_hardsect_size(s->cow->bdev) >> 9)) { 550 if (chunk_size_ulong % (bdev_hardsect_size(cow->bdev) >> 9)) {
549 *error = "Chunk size is not a multiple of device blocksize"; 551 *error = "Chunk size is not a multiple of device blocksize";
550 return -EINVAL; 552 return -EINVAL;
551 } 553 }
@@ -569,6 +571,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
569 char *origin_path; 571 char *origin_path;
570 char *cow_path; 572 char *cow_path;
571 chunk_t chunk_size, chunk_mask, chunk_shift; 573 chunk_t chunk_size, chunk_mask, chunk_shift;
574 struct dm_dev *cow;
572 575
573 if (argc != 4) { 576 if (argc != 4) {
574 ti->error = "requires exactly 4 arguments"; 577 ti->error = "requires exactly 4 arguments";
@@ -601,7 +604,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
601 } 604 }
602 605
603 r = dm_get_device(ti, cow_path, 0, 0, 606 r = dm_get_device(ti, cow_path, 0, 0,
604 FMODE_READ | FMODE_WRITE, &s->cow); 607 FMODE_READ | FMODE_WRITE, &cow);
605 if (r) { 608 if (r) {
606 dm_put_device(ti, s->origin); 609 dm_put_device(ti, s->origin);
607 ti->error = "Cannot get COW device"; 610 ti->error = "Cannot get COW device";
@@ -609,7 +612,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
609 } 612 }
610 613
611 r = set_chunk_size(s, argv[3], &chunk_size, &chunk_mask, &chunk_shift, 614 r = set_chunk_size(s, argv[3], &chunk_size, &chunk_mask, &chunk_shift,
612 &ti->error); 615 cow, &ti->error);
613 if (r) 616 if (r)
614 goto bad3; 617 goto bad3;
615 618
@@ -620,14 +623,14 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
620 spin_lock_init(&s->pe_lock); 623 spin_lock_init(&s->pe_lock);
621 624
622 /* Allocate hash table for COW data */ 625 /* Allocate hash table for COW data */
623 if (init_hash_tables(s, chunk_shift)) { 626 if (init_hash_tables(s, chunk_shift, cow)) {
624 ti->error = "Unable to allocate hash table space"; 627 ti->error = "Unable to allocate hash table space";
625 r = -ENOMEM; 628 r = -ENOMEM;
626 goto bad3; 629 goto bad3;
627 } 630 }
628 631
629 r = dm_exception_store_create(argv[2], ti, chunk_size, chunk_mask, 632 r = dm_exception_store_create(argv[2], ti, chunk_size, chunk_mask,
630 chunk_shift, &s->store); 633 chunk_shift, cow, &s->store);
631 if (r) { 634 if (r) {
632 ti->error = "Couldn't create exception store"; 635 ti->error = "Couldn't create exception store";
633 r = -EINVAL; 636 r = -EINVAL;
@@ -705,7 +708,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
705 exit_exception_table(&s->complete, exception_cache); 708 exit_exception_table(&s->complete, exception_cache);
706 709
707 bad3: 710 bad3:
708 dm_put_device(ti, s->cow); 711 dm_put_device(ti, cow);
709 dm_put_device(ti, s->origin); 712 dm_put_device(ti, s->origin);
710 713
711 bad2: 714 bad2:
@@ -732,6 +735,7 @@ static void snapshot_dtr(struct dm_target *ti)
732 int i; 735 int i;
733#endif 736#endif
734 struct dm_snapshot *s = ti->private; 737 struct dm_snapshot *s = ti->private;
738 struct dm_dev *cow = s->store->cow;
735 739
736 flush_workqueue(ksnapd); 740 flush_workqueue(ksnapd);
737 741
@@ -759,7 +763,7 @@ static void snapshot_dtr(struct dm_target *ti)
759 mempool_destroy(s->pending_pool); 763 mempool_destroy(s->pending_pool);
760 764
761 dm_put_device(ti, s->origin); 765 dm_put_device(ti, s->origin);
762 dm_put_device(ti, s->cow); 766 dm_put_device(ti, cow);
763 767
764 kfree(s); 768 kfree(s);
765} 769}
@@ -961,7 +965,7 @@ static void start_copy(struct dm_snap_pending_exception *pe)
961 src.sector = chunk_to_sector(s, pe->e.old_chunk); 965 src.sector = chunk_to_sector(s, pe->e.old_chunk);
962 src.count = min(s->store->chunk_size, dev_size - src.sector); 966 src.count = min(s->store->chunk_size, dev_size - src.sector);
963 967
964 dest.bdev = s->cow->bdev; 968 dest.bdev = s->store->cow->bdev;
965 dest.sector = chunk_to_sector(s, pe->e.new_chunk); 969 dest.sector = chunk_to_sector(s, pe->e.new_chunk);
966 dest.count = src.count; 970 dest.count = src.count;
967 971
@@ -1022,7 +1026,7 @@ __find_pending_exception(struct dm_snapshot *s,
1022static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e, 1026static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
1023 struct bio *bio, chunk_t chunk) 1027 struct bio *bio, chunk_t chunk)
1024{ 1028{
1025 bio->bi_bdev = s->cow->bdev; 1029 bio->bi_bdev = s->store->cow->bdev;
1026 bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) + 1030 bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) +
1027 (chunk - e->old_chunk)) + 1031 (chunk - e->old_chunk)) +
1028 (bio->bi_sector & s->store->chunk_mask); 1032 (bio->bi_sector & s->store->chunk_mask);
@@ -1168,7 +1172,7 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
1168 * make sense. 1172 * make sense.
1169 */ 1173 */
1170 snprintf(result, maxlen, "%s %s %s %llu", 1174 snprintf(result, maxlen, "%s %s %s %llu",
1171 snap->origin->name, snap->cow->name, 1175 snap->origin->name, snap->store->cow->name,
1172 snap->store->type->name, 1176 snap->store->type->name,
1173 (unsigned long long)snap->store->chunk_size); 1177 (unsigned long long)snap->store->chunk_size);
1174 break; 1178 break;