| diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c |
| index 426299ceb33d..0fa4f55728df 100644 |
| --- a/drivers/md/dm-verity-target.c |
| +++ b/drivers/md/dm-verity-target.c |
| @@ -16,6 +16,7 @@ |
| #include "dm-verity.h" |
| #include "dm-verity-fec.h" |
| #include "dm-verity-verify-sig.h" |
| +#include <linux/delay.h> |
| #include <linux/module.h> |
| #include <linux/reboot.h> |
| |
| @@ -48,6 +49,11 @@ struct dm_verity_prefetch_work { |
| unsigned n_blocks; |
| }; |
| |
| +/* Controls whether verity_get_device will wait forever for a device. */ |
| +static int dev_wait; |
| +module_param(dev_wait, int, 0444); |
| +MODULE_PARM_DESC(dev_wait, "Wait forever for a backing device"); |
| + |
| /* |
| * Auxiliary structure appended to each dm-bufio buffer. If the value |
| * hash_verified is nonzero, hash of the block has been verified. |
| @@ -1034,6 +1040,26 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, |
| return r; |
| } |
| |
| +static int verity_get_device(struct dm_target *ti, const char *devname, |
| + struct dm_dev **dm_dev) |
| +{ |
| + do { |
| + /* Try the normal path first since if everything is ready, it |
| + * will be the fastest. |
| + */ |
| + if (!dm_get_device(ti, devname, |
| + dm_table_get_mode(ti->table), dm_dev)) |
| + return 0; |
| + |
| + if (!dev_wait) |
| + break; |
| + |
| + /* No need to be too aggressive since this is a slow path. */ |
| + msleep(500); |
| + } while (dev_wait && (driver_probe_done() != 0 || *dm_dev == NULL)); |
| + return -1; |
| +} |
| + |
| /* |
| * Target parameters: |
| * <version> The current format is version 1. |
| @@ -1093,13 +1119,13 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv) |
| } |
| v->version = num; |
| |
| - r = dm_get_device(ti, argv[1], FMODE_READ, &v->data_dev); |
| + r = verity_get_device(ti, argv[1], &v->data_dev); |
| if (r) { |
| ti->error = "Data device lookup failed"; |
| goto bad; |
| } |
| |
| - r = dm_get_device(ti, argv[2], FMODE_READ, &v->hash_dev); |
| + r = verity_get_device(ti, argv[2], &v->hash_dev); |
| if (r) { |
| ti->error = "Hash device lookup failed"; |
| goto bad; |