Add support for dm-verity try_verify_in_tasklet option.

Available since kernel 6.0.
This commit is contained in:
Milan Broz
2022-07-26 22:02:36 +02:00
parent 09ac5321f4
commit b183bb25e2
9 changed files with 41 additions and 7 deletions

View File

@@ -1183,6 +1183,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (UINT32_C(1) << 25)
/** dm-integrity: reset automatic recalculation */
#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
/** dm-verity: try to use tasklets */
#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
/**
* Active device runtime attributes

View File

@@ -205,6 +205,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
if (_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_TASKLETS_SUPPORTED;
_dm_verity_checked = true;
}
@@ -734,6 +737,8 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
num_options++;
if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
num_options++;
if (flags & CRYPT_ACTIVATE_TASKLETS)
num_options++;
max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
fec_features = crypt_safe_alloc(max_fec_size);
@@ -764,13 +769,14 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
} else
*verity_verify_args = '\0';
if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 */
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s", num_options,
if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 + 22 */
r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
(flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "",
(flags & CRYPT_ACTIVATE_TASKLETS) ? " try_verify_in_tasklet" : "");
if (r < 0 || (size_t)r >= sizeof(features))
goto out;
} else
@@ -1705,6 +1711,12 @@ int dm_create_device(struct crypt_device *cd, const char *name,
r = -EINVAL;
}
if (dmd->flags & CRYPT_ACTIVATE_TASKLETS &&
!(dmt_flags & DM_VERITY_TASKLETS_SUPPORTED)) {
log_err(cd, _("Requested dm-verity tasklets option is not supported."));
r = -EINVAL;
}
if (dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED)) {
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
@@ -2289,6 +2301,8 @@ static int _dm_target_query_verity(struct crypt_device *cd,
*act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
else if (!strcasecmp(arg, "check_at_most_once"))
*act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
else if (!strcasecmp(arg, "try_verify_in_tasklet"))
*act_flags |= CRYPT_ACTIVATE_TASKLETS;
else if (!strcasecmp(arg, "use_fec_from_device")) {
str = strsep(&params, " ");
str2 = crypt_lookup_dev(str);

View File

@@ -75,6 +75,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
#define DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */
#define DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_EMPTY = 0, TARGET_SET, TARGET_QUERY };

View File

@@ -58,7 +58,7 @@ The <root_hash> is a hexadecimal string.
*<options>* can be [--hash-offset, --no-superblock, --ignore-corruption
or --restart-on-corruption, --panic-on-corruption, --ignore-zero-blocks,
--check-at-most-once, --root-hash-signature, --root-hash-file].
--check-at-most-once, --root-hash-signature, --root-hash-file, --use-tasklets].
If option --root-hash-file is used, the root hash is read from <path>
instead of from the command line parameter. Expects hex-encoded text,
@@ -213,6 +213,10 @@ Path to root hash signature file used to verify the root hash (in
kernel). This feature requires Linux kernel version 5.4 or more
recent.
*--use-tasklets*::
Try to use kernel tasklets in dm-verity driver for performance reasons.
This option is available since Linux kernel version 6.0.
*--deferred*::
Defers device removal in *close* command until the last user closes
it.

View File

@@ -158,6 +158,7 @@
#define OPT_USE_FSYNC "use-fsync"
#define OPT_USE_RANDOM "use-random"
#define OPT_USE_URANDOM "use-urandom"
#define OPT_USE_TASKLETS "use-tasklets"
#define OPT_UUID "uuid"
#define OPT_VERACRYPT "veracrypt"
#define OPT_VERACRYPT_PIM "veracrypt-pim"

View File

@@ -184,6 +184,8 @@ static int _activate(const char *dm_device,
activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
if (ARG_SET(OPT_CHECK_AT_MOST_ONCE_ID))
activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
if (ARG_SET(OPT_USE_TASKLETS_ID))
activate_flags |= CRYPT_ACTIVATE_TASKLETS;
if (!ARG_SET(OPT_NO_SUPERBLOCK_ID)) {
params.flags = flags;
@@ -436,13 +438,15 @@ static int action_status(void)
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
CRYPT_ACTIVATE_PANIC_ON_CORRUPTION|
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE))
log_std(" flags: %s%s%s%s%s\n",
CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE|
CRYPT_ACTIVATE_TASKLETS))
log_std(" flags: %s%s%s%s%s%s\n",
(cad.flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? "ignore_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? "restart_on_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? "panic_on_corruption " : "",
(cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "",
(cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : "");
(cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : "",
(cad.flags & CRYPT_ACTIVATE_TASKLETS) ? "try_verify_in_tasklet" : "");
}
out:
crypt_free(cd);

View File

@@ -63,6 +63,8 @@ ARG(OPT_ROOT_HASH_SIGNATURE, '\0', POPT_ARG_STRING, N_("Path to root hash signat
ARG(OPT_SALT, 's', POPT_ARG_STRING, N_("Salt"), N_("hex string"), CRYPT_ARG_STRING, {}, {})
ARG(OPT_USE_TASKLETS, '\0', POPT_ARG_NONE, N_("Use kernel tasklets for performance"), NULL, CRYPT_ARG_BOOL, {}, OPT_USE_TASKLETS_ACTIONS)
ARG(OPT_UUID, '\0', POPT_ARG_STRING, N_("UUID for device to use"), NULL, CRYPT_ARG_STRING, {}, {})
ARG(OPT_VERBOSE, 'v', POPT_ARG_NONE, N_("Shows more detailed error messages"), NULL, CRYPT_ARG_BOOL, {}, {})

View File

@@ -39,6 +39,7 @@
#define OPT_PANIC_ON_CORRUPTION_ACTIONS { OPEN_ACTION }
#define OPT_ROOT_HASH_FILE_ACTIONS { FORMAT_ACTION, OPEN_ACTION, VERIFY_ACTION }
#define OPT_ROOT_HASH_SIGNATURE_ACTIONS { OPEN_ACTION }
#define OPT_USE_TASKLETS_ACTIONS { OPEN_ACTION }
enum {
OPT_UNUSED_ID = 0,

View File

@@ -476,6 +476,11 @@ if check_version 1 3; then
if check_version 1 7; then
check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption"
fi
if check_version 1 9; then
echo "Verity data performance options test."
check_option 512 $HASH $SALT 1 sha256 "--use-tasklets" "try_verify_in_tasklet"
fi
fi
echo "Veritysetup [hash-offset bigger than 2G works] "