aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2014-06-13 09:47:24 -0400
committerMike Snitzer <snitzer@redhat.com>2014-08-01 12:30:32 -0400
commite5aea7b49f2b1fd01f35ca7abeb76f5c56128a55 (patch)
tree02a829b3be21ed5cf51f2fe585a1a751f25a7599 /drivers/md
parent50f3c3efdd5773d90396be07a7ecaa58227ff906 (diff)
dm thin: relax external origin size constraints
Track the size of any external origin. Previously the external origin's size had to be a multiple of the thin-pool's block size, that is no longer a requirement. In addition, snapshots that are larger than the external origin are now supported. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-thin.c158
1 files changed, 115 insertions, 43 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 4c9a3b5f4ff1..0e844a5eca8f 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -227,6 +227,7 @@ struct thin_c {
227 struct list_head list; 227 struct list_head list;
228 struct dm_dev *pool_dev; 228 struct dm_dev *pool_dev;
229 struct dm_dev *origin_dev; 229 struct dm_dev *origin_dev;
230 sector_t origin_size;
230 dm_thin_id dev_id; 231 dm_thin_id dev_id;
231 232
232 struct pool *pool; 233 struct pool *pool;
@@ -590,31 +591,31 @@ static void __complete_mapping_preparation(struct dm_thin_new_mapping *m)
590 } 591 }
591} 592}
592 593
593static void copy_complete(int read_err, unsigned long write_err, void *context) 594static void complete_mapping_preparation(struct dm_thin_new_mapping *m)
594{ 595{
595 unsigned long flags; 596 unsigned long flags;
596 struct dm_thin_new_mapping *m = context;
597 struct pool *pool = m->tc->pool; 597 struct pool *pool = m->tc->pool;
598 598
599 m->err = read_err || write_err ? -EIO : 0;
600
601 spin_lock_irqsave(&pool->lock, flags); 599 spin_lock_irqsave(&pool->lock, flags);
602 __complete_mapping_preparation(m); 600 __complete_mapping_preparation(m);
603 spin_unlock_irqrestore(&pool->lock, flags); 601 spin_unlock_irqrestore(&pool->lock, flags);
604} 602}
605 603
604static void copy_complete(int read_err, unsigned long write_err, void *context)
605{
606 struct dm_thin_new_mapping *m = context;
607
608 m->err = read_err || write_err ? -EIO : 0;
609 complete_mapping_preparation(m);
610}
611
606static void overwrite_endio(struct bio *bio, int err) 612static void overwrite_endio(struct bio *bio, int err)
607{ 613{
608 unsigned long flags;
609 struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook)); 614 struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
610 struct dm_thin_new_mapping *m = h->overwrite_mapping; 615 struct dm_thin_new_mapping *m = h->overwrite_mapping;
611 struct pool *pool = m->tc->pool;
612 616
613 m->err = err; 617 m->err = err;
614 618 complete_mapping_preparation(m);
615 spin_lock_irqsave(&pool->lock, flags);
616 __complete_mapping_preparation(m);
617 spin_unlock_irqrestore(&pool->lock, flags);
618} 619}
619 620
620/*----------------------------------------------------------------*/ 621/*----------------------------------------------------------------*/
@@ -824,10 +825,31 @@ static struct dm_thin_new_mapping *get_next_mapping(struct pool *pool)
824 return m; 825 return m;
825} 826}
826 827
828static void ll_zero(struct thin_c *tc, struct dm_thin_new_mapping *m,
829 sector_t begin, sector_t end)
830{
831 int r;
832 struct dm_io_region to;
833
834 to.bdev = tc->pool_dev->bdev;
835 to.sector = begin;
836 to.count = end - begin;
837
838 r = dm_kcopyd_zero(tc->pool->copier, 1, &to, 0, copy_complete, m);
839 if (r < 0) {
840 DMERR_LIMIT("dm_kcopyd_zero() failed");
841 copy_complete(1, 1, m);
842 }
843}
844
845/*
846 * A partial copy also needs to zero the uncopied region.
847 */
827static void schedule_copy(struct thin_c *tc, dm_block_t virt_block, 848static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
828 struct dm_dev *origin, dm_block_t data_origin, 849 struct dm_dev *origin, dm_block_t data_origin,
829 dm_block_t data_dest, 850 dm_block_t data_dest,
830 struct dm_bio_prison_cell *cell, struct bio *bio) 851 struct dm_bio_prison_cell *cell, struct bio *bio,
852 sector_t len)
831{ 853{
832 int r; 854 int r;
833 struct pool *pool = tc->pool; 855 struct pool *pool = tc->pool;
@@ -838,10 +860,15 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
838 m->data_block = data_dest; 860 m->data_block = data_dest;
839 m->cell = cell; 861 m->cell = cell;
840 862
863 /*
864 * quiesce action + copy action + an extra reference held for the
865 * duration of this function (we may need to inc later for a
866 * partial zero).
867 */
868 atomic_set(&m->prepare_actions, 3);
869
841 if (!dm_deferred_set_add_work(pool->shared_read_ds, &m->list)) 870 if (!dm_deferred_set_add_work(pool->shared_read_ds, &m->list))
842 atomic_set(&m->prepare_actions, 1); /* copy only */ 871 complete_mapping_preparation(m); /* already quiesced */
843 else
844 atomic_set(&m->prepare_actions, 2); /* quiesce + copy */
845 872
846 /* 873 /*
847 * IO to pool_dev remaps to the pool target's data_dev. 874 * IO to pool_dev remaps to the pool target's data_dev.
@@ -862,20 +889,38 @@ static void schedule_copy(struct thin_c *tc, dm_block_t virt_block,
862 889
863 from.bdev = origin->bdev; 890 from.bdev = origin->bdev;
864 from.sector = data_origin * pool->sectors_per_block; 891 from.sector = data_origin * pool->sectors_per_block;
865 from.count = pool->sectors_per_block; 892 from.count = len;
866 893
867 to.bdev = tc->pool_dev->bdev; 894 to.bdev = tc->pool_dev->bdev;
868 to.sector = data_dest * pool->sectors_per_block; 895 to.sector = data_dest * pool->sectors_per_block;
869 to.count = pool->sectors_per_block; 896 to.count = len;
870 897
871 r = dm_kcopyd_copy(pool->copier, &from, 1, &to, 898 r = dm_kcopyd_copy(pool->copier, &from, 1, &to,
872 0, copy_complete, m); 899 0, copy_complete, m);
873 if (r < 0) { 900 if (r < 0) {
874 mempool_free(m, pool->mapping_pool);
875 DMERR_LIMIT("dm_kcopyd_copy() failed"); 901 DMERR_LIMIT("dm_kcopyd_copy() failed");
876 cell_error(pool, cell); 902 copy_complete(1, 1, m);
903
904 /*
905 * We allow the zero to be issued, to simplify the
906 * error path. Otherwise we'd need to start
907 * worrying about decrementing the prepare_actions
908 * counter.
909 */
910 }
911
912 /*
913 * Do we need to zero a tail region?
914 */
915 if (len < pool->sectors_per_block && pool->pf.zero_new_blocks) {
916 atomic_inc(&m->prepare_actions);
917 ll_zero(tc, m,
918 data_dest * pool->sectors_per_block + len,
919 (data_dest + 1) * pool->sectors_per_block);
877 } 920 }
878 } 921 }
922
923 complete_mapping_preparation(m); /* drop our ref */
879} 924}
880 925
881static void schedule_internal_copy(struct thin_c *tc, dm_block_t virt_block, 926static void schedule_internal_copy(struct thin_c *tc, dm_block_t virt_block,
@@ -883,15 +928,8 @@ static void schedule_internal_copy(struct thin_c *tc, dm_block_t virt_block,
883 struct dm_bio_prison_cell *cell, struct bio *bio) 928 struct dm_bio_prison_cell *cell, struct bio *bio)
884{ 929{
885 schedule_copy(tc, virt_block, tc->pool_dev, 930 schedule_copy(tc, virt_block, tc->pool_dev,
886 data_origin, data_dest, cell, bio); 931 data_origin, data_dest, cell, bio,
887} 932 tc->pool->sectors_per_block);
888
889static void schedule_external_copy(struct thin_c *tc, dm_block_t virt_block,
890 dm_block_t data_dest,
891 struct dm_bio_prison_cell *cell, struct bio *bio)
892{
893 schedule_copy(tc, virt_block, tc->origin_dev,
894 virt_block, data_dest, cell, bio);
895} 933}
896 934
897static void schedule_zero(struct thin_c *tc, dm_block_t virt_block, 935static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
@@ -923,21 +961,33 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block,
923 save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio); 961 save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
924 inc_all_io_entry(pool, bio); 962 inc_all_io_entry(pool, bio);
925 remap_and_issue(tc, bio, data_block); 963 remap_and_issue(tc, bio, data_block);
926 } else {
927 int r;
928 struct dm_io_region to;
929 964
930 to.bdev = tc->pool_dev->bdev; 965 } else
931 to.sector = data_block * pool->sectors_per_block; 966 ll_zero(tc, m,
932 to.count = pool->sectors_per_block; 967 data_block * pool->sectors_per_block,
968 (data_block + 1) * pool->sectors_per_block);
969}
933 970
934 r = dm_kcopyd_zero(pool->copier, 1, &to, 0, copy_complete, m); 971static void schedule_external_copy(struct thin_c *tc, dm_block_t virt_block,
935 if (r < 0) { 972 dm_block_t data_dest,
936 mempool_free(m, pool->mapping_pool); 973 struct dm_bio_prison_cell *cell, struct bio *bio)
937 DMERR_LIMIT("dm_kcopyd_zero() failed"); 974{
938 cell_error(pool, cell); 975 struct pool *pool = tc->pool;
939 } 976 sector_t virt_block_begin = virt_block * pool->sectors_per_block;
940 } 977 sector_t virt_block_end = (virt_block + 1) * pool->sectors_per_block;
978
979 if (virt_block_end <= tc->origin_size)
980 schedule_copy(tc, virt_block, tc->origin_dev,
981 virt_block, data_dest, cell, bio,
982 pool->sectors_per_block);
983
984 else if (virt_block_begin < tc->origin_size)
985 schedule_copy(tc, virt_block, tc->origin_dev,
986 virt_block, data_dest, cell, bio,
987 tc->origin_size - virt_block_begin);
988
989 else
990 schedule_zero(tc, virt_block, data_dest, cell, bio);
941} 991}
942 992
943/* 993/*
@@ -1319,7 +1369,18 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
1319 inc_all_io_entry(pool, bio); 1369 inc_all_io_entry(pool, bio);
1320 cell_defer_no_holder(tc, cell); 1370 cell_defer_no_holder(tc, cell);
1321 1371
1322 remap_to_origin_and_issue(tc, bio); 1372 if (bio_end_sector(bio) <= tc->origin_size)
1373 remap_to_origin_and_issue(tc, bio);
1374
1375 else if (bio->bi_iter.bi_sector < tc->origin_size) {
1376 zero_fill_bio(bio);
1377 bio->bi_iter.bi_size = (tc->origin_size - bio->bi_iter.bi_sector) << SECTOR_SHIFT;
1378 remap_to_origin_and_issue(tc, bio);
1379
1380 } else {
1381 zero_fill_bio(bio);
1382 bio_endio(bio, 0);
1383 }
1323 } else 1384 } else
1324 provision_block(tc, bio, block, cell); 1385 provision_block(tc, bio, block, cell);
1325 break; 1386 break;
@@ -3145,7 +3206,7 @@ static struct target_type pool_target = {
3145 .name = "thin-pool", 3206 .name = "thin-pool",
3146 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | 3207 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
3147 DM_TARGET_IMMUTABLE, 3208 DM_TARGET_IMMUTABLE,
3148 .version = {1, 12, 0}, 3209 .version = {1, 13, 0},
3149 .module = THIS_MODULE, 3210 .module = THIS_MODULE,
3150 .ctr = pool_ctr, 3211 .ctr = pool_ctr,
3151 .dtr = pool_dtr, 3212 .dtr = pool_dtr,
@@ -3404,6 +3465,16 @@ static void thin_postsuspend(struct dm_target *ti)
3404 noflush_work(tc, do_noflush_stop); 3465 noflush_work(tc, do_noflush_stop);
3405} 3466}
3406 3467
3468static int thin_preresume(struct dm_target *ti)
3469{
3470 struct thin_c *tc = ti->private;
3471
3472 if (tc->origin_dev)
3473 tc->origin_size = get_dev_size(tc->origin_dev->bdev);
3474
3475 return 0;
3476}
3477
3407/* 3478/*
3408 * <nr mapped sectors> <highest mapped sector> 3479 * <nr mapped sectors> <highest mapped sector>
3409 */ 3480 */
@@ -3486,12 +3557,13 @@ static int thin_iterate_devices(struct dm_target *ti,
3486 3557
3487static struct target_type thin_target = { 3558static struct target_type thin_target = {
3488 .name = "thin", 3559 .name = "thin",
3489 .version = {1, 12, 0}, 3560 .version = {1, 13, 0},
3490 .module = THIS_MODULE, 3561 .module = THIS_MODULE,
3491 .ctr = thin_ctr, 3562 .ctr = thin_ctr,
3492 .dtr = thin_dtr, 3563 .dtr = thin_dtr,
3493 .map = thin_map, 3564 .map = thin_map,
3494 .end_io = thin_endio, 3565 .end_io = thin_endio,
3566 .preresume = thin_preresume,
3495 .presuspend = thin_presuspend, 3567 .presuspend = thin_presuspend,
3496 .postsuspend = thin_postsuspend, 3568 .postsuspend = thin_postsuspend,
3497 .status = thin_status, 3569 .status = thin_status,