Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 775a2e29 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull device mapper updates from Mike Snitzer:

 - various fixes and improvements to request-based DM and DM multipath

 - some locking improvements in DM bufio

 - add Kconfig option to disable the DM block manager's extra locking
   which mainly serves as a developer tool

 - a few bug fixes to DM's persistent-data

 - a couple changes to prepare for multipage biovec support in the block
   layer

 - various improvements and cleanups in the DM core, DM cache, DM raid
   and DM crypt

 - add ability to have DM crypt use keys from the kernel key retention
   service

 - add a new "error_writes" feature to the DM flakey target, reads are
   left unchanged in this mode

* tag 'dm-4.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (40 commits)
  dm flakey: introduce "error_writes" feature
  dm cache policy smq: use hash_32() instead of hash_32_generic()
  dm crypt: reject key strings containing whitespace chars
  dm space map: always set ev if sm_ll_mutate() succeeds
  dm space map metadata: skip useless memcpy in metadata_ll_init_index()
  dm space map metadata: fix 'struct sm_metadata' leak on failed create
  Documentation: dm raid: define data_offset status field
  dm raid: fix discard support regression
  dm raid: don't allow "write behind" with raid4/5/6
  dm mpath: use hw_handler_params if attached hw_handler is same as requested
  dm crypt: add ability to use keys from the kernel key retention service
  dm array: remove a dead assignment in populate_ablock_with_values()
  dm ioctl: use offsetof() instead of open-coding it
  dm rq: simplify use_blk_mq initialization
  dm: use blk_set_queue_dying() in __dm_destroy()
  dm bufio: drop the lock when doing GFP_NOIO allocation
  dm bufio: don't take the lock in dm_bufio_shrink_count
  dm bufio: avoid sleeping while holding the dm_bufio lock
  dm table: simplify dm_table_determine_type()
  dm table: an 'all_blk_mq' table must be loaded for a blk-mq DM device
  ...
parents 2a4c32ed ef548c55
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -21,13 +21,30 @@ Parameters: <cipher> <key> <iv_offset> <device path> \
    /proc/crypto contains supported crypto modes

<key>
    Key used for encryption. It is encoded as a hexadecimal number.
    Key used for encryption. It is encoded either as a hexadecimal number
    or it can be passed as <key_string> prefixed with single colon
    character (':') for keys residing in kernel keyring service.
    You can only use key sizes that are valid for the selected cipher
    in combination with the selected iv mode.
    Note that for some iv modes the key string can contain additional
    keys (for example IV seed) so the key contains more parts concatenated
    into a single string.

<key_string>
    The kernel keyring key is identified by string in following format:
    <key_size>:<key_type>:<key_description>.

<key_size>
    The encryption key size in bytes. The kernel key payload size must match
    the value passed in <key_size>.

<key_type>
    Either 'logon' or 'user' kernel key type.

<key_description>
    The kernel keyring key description crypt target should look for
    when loading key of <key_type>.

<keycount>
    Multi-key compatibility mode. You can define <keycount> keys and
    then sectors are encrypted according to their offsets (sector 0 uses key0;
@@ -88,6 +105,12 @@ https://gitlab.com/cryptsetup/cryptsetup
dmsetup create crypt1 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 babebabebabebabebabebabebabebabe 0 $1 0"
]]

[[
#!/bin/sh
# Create a crypt device using dmsetup when encryption key is stored in keyring service
dmsetup create crypt2 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 :32:logon:my_prefix:my_key 0 $1 0"
]]

