OLD | NEW |
1 /* | 1 /* |
2 * Originally based on dm-crypt.c, | 2 * Originally based on dm-crypt.c, |
3 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> | 3 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> |
4 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> | 4 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> |
5 * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. | 5 * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. |
6 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> | 6 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> |
7 * All Rights Reserved. | 7 * All Rights Reserved. |
8 * | 8 * |
9 * This file is released under the GPL. | 9 * This file is released under the GPL. |
10 * | 10 * |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 175 |
176 char hash_alg[CRYPTO_MAX_ALG_NAME]; | 176 char hash_alg[CRYPTO_MAX_ALG_NAME]; |
177 | 177 |
178 int error_behavior; | 178 int error_behavior; |
179 | 179 |
180 struct verity_stats stats; | 180 struct verity_stats stats; |
181 }; | 181 }; |
182 | 182 |
183 static struct kmem_cache *_verity_io_pool; | 183 static struct kmem_cache *_verity_io_pool; |
184 | 184 |
185 static void kverityd_queue_verify(struct dm_verity_io *io); | 185 static void kverityd_verify(struct work_struct *work); |
186 static void kverityd_queue_io(struct dm_verity_io *io, bool delayed); | 186 static void kverityd_io(struct work_struct *work); |
187 static void kverityd_io_bht_populate(struct dm_verity_io *io); | 187 static void kverityd_io_bht_populate(struct dm_verity_io *io); |
188 static void kverityd_io_bht_populate_end(struct bio *, int error); | 188 static void kverityd_io_bht_populate_end(struct bio *, int error); |
189 | 189 |
190 static BLOCKING_NOTIFIER_HEAD(verity_error_notifier); | 190 static BLOCKING_NOTIFIER_HEAD(verity_error_notifier); |
191 | 191 |
192 /*----------------------------------------------- | 192 /*----------------------------------------------- |
193 * Statistic tracking functions | 193 * Statistic tracking functions |
194 *-----------------------------------------------*/ | 194 *-----------------------------------------------*/ |
195 | 195 |
196 void verity_stats_pending_bio_inc(struct verity_config *vc) | 196 void verity_stats_pending_bio_inc(struct verity_config *vc) |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 { | 597 { |
598 struct verity_config *vc = io->target->private; | 598 struct verity_config *vc = io->target->private; |
599 | 599 |
600 if (io->error) | 600 if (io->error) |
601 verity_error(vc, io, io->error); | 601 verity_error(vc, io, io->error); |
602 | 602 |
603 bio_endio(io->bio, io->error); | 603 bio_endio(io->bio, io->error); |
604 mempool_free(io, vc->io_pool); | 604 mempool_free(io, vc->io_pool); |
605 } | 605 } |
606 | 606 |
| 607 /* Check for any missing bht hashes. */ |
| 608 static bool verity_is_bht_populated(struct dm_verity_io *io) |
| 609 { |
| 610 struct verity_config *vc = io->target->private; |
| 611 sector_t count; |
| 612 |
| 613 for (count = 0; count < io->count; ++count) |
| 614 if (!dm_bht_is_populated(&vc->bht, io->block + count)) |
| 615 return false; |
| 616 |
| 617 return true; |
| 618 } |
| 619 |
607 /* verity_dec_pending manages the lifetime of all dm_verity_io structs. | 620 /* verity_dec_pending manages the lifetime of all dm_verity_io structs. |
608 * Non-bug error handling is centralized through this interface and | 621 * Non-bug error handling is centralized through this interface and |
609 * all passage from workqueue to workqueue. | 622 * all passage from workqueue to workqueue. |
610 */ | 623 */ |
611 static void verity_dec_pending(struct dm_verity_io *io) | 624 static void verity_dec_pending(struct dm_verity_io *io) |
612 { | 625 { |
613 struct verity_config *vc = io->target->private; | 626 struct verity_config *vc = io->target->private; |
614 VERITY_BUG_ON(!io, "NULL argument"); | 627 VERITY_BUG_ON(!io, "NULL argument"); |
615 | 628 |
616 DMDEBUG("dec pending %p: %d--", io, atomic_read(&io->pending)); | 629 DMDEBUG("dec pending %p: %d--", io, atomic_read(&io->pending)); |
617 | 630 |
618 if (!atomic_dec_and_test(&io->pending)) | 631 if (!atomic_dec_and_test(&io->pending)) |
619 goto done; | 632 goto done; |
620 | 633 |
621 if (unlikely(io->error)) | 634 if (unlikely(io->error)) |
622 goto io_error; | 635 goto io_error; |
623 | 636 |
624 » if (io->flags & VERITY_IOFLAGS_PENDING) { | 637 » /* I/Os that were pending may now be ready */ |
| 638 » if ((io->flags & VERITY_IOFLAGS_PENDING) && |
| 639 » !verity_is_bht_populated(io)) { |
625 io->flags &= ~VERITY_IOFLAGS_PENDING; | 640 io->flags &= ~VERITY_IOFLAGS_PENDING; |
626 » » kverityd_queue_io(io, true); | 641 » » INIT_DELAYED_WORK(&io->work, kverityd_io); |
627 » » DMDEBUG("io %p requeued for io"); | 642 » » queue_delayed_work(vc->io_queue, &io->work, HZ/10); |
| 643 » » verity_stats_total_requeues_inc(vc); |
| 644 » » REQTRACE("Block %llu+ is being requeued for io (io:%p)", |
| 645 » » » ULL(io->block), io); |
628 } else { | 646 } else { |
| 647 io->flags &= ~VERITY_IOFLAGS_PENDING; |
629 verity_stats_io_queue_dec(vc); | 648 verity_stats_io_queue_dec(vc); |
630 verity_stats_verify_queue_inc(vc); | 649 verity_stats_verify_queue_inc(vc); |
631 » » kverityd_queue_verify(io); | 650 » » INIT_DELAYED_WORK(&io->work, kverityd_verify); |
632 » » DMDEBUG("io %p enqueued for verify"); | 651 » » queue_delayed_work(vc->verify_queue, &io->work, 0); |
| 652 » » REQTRACE("Block %llu+ is being queued for verify (io:%p)", |
| 653 » » » ULL(io->block), io); |
633 } | 654 } |
634 | 655 |
635 done: | 656 done: |
636 return; | 657 return; |
637 | 658 |
638 io_error: | 659 io_error: |
639 verity_return_bio_to_caller(io); | 660 verity_return_bio_to_caller(io); |
640 } | 661 } |
641 | 662 |
642 /* Walks the data set and computes the hash of the data read from the | 663 /* Walks the data set and computes the hash of the data read from the |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 work); | 724 work); |
704 struct verity_config *vc = io->target->private; | 725 struct verity_config *vc = io->target->private; |
705 | 726 |
706 io->error = verity_verify(vc, io->bio); | 727 io->error = verity_verify(vc, io->bio); |
707 | 728 |
708 /* Free up the bio and tag with the return value */ | 729 /* Free up the bio and tag with the return value */ |
709 verity_stats_verify_queue_dec(vc); | 730 verity_stats_verify_queue_dec(vc); |
710 verity_return_bio_to_caller(io); | 731 verity_return_bio_to_caller(io); |
711 } | 732 } |
712 | 733 |
713 /* After all I/O is completed successfully for a request, it is queued on the | |
714 * verify workqueue to ensure its integrity prior to returning it to the | |
715 * caller. There may be multiple workqueue threads - one per logical | |
716 * processor. | |
717 */ | |
718 static void kverityd_queue_verify(struct dm_verity_io *io) | |
719 { | |
720 struct verity_config *vc = io->target->private; | |
721 REQTRACE("Block %llu+ is being queued for verify (io:%p)", | |
722 ULL(io->block), io); | |
723 INIT_DELAYED_WORK(&io->work, kverityd_verify); | |
724 /* No delay needed. But if we move over jobs with pending io, then | |
725 * we could probably delay them here. | |
726 */ | |
727 queue_delayed_work(vc->verify_queue, &io->work, 0); | |
728 } | |
729 | |
730 /* Asynchronously called upon the completion of dm-bht I/O. The status | 734 /* Asynchronously called upon the completion of dm-bht I/O. The status |
731 * of the operation is passed back to dm-bht and the next steps are | 735 * of the operation is passed back to dm-bht and the next steps are |
732 * decided by verity_dec_pending. | 736 * decided by verity_dec_pending. |
733 */ | 737 */ |
734 static void kverityd_io_bht_populate_end(struct bio *bio, int error) | 738 static void kverityd_io_bht_populate_end(struct bio *bio, int error) |
735 { | 739 { |
736 struct dm_bht_entry *entry = (struct dm_bht_entry *) bio->bi_private; | 740 struct dm_bht_entry *entry = (struct dm_bht_entry *) bio->bi_private; |
737 struct dm_verity_io *io = (struct dm_verity_io *) entry->io_context; | 741 struct dm_verity_io *io = (struct dm_verity_io *) entry->io_context; |
738 | 742 |
739 DMDEBUG("kverityd_io_bht_populate_end (io:%p, entry:%p)", io, entry); | 743 DMDEBUG("kverityd_io_bht_populate_end (io:%p, entry:%p)", io, entry); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 work); | 966 work); |
963 VERITY_BUG_ON(!io->bio); | 967 VERITY_BUG_ON(!io->bio); |
964 | 968 |
965 /* Issue requests asynchronously. */ | 969 /* Issue requests asynchronously. */ |
966 verity_inc_pending(io); | 970 verity_inc_pending(io); |
967 kverityd_src_io_read(io); | 971 kverityd_src_io_read(io); |
968 kverityd_io_bht_populate(io); | 972 kverityd_io_bht_populate(io); |
969 verity_dec_pending(io); | 973 verity_dec_pending(io); |
970 } | 974 } |
971 | 975 |
972 /* All incoming requests are queued on the I/O workqueue at least once to | |
973 * acquire both the data from the real device (vc->dev) and any data from the | |
974 * hash tree device (vc->hash_dev) needed to verify the integrity of the data. | |
975 * There may be multiple I/O workqueues - one per logical processor. | |
976 */ | |
977 static void kverityd_queue_io(struct dm_verity_io *io, bool delayed) | |
978 { | |
979 struct verity_config *vc = io->target->private; | |
980 unsigned long delay = 0; /* jiffies */ | |
981 /* Send all requests through one call to dm_bht_populate on the | |
982 * queue to ensure that all blocks are accounted for before | |
983 * proceeding on to verification. | |
984 */ | |
985 INIT_DELAYED_WORK(&io->work, kverityd_io); | |
986 /* If this context is dependent on work from another context, we just | |
987 * requeue with a delay. Later we could bounce this work to the verify | |
988 * queue and have it wait there. TODO(wad) | |
989 */ | |
990 if (delayed) { | |
991 verity_stats_total_requeues_inc(vc); | |
992 delay = HZ / 10; | |
993 REQTRACE("block %llu+ is being delayed %lu jiffies (io:%p)", | |
994 ULL(io->block), delay, io); | |
995 } | |
996 queue_delayed_work(vc->io_queue, &io->work, delay); | |
997 } | |
998 | |
999 /* Paired with verity_dec_pending, the pending value in the io dictate the | 976 /* Paired with verity_dec_pending, the pending value in the io dictate the |
1000 * lifetime of a request and when it is ready to be processed on the | 977 * lifetime of a request and when it is ready to be processed on the |
1001 * workqueues. | 978 * workqueues. |
1002 */ | 979 */ |
1003 static void verity_inc_pending(struct dm_verity_io *io) | 980 static void verity_inc_pending(struct dm_verity_io *io) |
1004 { | 981 { |
1005 atomic_inc(&io->pending); | 982 atomic_inc(&io->pending); |
1006 } | 983 } |
1007 | 984 |
1008 /* Block-level requests start here. */ | 985 /* Block-level requests start here. */ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 VERITY_BUG_ON(bio->bi_sector % to_sector(VERITY_BLOCK_SIZE)); | 1028 VERITY_BUG_ON(bio->bi_sector % to_sector(VERITY_BLOCK_SIZE)); |
1052 VERITY_BUG_ON(bio->bi_size % VERITY_BLOCK_SIZE); | 1029 VERITY_BUG_ON(bio->bi_size % VERITY_BLOCK_SIZE); |
1053 | 1030 |
1054 /* Queue up the request to be verified */ | 1031 /* Queue up the request to be verified */ |
1055 io = verity_io_alloc(ti, bio, bio->bi_sector - ti->begin); | 1032 io = verity_io_alloc(ti, bio, bio->bi_sector - ti->begin); |
1056 if (!io) { | 1033 if (!io) { |
1057 DMERR_LIMIT("Failed to allocate and init IO data"); | 1034 DMERR_LIMIT("Failed to allocate and init IO data"); |
1058 return DM_MAPIO_REQUEUE; | 1035 return DM_MAPIO_REQUEUE; |
1059 } | 1036 } |
1060 verity_stats_io_queue_inc(vc); | 1037 verity_stats_io_queue_inc(vc); |
1061 » » kverityd_queue_io(io, false); | 1038 » » INIT_DELAYED_WORK(&io->work, kverityd_io); |
| 1039 » » queue_delayed_work(vc->io_queue, &io->work, 0); |
1062 } | 1040 } |
1063 | 1041 |
1064 return DM_MAPIO_SUBMITTED; | 1042 return DM_MAPIO_SUBMITTED; |
1065 } | 1043 } |
1066 | 1044 |
1067 /* | 1045 /* |
1068 * Non-block interfaces and device-mapper specific code | 1046 * Non-block interfaces and device-mapper specific code |
1069 */ | 1047 */ |
1070 | 1048 |
1071 /* | 1049 /* |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 dm_unregister_target(&verity_target); | 1409 dm_unregister_target(&verity_target); |
1432 kmem_cache_destroy(_verity_io_pool); | 1410 kmem_cache_destroy(_verity_io_pool); |
1433 } | 1411 } |
1434 | 1412 |
1435 module_init(dm_verity_init); | 1413 module_init(dm_verity_init); |
1436 module_exit(dm_verity_exit); | 1414 module_exit(dm_verity_exit); |
1437 | 1415 |
1438 MODULE_AUTHOR("The Chromium OS Authors <chromium-os-dev@chromium.org>"); | 1416 MODULE_AUTHOR("The Chromium OS Authors <chromium-os-dev@chromium.org>"); |
1439 MODULE_DESCRIPTION(DM_NAME " target for transparent disk integrity checking"); | 1417 MODULE_DESCRIPTION(DM_NAME " target for transparent disk integrity checking"); |
1440 MODULE_LICENSE("GPL"); | 1418 MODULE_LICENSE("GPL"); |
OLD | NEW |