Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Side by Side Diff: drivers/md/dm-verity.c

Issue 6739006: CHROMIUM: verity: only requeue if necessary (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Fix per reviewl. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « drivers/md/dm-bht.c ('k') | include/linux/dm-bht.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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");
OLDNEW
« no previous file with comments | « drivers/md/dm-bht.c ('k') | include/linux/dm-bht.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698