[[
#!/bin/sh
# Create a crypt device using cryptsetup and LUKS header with default cipher
+4 −0
Original line number Diff line number Diff line
@@ -242,6 +242,10 @@ recovery. Here is a fuller description of the individual fields:
			in RAID1/10 or wrong parity values found in RAID4/5/6.
			This value is valid only after a "check" of the array
			is performed.  A healthy array has a 'mismatch_cnt' of 0.
	<data_offset>   The current data offset to the start of the user data on
			each component device of a raid set (see the respective
			raid parameter to support out-of-place reshaping).


Message Interface
-----------------
+9 −1
Original line number Diff line number Diff line
@@ -240,9 +240,17 @@ config DM_BUFIO
	 as a cache, holding recently-read blocks in memory and performing
	 delayed writes.

config DM_DEBUG_BLOCK_MANAGER_LOCKING
       bool "Block manager locking"
       depends on DM_BUFIO
       ---help---
	 Block manager locking can catch various metadata corruption issues.

	 If unsure, say N.

config DM_DEBUG_BLOCK_STACK_TRACING
       bool "Keep stack trace of persistent data block lock holders"
       depends on STACKTRACE_SUPPORT && DM_BUFIO
       depends on STACKTRACE_SUPPORT && DM_DEBUG_BLOCK_MANAGER_LOCKING
       select STACKTRACE
       ---help---
	 Enable this for messages that may help debug problems with the
+15 −13
Original line number Diff line number Diff line
@@ -820,12 +820,14 @@ enum new_flag {
static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client *c, enum new_flag nf)
{
	struct dm_buffer *b;
	bool tried_noio_alloc = false;

	/*
	 * dm-bufio is resistant to allocation failures (it just keeps
	 * one buffer reserved in cases all the allocations fail).
	 * So set flags to not try too hard:
	 *	GFP_NOIO: don't recurse into the I/O layer
	 *	GFP_NOWAIT: don't wait; if we need to sleep we'll release our
	 *		    mutex and wait ourselves.
	 *	__GFP_NORETRY: don't retry and rather return failure
	 *	__GFP_NOMEMALLOC: don't use emergency reserves
	 *	__GFP_NOWARN: don't print a warning in case of failure
@@ -835,7 +837,7 @@ static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client
	 */
	while (1) {
		if (dm_bufio_cache_size_latch != 1) {
			b = alloc_buffer(c, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
			b = alloc_buffer(c, GFP_NOWAIT | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
			if (b)
				return b;
		}
@@ -843,6 +845,15 @@ static struct dm_buffer *__alloc_buffer_wait_no_callback(struct dm_bufio_client
		if (nf == NF_PREFETCH)
			return NULL;

		if (dm_bufio_cache_size_latch != 1 && !tried_noio_alloc) {
			dm_bufio_unlock(c);
			b = alloc_buffer(c, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
			dm_bufio_lock(c);
			if (b)
				return b;
			tried_noio_alloc = true;
		}

		if (!list_empty(&c->reserved_buffers)) {
			b = list_entry(c->reserved_buffers.next,
				       struct dm_buffer, lru_list);
@@ -1585,18 +1596,9 @@ dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
static unsigned long
dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
{
	struct dm_bufio_client *c;
	unsigned long count;
	struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker);

	c = container_of(shrink, struct dm_bufio_client, shrinker);
	if (sc->gfp_mask & __GFP_FS)
		dm_bufio_lock(c);
	else if (!dm_bufio_trylock(c))
		return 0;

	count = c->n_buffers[LIST_CLEAN] + c->n_buffers[LIST_DIRTY];
	dm_bufio_unlock(c);
	return count;
	return ACCESS_ONCE(c->n_buffers[LIST_CLEAN]) + ACCESS_ONCE(c->n_buffers[LIST_DIRTY]);
}

/*
+1 −2
Original line number Diff line number Diff line
@@ -383,7 +383,6 @@ static int __format_metadata(struct dm_cache_metadata *cmd)
		goto bad;

	dm_disk_bitset_init(cmd->tm, &cmd->discard_info);

	r = dm_bitset_empty(&cmd->discard_info, &cmd->discard_root);
	if (r < 0)
		goto bad;
@@ -789,7 +788,7 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size)
{
	if (cmd->data_block_size != data_block_size) {
		DMERR("data_block_size (%llu) different from that in metadata (%llu)\n",
		DMERR("data_block_size (%llu) different from that in metadata (%llu)",
		      (unsigned long long) data_block_size,
		      (unsigned long long) cmd->data_block_size);
		return false;
Loading