- Add DM verity support for signature verification with 2nd keyring.
- Fix DM verity to skip verity work if IO completes with error while system is shutting down. - Add new DM multipath "IO affinity" path selector that maps IO destined to a given path to a specific CPU based on user provided mapping. - Rename DM multipath path selector source files to have "dm-ps" prefix. - Add REQ_NOWAIT support to some other simple DM targets that don't block in more elaborate ways waiting for IO. - Export DM crypt's kcryptd workqueue via sysfs (WQ_SYSFS). - Fix error return code in DM's target_message() if empty message is received. - A handful of other small cleanups. -----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEJfWUX4UqZ4x1O2wixSPxCi2dA1oFAl/iDJYTHHNuaXR6ZXJA cmVkaGF0LmNvbQAKCRDFI/EKLZ0DWsI2CACUk9PCCtOOHH1s//VeLjF86VUIsuxf hNMfTgWT+arlHUIzl2Bp4c4Dq/T+hXTYlf+f5zGRAbBAd82eCqji5LTVvy/qaYt3 4gWSZnv/3VYHCx4MvV9UjtXQcSnS/ttDwyV0ZD6/NtYllQQobaCbyrE4p2tA1GIk ql8ESRgXKK5Sio197Tm45UEkrhG0oUrEZ3riBaXeM9yOldLp1mLLVPGJeLcJDvpA N7TDcM0owq/CMbmu5BkNv0xw7q/Vc9VQLGva8a15StxGjk1HY5/6KQWssCEkTkO7 HnIprATtWz2r0qgTcI+fOXndUmlqgQr1jhvYfJeuv45KbjoI5qubZvYr =vHNj -----END PGP SIGNATURE----- Merge tag 'for-5.11/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm Pull device mapper updates from Mike Snitzer: - Add DM verity support for signature verification with 2nd keyring - Fix DM verity to skip verity work if IO completes with error while system is shutting down - Add new DM multipath "IO affinity" path selector that maps IO destined to a given path to a specific CPU based on user provided mapping - Rename DM multipath path selector source files to have "dm-ps" prefix - Add REQ_NOWAIT support to some other simple DM targets that don't block in more elaborate ways waiting for IO - Export DM crypt's kcryptd workqueue via sysfs (WQ_SYSFS) - Fix error return code in DM's target_message() if empty message is received - A handful of other small cleanups * tag 'for-5.11/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm cache: simplify the return expression of load_mapping() dm ebs: avoid double unlikely() notation when using IS_ERR() dm verity: skip verity work if I/O error when system is shutting down dm crypt: export sysfs of kcryptd workqueue dm ioctl: fix error return code in target_message dm crypt: Constify static crypt_iv_operations dm: add support for REQ_NOWAIT to various targets dm: rename multipath path selector source files to have "dm-ps" prefix dm mpath: add IO affinity path selector dm verity: Add support for signature verification with 2nd keyring dm: remove unnecessary current->bio_list check when submitting split bio
This commit is contained in:
commit
d8355e740f
|
@ -134,7 +134,12 @@ root_hash_sig_key_desc <key_description>
|
|||
the pkcs7 signature of the roothash. The pkcs7 signature is used to validate
|
||||
the root hash during the creation of the device mapper block device.
|
||||
Verification of roothash depends on the config DM_VERITY_VERIFY_ROOTHASH_SIG
|
||||
being set in the kernel.
|
||||
being set in the kernel. The signatures are checked against the builtin
|
||||
trusted keyring by default, or the secondary trusted keyring if
|
||||
DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING is set. The secondary
|
||||
trusted keyring includes by default the builtin trusted keyring, and it can
|
||||
also gain new certificates at run time if they are signed by a certificate
|
||||
already in the secondary trusted keyring.
|
||||
|
||||
Theory of operation
|
||||
===================
|
||||
|
|
|
@ -463,6 +463,15 @@ config DM_MULTIPATH_HST
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config DM_MULTIPATH_IOA
|
||||
tristate "I/O Path Selector based on CPU submission"
|
||||
depends on DM_MULTIPATH
|
||||
help
|
||||
This path selector selects the path based on the CPU the IO is
|
||||
executed on and the CPU to path mapping setup at path addition time.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config DM_DELAY
|
||||
tristate "I/O delaying target"
|
||||
depends on BLK_DEV_DM
|
||||
|
@ -530,11 +539,22 @@ config DM_VERITY_VERIFY_ROOTHASH_SIG
|
|||
bool "Verity data device root hash signature verification support"
|
||||
depends on DM_VERITY
|
||||
select SYSTEM_DATA_VERIFICATION
|
||||
help
|
||||
help
|
||||
Add ability for dm-verity device to be validated if the
|
||||
pre-generated tree of cryptographic checksums passed has a pkcs#7
|
||||
signature file that can validate the roothash of the tree.
|
||||
|
||||
By default, rely on the builtin trusted keyring.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
|
||||
bool "Verity data device root hash signature verification with secondary keyring"
|
||||
depends on DM_VERITY_VERIFY_ROOTHASH_SIG
|
||||
depends on SECONDARY_TRUSTED_KEYRING
|
||||
help
|
||||
Rely on the secondary trusted keyring to verify dm-verity signatures.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config DM_VERITY_FEC
|
||||
|
|
|
@ -7,23 +7,28 @@ dm-mod-y += dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
|
|||
dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o dm-stats.o \
|
||||
dm-rq.o
|
||||
dm-multipath-y += dm-path-selector.o dm-mpath.o
|
||||
dm-historical-service-time-y += dm-ps-historical-service-time.o
|
||||
dm-io-affinity-y += dm-ps-io-affinity.o
|
||||
dm-queue-length-y += dm-ps-queue-length.o
|
||||
dm-round-robin-y += dm-ps-round-robin.o
|
||||
dm-service-time-y += dm-ps-service-time.o
|
||||
dm-snapshot-y += dm-snap.o dm-exception-store.o dm-snap-transient.o \
|
||||
dm-snap-persistent.o
|
||||
dm-mirror-y += dm-raid1.o
|
||||
dm-log-userspace-y \
|
||||
+= dm-log-userspace-base.o dm-log-userspace-transfer.o
|
||||
dm-log-userspace-y += dm-log-userspace-base.o dm-log-userspace-transfer.o
|
||||
dm-bio-prison-y += dm-bio-prison-v1.o dm-bio-prison-v2.o
|
||||
dm-thin-pool-y += dm-thin.o dm-thin-metadata.o
|
||||
dm-cache-y += dm-cache-target.o dm-cache-metadata.o dm-cache-policy.o \
|
||||
dm-cache-background-tracker.o
|
||||
dm-cache-smq-y += dm-cache-policy-smq.o
|
||||
dm-cache-smq-y += dm-cache-policy-smq.o
|
||||
dm-ebs-y += dm-ebs-target.o
|
||||
dm-era-y += dm-era-target.o
|
||||
dm-clone-y += dm-clone-target.o dm-clone-metadata.o
|
||||
dm-verity-y += dm-verity-target.o
|
||||
dm-zoned-y += dm-zoned-target.o dm-zoned-metadata.o dm-zoned-reclaim.o
|
||||
|
||||
md-mod-y += md.o md-bitmap.o
|
||||
raid456-y += raid5.o raid5-cache.o raid5-ppl.o
|
||||
dm-zoned-y += dm-zoned-target.o dm-zoned-metadata.o dm-zoned-reclaim.o
|
||||
linear-y += md-linear.o
|
||||
multipath-y += md-multipath.o
|
||||
faulty-y += md-faulty.o
|
||||
|
@ -59,14 +64,15 @@ obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o
|
|||
obj-$(CONFIG_DM_MULTIPATH_QL) += dm-queue-length.o
|
||||
obj-$(CONFIG_DM_MULTIPATH_ST) += dm-service-time.o
|
||||
obj-$(CONFIG_DM_MULTIPATH_HST) += dm-historical-service-time.o
|
||||
obj-$(CONFIG_DM_MULTIPATH_IOA) += dm-io-affinity.o
|
||||
obj-$(CONFIG_DM_SWITCH) += dm-switch.o
|
||||
obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o
|
||||
obj-$(CONFIG_DM_PERSISTENT_DATA) += persistent-data/
|
||||
obj-$(CONFIG_DM_PERSISTENT_DATA) += persistent-data/
|
||||
obj-$(CONFIG_DM_MIRROR) += dm-mirror.o dm-log.o dm-region-hash.o
|
||||
obj-$(CONFIG_DM_LOG_USERSPACE) += dm-log-userspace.o
|
||||
obj-$(CONFIG_DM_ZERO) += dm-zero.o
|
||||
obj-$(CONFIG_DM_RAID) += dm-raid.o
|
||||
obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o
|
||||
obj-$(CONFIG_DM_RAID) += dm-raid.o
|
||||
obj-$(CONFIG_DM_THIN_PROVISIONING) += dm-thin-pool.o
|
||||
obj-$(CONFIG_DM_VERITY) += dm-verity.o
|
||||
obj-$(CONFIG_DM_CACHE) += dm-cache.o
|
||||
obj-$(CONFIG_DM_CACHE_SMQ) += dm-cache-smq.o
|
||||
|
|
|
@ -2840,7 +2840,6 @@ static void cache_postsuspend(struct dm_target *ti)
|
|||
static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
|
||||
bool dirty, uint32_t hint, bool hint_valid)
|
||||
{
|
||||
int r;
|
||||
struct cache *cache = context;
|
||||
|
||||
if (dirty) {
|
||||
|
@ -2849,11 +2848,7 @@ static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock,
|
|||
} else
|
||||
clear_bit(from_cblock(cblock), cache->dirty_bitset);
|
||||
|
||||
r = policy_load_mapping(cache->policy, oblock, cblock, dirty, hint, hint_valid);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
return policy_load_mapping(cache->policy, oblock, cblock, dirty, hint, hint_valid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1090,16 +1090,16 @@ static const struct crypt_iv_operations crypt_iv_tcw_ops = {
|
|||
.post = crypt_iv_tcw_post
|
||||
};
|
||||
|
||||
static struct crypt_iv_operations crypt_iv_random_ops = {
|
||||
static const struct crypt_iv_operations crypt_iv_random_ops = {
|
||||
.generator = crypt_iv_random_gen
|
||||
};
|
||||
|
||||
static struct crypt_iv_operations crypt_iv_eboiv_ops = {
|
||||
static const struct crypt_iv_operations crypt_iv_eboiv_ops = {
|
||||
.ctr = crypt_iv_eboiv_ctr,
|
||||
.generator = crypt_iv_eboiv_gen
|
||||
};
|
||||
|
||||
static struct crypt_iv_operations crypt_iv_elephant_ops = {
|
||||
static const struct crypt_iv_operations crypt_iv_elephant_ops = {
|
||||
.ctr = crypt_iv_elephant_ctr,
|
||||
.dtr = crypt_iv_elephant_dtr,
|
||||
.init = crypt_iv_elephant_init,
|
||||
|
@ -3166,11 +3166,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
}
|
||||
|
||||
if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags))
|
||||
cc->crypt_queue = alloc_workqueue("kcryptd/%s", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM,
|
||||
cc->crypt_queue = alloc_workqueue("kcryptd-%s", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM,
|
||||
1, devname);
|
||||
else
|
||||
cc->crypt_queue = alloc_workqueue("kcryptd/%s",
|
||||
WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND,
|
||||
cc->crypt_queue = alloc_workqueue("kcryptd-%s",
|
||||
WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM |
|
||||
WQ_UNBOUND | WQ_SYSFS,
|
||||
num_online_cpus(), devname);
|
||||
if (!cc->crypt_queue) {
|
||||
ti->error = "Couldn't create kcryptd queue";
|
||||
|
|
|
@ -86,7 +86,7 @@ static int __ebs_rw_bvec(struct ebs_c *ec, int rw, struct bio_vec *bv, struct bv
|
|||
else
|
||||
ba = dm_bufio_new(ec->bufio, block, &b);
|
||||
|
||||
if (unlikely(IS_ERR(ba))) {
|
||||
if (IS_ERR(ba)) {
|
||||
/*
|
||||
* Carry on with next buffer, if any, to issue all possible
|
||||
* data but return error.
|
||||
|
|
|
@ -1600,6 +1600,7 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para
|
|||
|
||||
if (!argc) {
|
||||
DMWARN("Empty message received.");
|
||||
r = -EINVAL;
|
||||
goto out_argv;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020 Oracle Corporation
|
||||
*
|
||||
* Module Author: Mike Christie
|
||||
*/
|
||||
#include "dm-path-selector.h"
|
||||
|
||||
#include <linux/device-mapper.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define DM_MSG_PREFIX "multipath io-affinity"
|
||||
|
||||
struct path_info {
|
||||
struct dm_path *path;
|
||||
cpumask_var_t cpumask;
|
||||
refcount_t refcount;
|
||||
bool failed;
|
||||
};
|
||||
|
||||
struct selector {
|
||||
struct path_info **path_map;
|
||||
cpumask_var_t path_mask;
|
||||
atomic_t map_misses;
|
||||
};
|
||||
|
||||
static void ioa_free_path(struct selector *s, unsigned int cpu)
|
||||
{
|
||||
struct path_info *pi = s->path_map[cpu];
|
||||
|
||||
if (!pi)
|
||||
return;
|
||||
|
||||
if (refcount_dec_and_test(&pi->refcount)) {
|
||||
cpumask_clear_cpu(cpu, s->path_mask);
|
||||
free_cpumask_var(pi->cpumask);
|
||||
kfree(pi);
|
||||
|
||||
s->path_map[cpu] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int ioa_add_path(struct path_selector *ps, struct dm_path *path,
|
||||
int argc, char **argv, char **error)
|
||||
{
|
||||
struct selector *s = ps->context;
|
||||
struct path_info *pi = NULL;
|
||||
unsigned int cpu;
|
||||
int ret;
|
||||
|
||||
if (argc != 1) {
|
||||
*error = "io-affinity ps: invalid number of arguments";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pi = kzalloc(sizeof(*pi), GFP_KERNEL);
|
||||
if (!pi) {
|
||||
*error = "io-affinity ps: Error allocating path context";
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pi->path = path;
|
||||
path->pscontext = pi;
|
||||
refcount_set(&pi->refcount, 1);
|
||||
|
||||
if (!zalloc_cpumask_var(&pi->cpumask, GFP_KERNEL)) {
|
||||
*error = "io-affinity ps: Error allocating cpumask context";
|
||||
ret = -ENOMEM;
|
||||
goto free_pi;
|
||||
}
|
||||
|
||||
ret = cpumask_parse(argv[0], pi->cpumask);
|
||||
if (ret) {
|
||||
*error = "io-affinity ps: invalid cpumask";
|
||||
ret = -EINVAL;
|
||||
goto free_mask;
|
||||
}
|
||||
|
||||
for_each_cpu(cpu, pi->cpumask) {
|
||||
if (cpu >= nr_cpu_ids) {
|
||||
DMWARN_LIMIT("Ignoring mapping for CPU %u. Max CPU is %u",
|
||||
cpu, nr_cpu_ids);
|
||||
break;
|
||||
}
|
||||
|
||||
if (s->path_map[cpu]) {
|
||||
DMWARN("CPU mapping for %u exists. Ignoring.", cpu);
|
||||
continue;
|
||||
}
|
||||
|
||||
cpumask_set_cpu(cpu, s->path_mask);
|
||||
s->path_map[cpu] = pi;
|
||||
refcount_inc(&pi->refcount);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (refcount_dec_and_test(&pi->refcount)) {
|
||||
*error = "io-affinity ps: No new/valid CPU mapping found";
|
||||
ret = -EINVAL;
|
||||
goto free_mask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_mask:
|
||||
free_cpumask_var(pi->cpumask);
|
||||
free_pi:
|
||||
kfree(pi);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ioa_create(struct path_selector *ps, unsigned argc, char **argv)
|
||||
{
|
||||
struct selector *s;
|
||||
|
||||
s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
s->path_map = kzalloc(nr_cpu_ids * sizeof(struct path_info *),
|
||||
GFP_KERNEL);
|
||||
if (!s->path_map)
|
||||
goto free_selector;
|
||||
|
||||
if (!zalloc_cpumask_var(&s->path_mask, GFP_KERNEL))
|
||||
goto free_map;
|
||||
|
||||
atomic_set(&s->map_misses, 0);
|
||||
ps->context = s;
|
||||
return 0;
|
||||
|
||||
free_map:
|
||||
kfree(s->path_map);
|
||||
free_selector:
|
||||
kfree(s);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void ioa_destroy(struct path_selector *ps)
|
||||
{
|
||||
struct selector *s = ps->context;
|
||||
unsigned cpu;
|
||||
|
||||
for_each_cpu(cpu, s->path_mask)
|
||||
ioa_free_path(s, cpu);
|
||||
|
||||
free_cpumask_var(s->path_mask);
|
||||
kfree(s->path_map);
|
||||
kfree(s);
|
||||
|
||||
ps->context = NULL;
|
||||
}
|
||||
|
||||
static int ioa_status(struct path_selector *ps, struct dm_path *path,
|
||||
status_type_t type, char *result, unsigned int maxlen)
|
||||
{
|
||||
struct selector *s = ps->context;
|
||||
struct path_info *pi;
|
||||
int sz = 0;
|
||||
|
||||
if (!path) {
|
||||
DMEMIT("0 ");
|
||||
return sz;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case STATUSTYPE_INFO:
|
||||
DMEMIT("%d ", atomic_read(&s->map_misses));
|
||||
break;
|
||||
case STATUSTYPE_TABLE:
|
||||
pi = path->pscontext;
|
||||
DMEMIT("%*pb ", cpumask_pr_args(pi->cpumask));
|
||||
break;
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void ioa_fail_path(struct path_selector *ps, struct dm_path *p)
|
||||
{
|
||||
struct path_info *pi = p->pscontext;
|
||||
|
||||
pi->failed = true;
|
||||
}
|
||||
|
||||
static int ioa_reinstate_path(struct path_selector *ps, struct dm_path *p)
|
||||
{
|
||||
struct path_info *pi = p->pscontext;
|
||||
|
||||
pi->failed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_path *ioa_select_path(struct path_selector *ps,
|
||||
size_t nr_bytes)
|
||||
{
|
||||
unsigned int cpu, node;
|
||||
struct selector *s = ps->context;
|
||||
const struct cpumask *cpumask;
|
||||
struct path_info *pi;
|
||||
int i;
|
||||
|
||||
cpu = get_cpu();
|
||||
|
||||
pi = s->path_map[cpu];
|
||||
if (pi && !pi->failed)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Perf is not optimal, but we at least try the local node then just
|
||||
* try not to fail.
|
||||
*/
|
||||
if (!pi)
|
||||
atomic_inc(&s->map_misses);
|
||||
|
||||
node = cpu_to_node(cpu);
|
||||
cpumask = cpumask_of_node(node);
|
||||
for_each_cpu(i, cpumask) {
|
||||
pi = s->path_map[i];
|
||||
if (pi && !pi->failed)
|
||||
goto done;
|
||||
}
|
||||
|
||||
for_each_cpu(i, s->path_mask) {
|
||||
pi = s->path_map[i];
|
||||
if (pi && !pi->failed)
|
||||
goto done;
|
||||
}
|
||||
pi = NULL;
|
||||
|
||||
done:
|
||||
put_cpu();
|
||||
return pi ? pi->path : NULL;
|
||||
}
|
||||
|
||||
static struct path_selector_type ioa_ps = {
|
||||
.name = "io-affinity",
|
||||
.module = THIS_MODULE,
|
||||
.table_args = 1,
|
||||
.info_args = 1,
|
||||
.create = ioa_create,
|
||||
.destroy = ioa_destroy,
|
||||
.status = ioa_status,
|
||||
.add_path = ioa_add_path,
|
||||
.fail_path = ioa_fail_path,
|
||||
.reinstate_path = ioa_reinstate_path,
|
||||
.select_path = ioa_select_path,
|
||||
};
|
||||
|
||||
static int __init dm_ioa_init(void)
|
||||
{
|
||||
int ret = dm_register_path_selector(&ioa_ps);
|
||||
|
||||
if (ret < 0)
|
||||
DMERR("register failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit dm_ioa_exit(void)
|
||||
{
|
||||
int ret = dm_unregister_path_selector(&ioa_ps);
|
||||
|
||||
if (ret < 0)
|
||||
DMERR("unregister failed %d", ret);
|
||||
}
|
||||
|
||||
module_init(dm_ioa_init);
|
||||
module_exit(dm_ioa_exit);
|
||||
|
||||
MODULE_DESCRIPTION(DM_NAME " multipath path selector that selects paths based on the CPU IO is being executed on");
|
||||
MODULE_AUTHOR("Mike Christie <michael.christie@oracle.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -496,7 +496,7 @@ static void stripe_io_hints(struct dm_target *ti,
|
|||
static struct target_type stripe_target = {
|
||||
.name = "striped",
|
||||
.version = {1, 6, 0},
|
||||
.features = DM_TARGET_PASSES_INTEGRITY,
|
||||
.features = DM_TARGET_PASSES_INTEGRITY | DM_TARGET_NOWAIT,
|
||||
.module = THIS_MODULE,
|
||||
.ctr = stripe_ctr,
|
||||
.dtr = stripe_dtr,
|
||||
|
|
|
@ -550,6 +550,7 @@ static int switch_iterate_devices(struct dm_target *ti,
|
|||
static struct target_type switch_target = {
|
||||
.name = "switch",
|
||||
.version = {1, 1, 0},
|
||||
.features = DM_TARGET_NOWAIT,
|
||||
.module = THIS_MODULE,
|
||||
.ctr = switch_ctr,
|
||||
.dtr = switch_dtr,
|
||||
|
|
|
@ -178,6 +178,7 @@ static void unstripe_io_hints(struct dm_target *ti,
|
|||
static struct target_type unstripe_target = {
|
||||
.name = "unstriped",
|
||||
.version = {1, 1, 0},
|
||||
.features = DM_TARGET_NOWAIT,
|
||||
.module = THIS_MODULE,
|
||||
.ctr = unstripe_ctr,
|
||||
.dtr = unstripe_dtr,
|
||||
|
|
|
@ -537,6 +537,15 @@ static int verity_verify_io(struct dm_verity_io *io)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip verity work in response to I/O error when system is shutting down.
|
||||
*/
|
||||
static inline bool verity_is_system_shutting_down(void)
|
||||
{
|
||||
return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF
|
||||
|| system_state == SYSTEM_RESTART;
|
||||
}
|
||||
|
||||
/*
|
||||
* End one "io" structure with a given error.
|
||||
*/
|
||||
|
@ -564,7 +573,8 @@ static void verity_end_io(struct bio *bio)
|
|||
{
|
||||
struct dm_verity_io *io = bio->bi_private;
|
||||
|
||||
if (bio->bi_status && !verity_fec_is_enabled(io->v)) {
|
||||
if (bio->bi_status &&
|
||||
(!verity_fec_is_enabled(io->v) || verity_is_system_shutting_down())) {
|
||||
verity_finish_io(io, bio->bi_status);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -119,8 +119,13 @@ int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
|
|||
}
|
||||
|
||||
ret = verify_pkcs7_signature(root_hash, root_hash_len, sig_data,
|
||||
sig_len, NULL, VERIFYING_UNSPECIFIED_SIGNATURE,
|
||||
NULL, NULL);
|
||||
sig_len,
|
||||
#ifdef CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
|
||||
VERIFY_USE_SECONDARY_KEYRING,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ static int zero_map(struct dm_target *ti, struct bio *bio)
|
|||
static struct target_type zero_target = {
|
||||
.name = "zero",
|
||||
.version = {1, 1, 0},
|
||||
.features = DM_TARGET_NOWAIT,
|
||||
.module = THIS_MODULE,
|
||||
.ctr = zero_ctr,
|
||||
.map = zero_map,
|
||||
|
|
|
@ -1586,7 +1586,7 @@ static blk_qc_t __split_and_process_bio(struct mapped_device *md,
|
|||
ci.sector_count = bio_sectors(bio);
|
||||
while (ci.sector_count && !error) {
|
||||
error = __split_and_process_non_flush(&ci);
|
||||
if (current->bio_list && ci.sector_count && !error) {
|
||||
if (ci.sector_count && !error) {
|
||||
/*
|
||||
* Remainder must be passed to submit_bio_noacct()
|
||||
* so that it gets handled *after* bios already submitted
|
||||
|
|
Loading…
Reference in New Issue