dm snapshot: extend exception store functions

Supply dm_add_exception as a callback to the read_metadata function.
Add a status function ready for a later patch and name the functions
consistently.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

authored by

Jonathan Brassow and committed by
Alasdair G Kergon
a159c1ac 4db6bfe0

+55 -37
-1
drivers/md/dm-exception-store.c
··· 11 #include <linux/pagemap.h> 12 #include <linux/vmalloc.h> 13 #include <linux/slab.h> 14 - #include <linux/device-mapper.h> 15 16 #define DM_MSG_PREFIX "snapshot exception stores" 17
··· 11 #include <linux/pagemap.h> 12 #include <linux/vmalloc.h> 13 #include <linux/slab.h> 14 15 #define DM_MSG_PREFIX "snapshot exception stores" 16
+10 -3
drivers/md/dm-exception-store.h
··· 11 #define _LINUX_DM_EXCEPTION_STORE 12 13 #include <linux/blkdev.h> 14 15 /* 16 * The snapshot code deals with largish chunks of the disk at a ··· 38 * COW device). 39 */ 40 struct dm_exception_store { 41 - 42 /* 43 * Destroys this object when you've finished with it. 44 */ ··· 45 46 /* 47 * The target shouldn't read the COW device until this is 48 - * called. 49 */ 50 - int (*read_metadata) (struct dm_exception_store *store); 51 52 /* 53 * Find somewhere to store the next exception. ··· 71 * The snapshot is invalid, note this in the metadata. 72 */ 73 void (*drop_snapshot) (struct dm_exception_store *store); 74 75 /* 76 * Return how full the snapshot is.
··· 11 #define _LINUX_DM_EXCEPTION_STORE 12 13 #include <linux/blkdev.h> 14 + #include <linux/device-mapper.h> 15 16 /* 17 * The snapshot code deals with largish chunks of the disk at a ··· 37 * COW device). 38 */ 39 struct dm_exception_store { 40 /* 41 * Destroys this object when you've finished with it. 42 */ ··· 45 46 /* 47 * The target shouldn't read the COW device until this is 48 + * called. As exceptions are read from the COW, they are 49 + * reported back via the callback. 50 */ 51 + int (*read_metadata) (struct dm_exception_store *store, 52 + int (*callback)(void *callback_context, 53 + chunk_t old, chunk_t new), 54 + void *callback_context); 55 56 /* 57 * Find somewhere to store the next exception. ··· 67 * The snapshot is invalid, note this in the metadata. 68 */ 69 void (*drop_snapshot) (struct dm_exception_store *store); 70 + 71 + int (*status) (struct dm_exception_store *store, status_type_t status, 72 + char *result, unsigned int maxlen); 73 74 /* 75 * Return how full the snapshot is.
+26 -16
drivers/md/dm-snap-persistent.c
··· 395 * 'full' is filled in to indicate if the area has been 396 * filled. 397 */ 398 - static int insert_exceptions(struct pstore *ps, int *full) 399 { 400 int r; 401 unsigned int i; ··· 432 /* 433 * Otherwise we add the exception to the snapshot. 434 */ 435 - r = dm_add_exception(ps->snap, de.old_chunk, de.new_chunk); 436 if (r) 437 return r; 438 } ··· 440 return 0; 441 } 442 443 - static int read_exceptions(struct pstore *ps) 444 { 445 int r, full = 1; 446 ··· 456 if (r) 457 return r; 458 459 - r = insert_exceptions(ps, &full); 460 if (r) 461 return r; 462 } ··· 489 kfree(ps); 490 } 491 492 - static int persistent_read_metadata(struct dm_exception_store *store) 493 { 494 int r, uninitialized_var(new_snapshot); 495 struct pstore *ps = get_info(store); ··· 550 /* 551 * Read the metadata. 552 */ 553 - r = read_exceptions(ps); 554 if (r) 555 return r; 556 } ··· 558 return 0; 559 } 560 561 - static int persistent_prepare(struct dm_exception_store *store, 562 - struct dm_snap_exception *e) 563 { 564 struct pstore *ps = get_info(store); 565 uint32_t stride; ··· 585 return 0; 586 } 587 588 - static void persistent_commit(struct dm_exception_store *store, 589 - struct dm_snap_exception *e, 590 - void (*callback) (void *, int success), 591 - void *callback_context) 592 { 593 unsigned int i; 594 struct pstore *ps = get_info(store); ··· 647 ps->callback_count = 0; 648 } 649 650 - static void persistent_drop(struct dm_exception_store *store) 651 { 652 struct pstore *ps = get_info(store); 653 ··· 685 686 store->destroy = persistent_destroy; 687 store->read_metadata = persistent_read_metadata; 688 - store->prepare_exception = persistent_prepare; 689 - store->commit_exception = persistent_commit; 690 - store->drop_snapshot = persistent_drop; 691 store->fraction_full = persistent_fraction_full; 692 store->context = ps; 693
··· 395 * 'full' is filled in to indicate if the area has been 396 * filled. 397 */ 398 + static int insert_exceptions(struct pstore *ps, 399 + int (*callback)(void *callback_context, 400 + chunk_t old, chunk_t new), 401 + void *callback_context, 402 + int *full) 403 { 404 int r; 405 unsigned int i; ··· 428 /* 429 * Otherwise we add the exception to the snapshot. 430 */ 431 + r = callback(callback_context, de.old_chunk, de.new_chunk); 432 if (r) 433 return r; 434 } ··· 436 return 0; 437 } 438 439 + static int read_exceptions(struct pstore *ps, 440 + int (*callback)(void *callback_context, chunk_t old, 441 + chunk_t new), 442 + void *callback_context) 443 { 444 int r, full = 1; 445 ··· 449 if (r) 450 return r; 451 452 + r = insert_exceptions(ps, callback, callback_context, &full); 453 if (r) 454 return r; 455 } ··· 482 kfree(ps); 483 } 484 485 + static int persistent_read_metadata(struct dm_exception_store *store, 486 + int (*callback)(void *callback_context, 487 + chunk_t old, chunk_t new), 488 + void *callback_context) 489 { 490 int r, uninitialized_var(new_snapshot); 491 struct pstore *ps = get_info(store); ··· 540 /* 541 * Read the metadata. 542 */ 543 + r = read_exceptions(ps, callback, callback_context); 544 if (r) 545 return r; 546 } ··· 548 return 0; 549 } 550 551 + static int persistent_prepare_exception(struct dm_exception_store *store, 552 + struct dm_snap_exception *e) 553 { 554 struct pstore *ps = get_info(store); 555 uint32_t stride; ··· 575 return 0; 576 } 577 578 + static void persistent_commit_exception(struct dm_exception_store *store, 579 + struct dm_snap_exception *e, 580 + void (*callback) (void *, int success), 581 + void *callback_context) 582 { 583 unsigned int i; 584 struct pstore *ps = get_info(store); ··· 637 ps->callback_count = 0; 638 } 639 640 + static void persistent_drop_snapshot(struct dm_exception_store *store) 641 { 642 struct pstore *ps = get_info(store); 643 ··· 675 676 store->destroy = persistent_destroy; 677 store->read_metadata = persistent_read_metadata; 678 + store->prepare_exception = persistent_prepare_exception; 679 + store->commit_exception = persistent_commit_exception; 680 + store->drop_snapshot = persistent_drop_snapshot; 681 store->fraction_full = persistent_fraction_full; 682 store->context = ps; 683
+12 -9
drivers/md/dm-snap-transient.c
··· 28 kfree(store->context); 29 } 30 31 - static int transient_read_metadata(struct dm_exception_store *store) 32 { 33 return 0; 34 } 35 36 - static int transient_prepare(struct dm_exception_store *store, 37 - struct dm_snap_exception *e) 38 { 39 struct transient_c *tc = (struct transient_c *) store->context; 40 sector_t size = get_dev_size(store->snap->cow->bdev); ··· 51 return 0; 52 } 53 54 - static void transient_commit(struct dm_exception_store *store, 55 - struct dm_snap_exception *e, 56 - void (*callback) (void *, int success), 57 - void *callback_context) 58 { 59 /* Just succeed */ 60 callback(callback_context, 1); ··· 73 74 store->destroy = transient_destroy; 75 store->read_metadata = transient_read_metadata; 76 - store->prepare_exception = transient_prepare; 77 - store->commit_exception = transient_commit; 78 store->drop_snapshot = NULL; 79 store->fraction_full = transient_fraction_full; 80
··· 28 kfree(store->context); 29 } 30 31 + static int transient_read_metadata(struct dm_exception_store *store, 32 + int (*callback)(void *callback_context, 33 + chunk_t old, chunk_t new), 34 + void *callback_context) 35 { 36 return 0; 37 } 38 39 + static int transient_prepare_exception(struct dm_exception_store *store, 40 + struct dm_snap_exception *e) 41 { 42 struct transient_c *tc = (struct transient_c *) store->context; 43 sector_t size = get_dev_size(store->snap->cow->bdev); ··· 48 return 0; 49 } 50 51 + static void transient_commit_exception(struct dm_exception_store *store, 52 + struct dm_snap_exception *e, 53 + void (*callback) (void *, int success), 54 + void *callback_context) 55 { 56 /* Just succeed */ 57 callback(callback_context, 1); ··· 70 71 store->destroy = transient_destroy; 72 store->read_metadata = transient_read_metadata; 73 + store->prepare_exception = transient_prepare_exception; 74 + store->commit_exception = transient_commit_exception; 75 store->drop_snapshot = NULL; 76 store->fraction_full = transient_fraction_full; 77
+7 -2
drivers/md/dm-snap.c
··· 430 list_add(&new_e->hash_list, e ? &e->hash_list : l); 431 } 432 433 - int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new) 434 { 435 struct dm_snap_exception *e; 436 437 e = alloc_exception(); ··· 665 spin_lock_init(&s->tracked_chunk_lock); 666 667 /* Metadata must only be loaded into one table at once */ 668 - r = s->store.read_metadata(&s->store); 669 if (r < 0) { 670 ti->error = "Failed to read snapshot metadata"; 671 goto bad_load_and_register;
··· 430 list_add(&new_e->hash_list, e ? &e->hash_list : l); 431 } 432 433 + /* 434 + * Callback used by the exception stores to load exceptions when 435 + * initialising. 436 + */ 437 + static int dm_add_exception(void *context, chunk_t old, chunk_t new) 438 { 439 + struct dm_snapshot *s = context; 440 struct dm_snap_exception *e; 441 442 e = alloc_exception(); ··· 660 spin_lock_init(&s->tracked_chunk_lock); 661 662 /* Metadata must only be loaded into one table at once */ 663 + r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s); 664 if (r < 0) { 665 ti->error = "Failed to read snapshot metadata"; 666 goto bad_load_and_register;
-6
drivers/md/dm-snap.h
··· 76 }; 77 78 /* 79 - * Used by the exception stores to load exceptions hen 80 - * initialising. 81 - */ 82 - int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new); 83 - 84 - /* 85 * Return the number of sectors in the device. 86 */ 87 static inline sector_t get_dev_size(struct block_device *bdev)
··· 76 }; 77 78 /* 79 * Return the number of sectors in the device. 80 */ 81 static inline sector_t get_dev_size(struct block_device *bdev)