Add support for allow_discrads for dm-integrity.

Kernel 5.7 adds support for optional discard/TRIM operation
for dm-integrity (available only for internal hash, not for LUKS2
with integrity).

This patch adds support for the new option.
This commit is contained in:
Milan Broz
2020-04-09 00:03:42 +02:00
parent c9f6ccff9f
commit 790666ffb0
5 changed files with 42 additions and 1 deletions

View File

@@ -230,6 +230,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
_dm_integrity_checked = true;
}
@@ -900,6 +903,12 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
num_options++;
snprintf(feature, sizeof(feature), "allow_discards ");
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (tgt->u.integrity.meta_device) {
num_options++;
snprintf(feature, sizeof(feature), "meta_device:%s ",
@@ -1632,6 +1641,10 @@ int dm_create_device(struct crypt_device *cd, const char *name,
!(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
!(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED))
log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
@@ -1664,6 +1677,9 @@ int dm_reload_device(struct crypt_device *cd, const char *name,
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
}
if (!r && resume)
@@ -2397,6 +2413,8 @@ static int _dm_target_query_integrity(struct crypt_device *cd,
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
} else if (!strcmp(arg, "fix_padding")) {
tgt->u.integrity.fix_padding = true;
} else if (!strcmp(arg, "allow_discards")) {
*act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
} else /* unknown option */
goto err;
}

View File

@@ -2156,6 +2156,11 @@ int LUKS2_activate(struct crypt_device *cd,
return -EINVAL;
}
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
log_err(cd, _("Discard/TRIM is not supported."));
return -EINVAL;
}
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
if (r)
return r;

View File

@@ -68,6 +68,7 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_BITLK_EBOIV_SUPPORTED (1 << 20) /* EBOIV for BITLK supported */
#define DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */
#define DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */
#define DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_SET = 1, TARGET_QUERY };

View File

@@ -33,7 +33,7 @@ Open a mapping with <name> backed by device <device>.
\fB<options>\fR can be [\-\-data\-device, \-\-batch\-mode, \-\-journal\-watermark,
\-\-journal\-commit\-time, \-\-buffer\-sectors, \-\-integrity, \-\-integrity\-key\-size,
\-\-integrity\-key\-file, \-\-integrity\-no\-journal, \-\-integrity\-recalculate,
\-\-integrity\-recovery\-mode]
\-\-integrity\-recovery\-mode, \-\-allow\-discards]
.PP
\fIclose\fR <name>
@@ -174,6 +174,10 @@ The size of the journal encryption key.
.B "\-\-journal\-crypt\-key\-file FILE"
The file with the journal encryption key.
.TP
.B "\-\-allow\-discards\fR"
Allow the use of discard (TRIM) requests for the device.
This option is available since the Linux kernel version 5.7.
.TP
The dm-integrity target is available since Linux kernel version 4.12.
.TP
\fBNOTE:\fR

View File

@@ -60,6 +60,7 @@ static int opt_integrity_bitmap = 0;
static int opt_integrity_legacy_padding = 0;
static int opt_integrity_recalculate = 0;
static int opt_allow_discards = 0;
static const char **action_argv;
static int action_argc;
@@ -314,6 +315,8 @@ static int action_open(int arg)
if (opt_integrity_recalculate)
activate_flags |= CRYPT_ACTIVATE_RECALCULATE;
if (opt_allow_discards)
activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
r = _read_keys(&integrity_key, &params);
if (r)
@@ -437,6 +440,9 @@ static int action_status(int arg)
if (ip.journal_crypt)
log_std(" journal encryption: %s\n", ip.journal_crypt);
}
if (cad.flags & (CRYPT_ACTIVATE_ALLOW_DISCARDS))
log_std(" flags: %s\n",
(cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? "discards " : "");
}
out:
crypt_free(cd);
@@ -569,6 +575,8 @@ int main(int argc, const char **argv)
{ "integrity-bitmap-mode", 'B', POPT_ARG_NONE, &opt_integrity_bitmap, 0, N_("Use bitmap to track changes and disable journal for integrity device"), NULL },
{ "integrity-recalculate", '\0', POPT_ARG_NONE, &opt_integrity_recalculate, 0, N_("Recalculate initial tags automatically."), NULL },
{ "integrity-legacy-padding", '\0', POPT_ARG_NONE, &opt_integrity_legacy_padding, 0, N_("Use inefficient legacy padding (old kernels)"), NULL },
{ "allow-discards", '\0', POPT_ARG_NONE, &opt_allow_discards, 0, N_("Allow discards (aka TRIM) requests for device"), NULL },
POPT_TABLEEND
};
poptContext popt_context;
@@ -641,6 +649,11 @@ int main(int argc, const char **argv)
_("Option --integrity-recalculate can be used only for open action."),
poptGetInvocationName(popt_context));
if (opt_allow_discards && strcmp(aname, "open"))
usage(popt_context, EXIT_FAILURE,
_("Option --allow-discards is allowed only for open operation.\n"),
poptGetInvocationName(popt_context));
if (opt_interleave_sectors < 0 || opt_journal_watermark < 0 ||
opt_journal_commit_time < 0 || opt_tag_size < 0 ||
opt_sector_size < 0 || opt_buffer_sectors < 0 ||