aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-snap.c
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2009-12-10 18:52:12 -0500
committerAlasdair G Kergon <agk@redhat.com>2009-12-10 18:52:12 -0500
commitfc56f6fbcca3672c63c93c65f45105faacfc13cb (patch)
treef50f42a461ef33f8617fbdb781879e6ae77b62c4 /drivers/md/dm-snap.c
parent985903bb3a6d98623360ab6c855417f638840029 (diff)
dm snapshot: move cow ref from exception store to snap core
Store the reference to the snapshot cow device in the core snapshot code instead of each exception store. It can be accessed through the new function dm_snap_cow(). Exception stores should each now maintain a reference to their parent snapshot struct. This is cleaner and makes part of the forthcoming snapshot merge code simpler. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Reviewed-by: Jonathan Brassow <jbrassow@redhat.com> Cc: Mikulas Patocka <mpatocka@redhat.com>
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r--drivers/md/dm-snap.c74
1 files changed, 49 insertions, 25 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 8bd77cbd7e45..dc500a6f6232 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -59,6 +59,9 @@ struct dm_snapshot {
59 struct rw_semaphore lock; 59 struct rw_semaphore lock;
60 60
61 struct dm_dev *origin; 61 struct dm_dev *origin;
62 struct dm_dev *cow;
63
64 struct dm_target *ti;
62 65
63 /* List of snapshots per Origin */ 66 /* List of snapshots per Origin */
64 struct list_head list; 67 struct list_head list;
@@ -97,6 +100,12 @@ struct dm_snapshot {
97 struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; 100 struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
98}; 101};
99 102
103struct dm_dev *dm_snap_cow(struct dm_snapshot *s)
104{
105 return s->cow;
106}
107EXPORT_SYMBOL(dm_snap_cow);
108
100static struct workqueue_struct *ksnapd; 109static struct workqueue_struct *ksnapd;
101static void flush_queued_bios(struct work_struct *work); 110static void flush_queued_bios(struct work_struct *work);
102 111
@@ -558,7 +567,7 @@ static int init_hash_tables(struct dm_snapshot *s)
558 * Calculate based on the size of the original volume or 567 * Calculate based on the size of the original volume or
559 * the COW volume... 568 * the COW volume...
560 */ 569 */
561 cow_dev_size = get_dev_size(s->store->cow->bdev); 570 cow_dev_size = get_dev_size(s->cow->bdev);
562 origin_dev_size = get_dev_size(s->origin->bdev); 571 origin_dev_size = get_dev_size(s->origin->bdev);
563 max_buckets = calc_max_buckets(); 572 max_buckets = calc_max_buckets();
564 573
@@ -596,45 +605,55 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
596 struct dm_snapshot *s; 605 struct dm_snapshot *s;
597 int i; 606 int i;
598 int r = -EINVAL; 607 int r = -EINVAL;
599 char *origin_path; 608 char *origin_path, *cow_path;
600 struct dm_exception_store *store;
601 unsigned args_used; 609 unsigned args_used;
602 610
603 if (argc != 4) { 611 if (argc != 4) {
604 ti->error = "requires exactly 4 arguments"; 612 ti->error = "requires exactly 4 arguments";
605 r = -EINVAL; 613 r = -EINVAL;
606 goto bad_args; 614 goto bad;
607 } 615 }
608 616
609 origin_path = argv[0]; 617 origin_path = argv[0];
610 argv++; 618 argv++;
611 argc--; 619 argc--;
612 620
613 r = dm_exception_store_create(ti, argc, argv, &args_used, &store); 621 s = kmalloc(sizeof(*s), GFP_KERNEL);
622 if (!s) {
623 ti->error = "Cannot allocate snapshot context private "
624 "structure";
625 r = -ENOMEM;
626 goto bad;
627 }
628
629 cow_path = argv[0];
630 argv++;
631 argc--;
632
633 r = dm_get_device(ti, cow_path, 0, 0,
634 FMODE_READ | FMODE_WRITE, &s->cow);
635 if (r) {
636 ti->error = "Cannot get COW device";
637 goto bad_cow;
638 }
639
640 r = dm_exception_store_create(ti, argc, argv, s, &args_used, &s->store);
614 if (r) { 641 if (r) {
615 ti->error = "Couldn't create exception store"; 642 ti->error = "Couldn't create exception store";
616 r = -EINVAL; 643 r = -EINVAL;
617 goto bad_args; 644 goto bad_store;
618 } 645 }
619 646
620 argv += args_used; 647 argv += args_used;
621 argc -= args_used; 648 argc -= args_used;
622 649
623 s = kmalloc(sizeof(*s), GFP_KERNEL);
624 if (!s) {
625 ti->error = "Cannot allocate snapshot context private "
626 "structure";
627 r = -ENOMEM;
628 goto bad_snap;
629 }
630
631 r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); 650 r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
632 if (r) { 651 if (r) {
633 ti->error = "Cannot get origin device"; 652 ti->error = "Cannot get origin device";
634 goto bad_origin; 653 goto bad_origin;
635 } 654 }
636 655
637 s->store = store; 656 s->ti = ti;
638 s->valid = 1; 657 s->valid = 1;
639 s->active = 0; 658 s->active = 0;
640 atomic_set(&s->pending_exceptions_count, 0); 659 atomic_set(&s->pending_exceptions_count, 0);
@@ -723,12 +742,15 @@ bad_hash_tables:
723 dm_put_device(ti, s->origin); 742 dm_put_device(ti, s->origin);
724 743
725bad_origin: 744bad_origin:
726 kfree(s); 745 dm_exception_store_destroy(s->store);
727 746
728bad_snap: 747bad_store:
729 dm_exception_store_destroy(store); 748 dm_put_device(ti, s->cow);
730 749
731bad_args: 750bad_cow:
751 kfree(s);
752
753bad:
732 return r; 754 return r;
733} 755}
734 756
@@ -777,6 +799,8 @@ static void snapshot_dtr(struct dm_target *ti)
777 799
778 dm_exception_store_destroy(s->store); 800 dm_exception_store_destroy(s->store);
779 801
802 dm_put_device(ti, s->cow);
803
780 kfree(s); 804 kfree(s);
781} 805}
782 806
@@ -839,7 +863,7 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)
839 863
840 s->valid = 0; 864 s->valid = 0;
841 865
842 dm_table_event(s->store->ti->table); 866 dm_table_event(s->ti->table);
843} 867}
844 868
845static void get_pending_exception(struct dm_snap_pending_exception *pe) 869static void get_pending_exception(struct dm_snap_pending_exception *pe)
@@ -977,7 +1001,7 @@ static void start_copy(struct dm_snap_pending_exception *pe)
977 src.sector = chunk_to_sector(s->store, pe->e.old_chunk); 1001 src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
978 src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector); 1002 src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector);
979 1003
980 dest.bdev = s->store->cow->bdev; 1004 dest.bdev = s->cow->bdev;
981 dest.sector = chunk_to_sector(s->store, pe->e.new_chunk); 1005 dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
982 dest.count = src.count; 1006 dest.count = src.count;
983 1007
@@ -1038,7 +1062,7 @@ __find_pending_exception(struct dm_snapshot *s,
1038static void remap_exception(struct dm_snapshot *s, struct dm_exception *e, 1062static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
1039 struct bio *bio, chunk_t chunk) 1063 struct bio *bio, chunk_t chunk)
1040{ 1064{
1041 bio->bi_bdev = s->store->cow->bdev; 1065 bio->bi_bdev = s->cow->bdev;
1042 bio->bi_sector = chunk_to_sector(s->store, 1066 bio->bi_sector = chunk_to_sector(s->store,
1043 dm_chunk_number(e->new_chunk) + 1067 dm_chunk_number(e->new_chunk) +
1044 (chunk - e->old_chunk)) + 1068 (chunk - e->old_chunk)) +
@@ -1056,7 +1080,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
1056 struct dm_snap_pending_exception *pe = NULL; 1080 struct dm_snap_pending_exception *pe = NULL;
1057 1081
1058 if (unlikely(bio_empty_barrier(bio))) { 1082 if (unlikely(bio_empty_barrier(bio))) {
1059 bio->bi_bdev = s->store->cow->bdev; 1083 bio->bi_bdev = s->cow->bdev;
1060 return DM_MAPIO_REMAPPED; 1084 return DM_MAPIO_REMAPPED;
1061 } 1085 }
1062 1086
@@ -1200,7 +1224,7 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
1200 * to make private copies if the output is to 1224 * to make private copies if the output is to
1201 * make sense. 1225 * make sense.
1202 */ 1226 */
1203 DMEMIT("%s", snap->origin->name); 1227 DMEMIT("%s %s", snap->origin->name, snap->cow->name);
1204 snap->store->type->status(snap->store, type, result + sz, 1228 snap->store->type->status(snap->store, type, result + sz,
1205 maxlen - sz); 1229 maxlen - sz);
1206 break; 1230 break;
@@ -1240,7 +1264,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
1240 goto next_snapshot; 1264 goto next_snapshot;
1241 1265
1242 /* Nothing to do if writing beyond end of snapshot */ 1266 /* Nothing to do if writing beyond end of snapshot */
1243 if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table)) 1267 if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
1244 goto next_snapshot; 1268 goto next_snapshot;
1245 1269
1246 /* 1270 /*