diff options
author | Jonathan Brassow <jbrassow@redhat.com> | 2009-04-02 14:55:32 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-04-02 14:55:32 -0400 |
commit | d0216849519bec8dc96301a3cd80316e71243839 (patch) | |
tree | 06e7f1d2028e784213e17f1a8ea1abae9ffb0ab9 /drivers/md/dm-snap.c | |
parent | 0cea9c78270cdf1d2ad74ce0e083d5555a0842e8 (diff) |
dm exception store: move chunk_fields
Move chunk fields from snapshot to exception store.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r-- | drivers/md/dm-snap.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 4429c2a1d6fb..7a90fed033fe 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -468,7 +468,7 @@ 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 | */ |
471 | static int init_hash_tables(struct dm_snapshot *s) | 471 | static int init_hash_tables(struct dm_snapshot *s, chunk_t chunk_shift) |
472 | { | 472 | { |
473 | sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; | 473 | sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; |
474 | 474 | ||
@@ -480,7 +480,7 @@ static int init_hash_tables(struct dm_snapshot *s) | |||
480 | origin_dev_size = get_dev_size(s->origin->bdev); | 480 | origin_dev_size = get_dev_size(s->origin->bdev); |
481 | max_buckets = calc_max_buckets(); | 481 | max_buckets = calc_max_buckets(); |
482 | 482 | ||
483 | hash_size = min(origin_dev_size, cow_dev_size) >> s->chunk_shift; | 483 | hash_size = min(origin_dev_size, cow_dev_size) >> chunk_shift; |
484 | hash_size = min(hash_size, max_buckets); | 484 | hash_size = min(hash_size, max_buckets); |
485 | 485 | ||
486 | hash_size = rounddown_pow_of_two(hash_size); | 486 | hash_size = rounddown_pow_of_two(hash_size); |
@@ -515,19 +515,20 @@ static ulong round_up(ulong n, ulong size) | |||
515 | } | 515 | } |
516 | 516 | ||
517 | static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg, | 517 | static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg, |
518 | char **error) | 518 | chunk_t *chunk_size, chunk_t *chunk_mask, |
519 | chunk_t *chunk_shift, char **error) | ||
519 | { | 520 | { |
520 | unsigned long chunk_size; | 521 | unsigned long chunk_size_ulong; |
521 | char *value; | 522 | char *value; |
522 | 523 | ||
523 | chunk_size = simple_strtoul(chunk_size_arg, &value, 10); | 524 | chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10); |
524 | if (*chunk_size_arg == '\0' || *value != '\0') { | 525 | if (*chunk_size_arg == '\0' || *value != '\0') { |
525 | *error = "Invalid chunk size"; | 526 | *error = "Invalid chunk size"; |
526 | return -EINVAL; | 527 | return -EINVAL; |
527 | } | 528 | } |
528 | 529 | ||
529 | if (!chunk_size) { | 530 | if (!chunk_size_ulong) { |
530 | s->chunk_size = s->chunk_mask = s->chunk_shift = 0; | 531 | *chunk_size = *chunk_mask = *chunk_shift = 0; |
531 | return 0; | 532 | return 0; |
532 | } | 533 | } |
533 | 534 | ||
@@ -535,23 +536,23 @@ static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg, | |||
535 | * Chunk size must be multiple of page size. Silently | 536 | * Chunk size must be multiple of page size. Silently |
536 | * round up if it's not. | 537 | * round up if it's not. |
537 | */ | 538 | */ |
538 | chunk_size = round_up(chunk_size, PAGE_SIZE >> 9); | 539 | chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9); |
539 | 540 | ||
540 | /* Check chunk_size is a power of 2 */ | 541 | /* Check chunk_size is a power of 2 */ |
541 | if (!is_power_of_2(chunk_size)) { | 542 | if (!is_power_of_2(chunk_size_ulong)) { |
542 | *error = "Chunk size is not a power of 2"; | 543 | *error = "Chunk size is not a power of 2"; |
543 | return -EINVAL; | 544 | return -EINVAL; |
544 | } | 545 | } |
545 | 546 | ||
546 | /* Validate the chunk size against the device block size */ | 547 | /* Validate the chunk size against the device block size */ |
547 | if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) { | 548 | if (chunk_size_ulong % (bdev_hardsect_size(s->cow->bdev) >> 9)) { |
548 | *error = "Chunk size is not a multiple of device blocksize"; | 549 | *error = "Chunk size is not a multiple of device blocksize"; |
549 | return -EINVAL; | 550 | return -EINVAL; |
550 | } | 551 | } |
551 | 552 | ||
552 | s->chunk_size = chunk_size; | 553 | *chunk_size = chunk_size_ulong; |
553 | s->chunk_mask = chunk_size - 1; | 554 | *chunk_mask = chunk_size_ulong - 1; |
554 | s->chunk_shift = ffs(chunk_size) - 1; | 555 | *chunk_shift = ffs(chunk_size_ulong) - 1; |
555 | 556 | ||
556 | return 0; | 557 | return 0; |
557 | } | 558 | } |
@@ -567,6 +568,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
567 | char persistent; | 568 | char persistent; |
568 | char *origin_path; | 569 | char *origin_path; |
569 | char *cow_path; | 570 | char *cow_path; |
571 | chunk_t chunk_size, chunk_mask, chunk_shift; | ||
570 | 572 | ||
571 | if (argc != 4) { | 573 | if (argc != 4) { |
572 | ti->error = "requires exactly 4 arguments"; | 574 | ti->error = "requires exactly 4 arguments"; |
@@ -606,7 +608,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
606 | goto bad2; | 608 | goto bad2; |
607 | } | 609 | } |
608 | 610 | ||
609 | r = set_chunk_size(s, argv[3], &ti->error); | 611 | r = set_chunk_size(s, argv[3], &chunk_size, &chunk_mask, &chunk_shift, |
612 | &ti->error); | ||
610 | if (r) | 613 | if (r) |
611 | goto bad3; | 614 | goto bad3; |
612 | 615 | ||
@@ -617,13 +620,14 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
617 | spin_lock_init(&s->pe_lock); | 620 | spin_lock_init(&s->pe_lock); |
618 | 621 | ||
619 | /* Allocate hash table for COW data */ | 622 | /* Allocate hash table for COW data */ |
620 | if (init_hash_tables(s)) { | 623 | if (init_hash_tables(s, chunk_shift)) { |
621 | ti->error = "Unable to allocate hash table space"; | 624 | ti->error = "Unable to allocate hash table space"; |
622 | r = -ENOMEM; | 625 | r = -ENOMEM; |
623 | goto bad3; | 626 | goto bad3; |
624 | } | 627 | } |
625 | 628 | ||
626 | r = dm_exception_store_create(argv[2], ti, &s->store); | 629 | r = dm_exception_store_create(argv[2], ti, chunk_size, chunk_mask, |
630 | chunk_shift, &s->store); | ||
627 | if (r) { | 631 | if (r) { |
628 | ti->error = "Couldn't create exception store"; | 632 | ti->error = "Couldn't create exception store"; |
629 | r = -EINVAL; | 633 | r = -EINVAL; |
@@ -680,7 +684,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
680 | } | 684 | } |
681 | 685 | ||
682 | ti->private = s; | 686 | ti->private = s; |
683 | ti->split_io = s->chunk_size; | 687 | ti->split_io = s->store->chunk_size; |
684 | 688 | ||
685 | return 0; | 689 | return 0; |
686 | 690 | ||
@@ -955,7 +959,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) | |||
955 | 959 | ||
956 | src.bdev = bdev; | 960 | src.bdev = bdev; |
957 | src.sector = chunk_to_sector(s, pe->e.old_chunk); | 961 | src.sector = chunk_to_sector(s, pe->e.old_chunk); |
958 | src.count = min(s->chunk_size, dev_size - src.sector); | 962 | src.count = min(s->store->chunk_size, dev_size - src.sector); |
959 | 963 | ||
960 | dest.bdev = s->cow->bdev; | 964 | dest.bdev = s->cow->bdev; |
961 | dest.sector = chunk_to_sector(s, pe->e.new_chunk); | 965 | dest.sector = chunk_to_sector(s, pe->e.new_chunk); |
@@ -1021,7 +1025,7 @@ static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e, | |||
1021 | bio->bi_bdev = s->cow->bdev; | 1025 | bio->bi_bdev = s->cow->bdev; |
1022 | bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) + | 1026 | bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) + |
1023 | (chunk - e->old_chunk)) + | 1027 | (chunk - e->old_chunk)) + |
1024 | (bio->bi_sector & s->chunk_mask); | 1028 | (bio->bi_sector & s->store->chunk_mask); |
1025 | } | 1029 | } |
1026 | 1030 | ||
1027 | static int snapshot_map(struct dm_target *ti, struct bio *bio, | 1031 | static int snapshot_map(struct dm_target *ti, struct bio *bio, |
@@ -1166,7 +1170,7 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, | |||
1166 | snprintf(result, maxlen, "%s %s %s %llu", | 1170 | snprintf(result, maxlen, "%s %s %s %llu", |
1167 | snap->origin->name, snap->cow->name, | 1171 | snap->origin->name, snap->cow->name, |
1168 | snap->store->type->name, | 1172 | snap->store->type->name, |
1169 | (unsigned long long)snap->chunk_size); | 1173 | (unsigned long long)snap->store->chunk_size); |
1170 | break; | 1174 | break; |
1171 | } | 1175 | } |
1172 | 1176 | ||
@@ -1377,7 +1381,8 @@ static void origin_resume(struct dm_target *ti) | |||
1377 | o = __lookup_origin(dev->bdev); | 1381 | o = __lookup_origin(dev->bdev); |
1378 | if (o) | 1382 | if (o) |
1379 | list_for_each_entry (snap, &o->snapshots, list) | 1383 | list_for_each_entry (snap, &o->snapshots, list) |
1380 | chunk_size = min_not_zero(chunk_size, snap->chunk_size); | 1384 | chunk_size = min_not_zero(chunk_size, |
1385 | snap->store->chunk_size); | ||
1381 | up_read(&_origins_lock); | 1386 | up_read(&_origins_lock); |
1382 | 1387 | ||
1383 | ti->split_io = chunk_size; | 1388 | ti->split_io = chunk_size; |