diff options
-rw-r--r-- | drivers/md/dm-exception-store.c | 30 | ||||
-rw-r--r-- | drivers/md/dm-exception-store.h | 12 | ||||
-rw-r--r-- | drivers/md/dm-snap-persistent.c | 12 | ||||
-rw-r--r-- | drivers/md/dm-snap-transient.c | 7 | ||||
-rw-r--r-- | drivers/md/dm-snap.c | 74 |
5 files changed, 78 insertions, 57 deletions
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 205215968ff1..2b7907b6dd09 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c | |||
@@ -172,7 +172,8 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store, | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /* Validate the chunk size against the device block size */ | 174 | /* Validate the chunk size against the device block size */ |
175 | if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) { | 175 | if (chunk_size % |
176 | (bdev_logical_block_size(dm_snap_cow(store->snap)->bdev) >> 9)) { | ||
176 | *error = "Chunk size is not a multiple of device blocksize"; | 177 | *error = "Chunk size is not a multiple of device blocksize"; |
177 | return -EINVAL; | 178 | return -EINVAL; |
178 | } | 179 | } |
@@ -190,6 +191,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store, | |||
190 | } | 191 | } |
191 | 192 | ||
192 | int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | 193 | int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, |
194 | struct dm_snapshot *snap, | ||
193 | unsigned *args_used, | 195 | unsigned *args_used, |
194 | struct dm_exception_store **store) | 196 | struct dm_exception_store **store) |
195 | { | 197 | { |
@@ -198,7 +200,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | |||
198 | struct dm_exception_store *tmp_store; | 200 | struct dm_exception_store *tmp_store; |
199 | char persistent; | 201 | char persistent; |
200 | 202 | ||
201 | if (argc < 3) { | 203 | if (argc < 2) { |
202 | ti->error = "Insufficient exception store arguments"; | 204 | ti->error = "Insufficient exception store arguments"; |
203 | return -EINVAL; | 205 | return -EINVAL; |
204 | } | 206 | } |
@@ -209,7 +211,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | |||
209 | return -ENOMEM; | 211 | return -ENOMEM; |
210 | } | 212 | } |
211 | 213 | ||
212 | persistent = toupper(*argv[1]); | 214 | persistent = toupper(*argv[0]); |
213 | if (persistent == 'P') | 215 | if (persistent == 'P') |
214 | type = get_type("P"); | 216 | type = get_type("P"); |
215 | else if (persistent == 'N') | 217 | else if (persistent == 'N') |
@@ -227,32 +229,23 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | |||
227 | } | 229 | } |
228 | 230 | ||
229 | tmp_store->type = type; | 231 | tmp_store->type = type; |
230 | tmp_store->ti = ti; | 232 | tmp_store->snap = snap; |
231 | 233 | ||
232 | r = dm_get_device(ti, argv[0], 0, 0, | 234 | r = set_chunk_size(tmp_store, argv[1], &ti->error); |
233 | FMODE_READ | FMODE_WRITE, &tmp_store->cow); | ||
234 | if (r) { | ||
235 | ti->error = "Cannot get COW device"; | ||
236 | goto bad_cow; | ||
237 | } | ||
238 | |||
239 | r = set_chunk_size(tmp_store, argv[2], &ti->error); | ||
240 | if (r) | 235 | if (r) |
241 | goto bad_ctr; | 236 | goto bad; |
242 | 237 | ||
243 | r = type->ctr(tmp_store, 0, NULL); | 238 | r = type->ctr(tmp_store, 0, NULL); |
244 | if (r) { | 239 | if (r) { |
245 | ti->error = "Exception store type constructor failed"; | 240 | ti->error = "Exception store type constructor failed"; |
246 | goto bad_ctr; | 241 | goto bad; |
247 | } | 242 | } |
248 | 243 | ||
249 | *args_used = 3; | 244 | *args_used = 2; |
250 | *store = tmp_store; | 245 | *store = tmp_store; |
251 | return 0; | 246 | return 0; |
252 | 247 | ||
253 | bad_ctr: | 248 | bad: |
254 | dm_put_device(ti, tmp_store->cow); | ||
255 | bad_cow: | ||
256 | put_type(type); | 249 | put_type(type); |
257 | bad_type: | 250 | bad_type: |
258 | kfree(tmp_store); | 251 | kfree(tmp_store); |
@@ -263,7 +256,6 @@ EXPORT_SYMBOL(dm_exception_store_create); | |||
263 | void dm_exception_store_destroy(struct dm_exception_store *store) | 256 | void dm_exception_store_destroy(struct dm_exception_store *store) |
264 | { | 257 | { |
265 | store->type->dtr(store); | 258 | store->type->dtr(store); |
266 | dm_put_device(store->ti, store->cow); | ||
267 | put_type(store->type); | 259 | put_type(store->type); |
268 | kfree(store); | 260 | kfree(store); |
269 | } | 261 | } |
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index 366c8b1fca37..bb8874653de1 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h | |||
@@ -94,11 +94,11 @@ struct dm_exception_store_type { | |||
94 | struct list_head list; | 94 | struct list_head list; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | struct dm_snapshot; | ||
98 | |||
97 | struct dm_exception_store { | 99 | struct dm_exception_store { |
98 | struct dm_exception_store_type *type; | 100 | struct dm_exception_store_type *type; |
99 | struct dm_target *ti; | 101 | struct dm_snapshot *snap; |
100 | |||
101 | struct dm_dev *cow; | ||
102 | 102 | ||
103 | /* Size of data blocks saved - must be a power of 2 */ | 103 | /* Size of data blocks saved - must be a power of 2 */ |
104 | unsigned chunk_size; | 104 | unsigned chunk_size; |
@@ -109,6 +109,11 @@ struct dm_exception_store { | |||
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* | 111 | /* |
112 | * Obtain the cow device used by a given snapshot. | ||
113 | */ | ||
114 | struct dm_dev *dm_snap_cow(struct dm_snapshot *snap); | ||
115 | |||
116 | /* | ||
112 | * Funtions to manipulate consecutive chunks | 117 | * Funtions to manipulate consecutive chunks |
113 | */ | 118 | */ |
114 | # if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) | 119 | # if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) |
@@ -173,6 +178,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store, | |||
173 | char **error); | 178 | char **error); |
174 | 179 | ||
175 | int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, | 180 | int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, |
181 | struct dm_snapshot *snap, | ||
176 | unsigned *args_used, | 182 | unsigned *args_used, |
177 | struct dm_exception_store **store); | 183 | struct dm_exception_store **store); |
178 | void dm_exception_store_destroy(struct dm_exception_store *store); | 184 | void dm_exception_store_destroy(struct dm_exception_store *store); |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 767065f6c5f3..157999ebd236 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -214,7 +214,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, | |||
214 | int metadata) | 214 | int metadata) |
215 | { | 215 | { |
216 | struct dm_io_region where = { | 216 | struct dm_io_region where = { |
217 | .bdev = ps->store->cow->bdev, | 217 | .bdev = dm_snap_cow(ps->store->snap)->bdev, |
218 | .sector = ps->store->chunk_size * chunk, | 218 | .sector = ps->store->chunk_size * chunk, |
219 | .count = ps->store->chunk_size, | 219 | .count = ps->store->chunk_size, |
220 | }; | 220 | }; |
@@ -294,7 +294,8 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
294 | */ | 294 | */ |
295 | if (!ps->store->chunk_size) { | 295 | if (!ps->store->chunk_size) { |
296 | ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS, | 296 | ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS, |
297 | bdev_logical_block_size(ps->store->cow->bdev) >> 9); | 297 | bdev_logical_block_size(dm_snap_cow(ps->store->snap)-> |
298 | bdev) >> 9); | ||
298 | ps->store->chunk_mask = ps->store->chunk_size - 1; | 299 | ps->store->chunk_mask = ps->store->chunk_size - 1; |
299 | ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1; | 300 | ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1; |
300 | chunk_size_supplied = 0; | 301 | chunk_size_supplied = 0; |
@@ -497,7 +498,7 @@ static void persistent_usage(struct dm_exception_store *store, | |||
497 | struct pstore *ps = get_info(store); | 498 | struct pstore *ps = get_info(store); |
498 | 499 | ||
499 | *sectors_allocated = ps->next_free * store->chunk_size; | 500 | *sectors_allocated = ps->next_free * store->chunk_size; |
500 | *total_sectors = get_dev_size(store->cow->bdev); | 501 | *total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev); |
501 | 502 | ||
502 | /* | 503 | /* |
503 | * First chunk is the fixed header. | 504 | * First chunk is the fixed header. |
@@ -596,7 +597,7 @@ static int persistent_prepare_exception(struct dm_exception_store *store, | |||
596 | struct pstore *ps = get_info(store); | 597 | struct pstore *ps = get_info(store); |
597 | uint32_t stride; | 598 | uint32_t stride; |
598 | chunk_t next_free; | 599 | chunk_t next_free; |
599 | sector_t size = get_dev_size(store->cow->bdev); | 600 | sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); |
600 | 601 | ||
601 | /* Is there enough room ? */ | 602 | /* Is there enough room ? */ |
602 | if (size < ((ps->next_free + 1) * store->chunk_size)) | 603 | if (size < ((ps->next_free + 1) * store->chunk_size)) |
@@ -733,8 +734,7 @@ static unsigned persistent_status(struct dm_exception_store *store, | |||
733 | case STATUSTYPE_INFO: | 734 | case STATUSTYPE_INFO: |
734 | break; | 735 | break; |
735 | case STATUSTYPE_TABLE: | 736 | case STATUSTYPE_TABLE: |
736 | DMEMIT(" %s P %llu", store->cow->name, | 737 | DMEMIT(" P %llu", (unsigned long long)store->chunk_size); |
737 | (unsigned long long)store->chunk_size); | ||
738 | } | 738 | } |
739 | 739 | ||
740 | return sz; | 740 | return sz; |
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index 245a50c7337e..a0898a66a2f8 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c | |||
@@ -39,7 +39,7 @@ static int transient_prepare_exception(struct dm_exception_store *store, | |||
39 | struct dm_exception *e) | 39 | struct dm_exception *e) |
40 | { | 40 | { |
41 | struct transient_c *tc = store->context; | 41 | struct transient_c *tc = store->context; |
42 | sector_t size = get_dev_size(store->cow->bdev); | 42 | sector_t size = get_dev_size(dm_snap_cow(store->snap)->bdev); |
43 | 43 | ||
44 | if (size < (tc->next_free + store->chunk_size)) | 44 | if (size < (tc->next_free + store->chunk_size)) |
45 | return -1; | 45 | return -1; |
@@ -65,7 +65,7 @@ static void transient_usage(struct dm_exception_store *store, | |||
65 | sector_t *metadata_sectors) | 65 | sector_t *metadata_sectors) |
66 | { | 66 | { |
67 | *sectors_allocated = ((struct transient_c *) store->context)->next_free; | 67 | *sectors_allocated = ((struct transient_c *) store->context)->next_free; |
68 | *total_sectors = get_dev_size(store->cow->bdev); | 68 | *total_sectors = get_dev_size(dm_snap_cow(store->snap)->bdev); |
69 | *metadata_sectors = 0; | 69 | *metadata_sectors = 0; |
70 | } | 70 | } |
71 | 71 | ||
@@ -94,8 +94,7 @@ static unsigned transient_status(struct dm_exception_store *store, | |||
94 | case STATUSTYPE_INFO: | 94 | case STATUSTYPE_INFO: |
95 | break; | 95 | break; |
96 | case STATUSTYPE_TABLE: | 96 | case STATUSTYPE_TABLE: |
97 | DMEMIT(" %s N %llu", store->cow->name, | 97 | DMEMIT(" N %llu", (unsigned long long)store->chunk_size); |
98 | (unsigned long long)store->chunk_size); | ||
99 | } | 98 | } |
100 | 99 | ||
101 | return sz; | 100 | return sz; |
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 | ||
103 | struct dm_dev *dm_snap_cow(struct dm_snapshot *s) | ||
104 | { | ||
105 | return s->cow; | ||
106 | } | ||
107 | EXPORT_SYMBOL(dm_snap_cow); | ||
108 | |||
100 | static struct workqueue_struct *ksnapd; | 109 | static struct workqueue_struct *ksnapd; |
101 | static void flush_queued_bios(struct work_struct *work); | 110 | static 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 | ||
725 | bad_origin: | 744 | bad_origin: |
726 | kfree(s); | 745 | dm_exception_store_destroy(s->store); |
727 | 746 | ||
728 | bad_snap: | 747 | bad_store: |
729 | dm_exception_store_destroy(store); | 748 | dm_put_device(ti, s->cow); |
730 | 749 | ||
731 | bad_args: | 750 | bad_cow: |
751 | kfree(s); | ||
752 | |||
753 | bad: | ||
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 | ||
845 | static void get_pending_exception(struct dm_snap_pending_exception *pe) | 869 | static 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, | |||
1038 | static void remap_exception(struct dm_snapshot *s, struct dm_exception *e, | 1062 | static 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 | /* |