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

Commit b0e5c294 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-4.19/dm-changes' of...

Merge tag 'for-4.19/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper updates from Mike Snitzer:

 - A couple stable fixes for the DM writecache target.

 - A stable fix for the DM cache target that fixes the potential for
   data corruption after an unclean shutdown of a cache device using
   writeback mode.

 - Update DM integrity target to allow the metadata to be stored on a
   separate device from data.

 - Fix DM kcopyd and the snapshot target to cond_resched() where
   appropriate and be more efficient with processing completed work.

 - A few fixes and improvements for DM crypt.

 - Add DM delay target feature to configure delay of flushes independent
   of writes.

 - Update DM thin-provisioning target to include metadata_low_watermark
   threshold in pool status.

 - Fix stale DM thin-provisioning Documentation.

* tag 'for-4.19/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: (26 commits)
  dm writecache: fix a crash due to reading past end of dirty_bitmap
  dm crypt: don't decrease device limits
  dm cache metadata: set dirty on all cache blocks after a crash
  dm snapshot: remove stale FIXME in snapshot_map()
  dm snapshot: improve performance by switching out_of_order_list to rbtree
  dm kcopyd: avoid softlockup in run_complete_job
  dm cache metadata: save in-core policy_hint_size to on-disk superblock
  dm thin: stop no_space_timeout worker when switching to write-mode
  dm kcopyd: return void from dm_kcopyd_copy()
  dm thin: include metadata_low_watermark threshold in pool status
  dm writecache: report start_sector in status line
  dm crypt: convert essiv from ahash to shash
  dm crypt: use wake_up_process() instead of a wait queue
  dm integrity: recalculate checksums on creation
  dm integrity: flush journal on suspend when using separate metadata device
  dm integrity: use version 2 for separate metadata
  dm integrity: allow separate metadata device
  dm integrity: add ic->start in get_data_sector()
  dm integrity: report provided data sectors in the status
  dm integrity: implement fair range locks
  ...
parents 2645b9d1 1e1132ea
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -5,7 +5,8 @@ Device-Mapper's "delay" target delays reads and/or writes
and maps them to different devices.

Parameters:
    <device> <offset> <delay> [<write_device> <write_offset> <write_delay>]
    <device> <offset> <delay> [<write_device> <write_offset> <write_delay>
			       [<flush_device> <flush_offset> <flush_delay>]]

With separate write parameters, the first set is only used for reads.
Offsets are specified in sectors.
+4 −0
Original line number Diff line number Diff line
@@ -113,6 +113,10 @@ internal_hash:algorithm(:key) (the key is optional)
	from an upper layer target, such as dm-crypt. The upper layer
	target should check the validity of the integrity tags.

recalculate
	Recalculate the integrity tags automatically. It is only valid
	when using internal hash.

journal_crypt:algorithm(:key)	(the key is optional)
	Encrypt the journal using given algorithm to make sure that the
	attacker can't read the journal. You can use a block cipher here
+13 −7
Original line number Diff line number Diff line
@@ -28,17 +28,18 @@ administrator some freedom, for example to:
Status
======

These targets are very much still in the EXPERIMENTAL state.  Please
do not yet rely on them in production.  But do experiment and offer us
feedback.  Different use cases will have different performance
characteristics, for example due to fragmentation of the data volume.
These targets are considered safe for production use.  But different use
cases will have different performance characteristics, for example due
to fragmentation of the data volume.

If you find this software is not performing as expected please mail
dm-devel@redhat.com with details and we'll try our best to improve
things for you.

Userspace tools for checking and repairing the metadata are under
development.
Userspace tools for checking and repairing the metadata have been fully
developed and are available as 'thin_check' and 'thin_repair'.  The name
of the package that provides these utilities varies by distribution (on
a Red Hat distribution it is named 'device-mapper-persistent-data').

Cookbook
========
@@ -280,7 +281,7 @@ ii) Status
    <transaction id> <used metadata blocks>/<total metadata blocks>
    <used data blocks>/<total data blocks> <held metadata root>
    ro|rw|out_of_data_space [no_]discard_passdown [error|queue]_if_no_space
    needs_check|-
    needs_check|- metadata_low_watermark

    transaction id:
	A 64-bit number used by userspace to help synchronise with metadata
@@ -327,6 +328,11 @@ ii) Status
	thin-pool can be made fully operational again.  '-' indicates
	needs_check is not set.

    metadata_low_watermark:
	Value of metadata low watermark in blocks.  The kernel sets this
	value internally but userspace needs to know this value to
	determine if an event was caused by crossing this threshold.

iii) Messages

    create_thin <dev id>
+9 −4
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
	disk_super->version = cpu_to_le32(cmd->version);
	memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
	memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
	disk_super->policy_hint_size = 0;
	disk_super->policy_hint_size = cpu_to_le32(0);

	__copy_sm_root(cmd, disk_super);

@@ -701,6 +701,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
	disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
	disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
	disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
	disk_super->policy_hint_size = cpu_to_le32(cmd->policy_hint_size);

	disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
	disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
@@ -1322,6 +1323,7 @@ static int __load_mapping_v1(struct dm_cache_metadata *cmd,

	dm_oblock_t oblock;
	unsigned flags;
	bool dirty = true;

	dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
	memcpy(&mapping, mapping_value_le, sizeof(mapping));
@@ -1332,8 +1334,10 @@ static int __load_mapping_v1(struct dm_cache_metadata *cmd,
			dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
			memcpy(&hint, hint_value_le, sizeof(hint));
		}
		if (cmd->clean_when_opened)
			dirty = flags & M_DIRTY;

		r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY,
		r = fn(context, oblock, to_cblock(cb), dirty,
		       le32_to_cpu(hint), hints_valid);
		if (r) {
			DMERR("policy couldn't load cache block %llu",
@@ -1361,7 +1365,7 @@ static int __load_mapping_v2(struct dm_cache_metadata *cmd,

	dm_oblock_t oblock;
	unsigned flags;
	bool dirty;
	bool dirty = true;

	dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
	memcpy(&mapping, mapping_value_le, sizeof(mapping));
@@ -1372,8 +1376,9 @@ static int __load_mapping_v2(struct dm_cache_metadata *cmd,
			dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
			memcpy(&hint, hint_value_le, sizeof(hint));
		}

		if (cmd->clean_when_opened)
			dirty = dm_bitset_cursor_get_value(dirty_cursor);

		r = fn(context, oblock, to_cblock(cb), dirty,
		       le32_to_cpu(hint), hints_valid);
		if (r) {
+19 −16
Original line number Diff line number Diff line
@@ -1188,9 +1188,8 @@ static void copy_complete(int read_err, unsigned long write_err, void *context)
	queue_continuation(mg->cache->wq, &mg->k);
}

static int copy(struct dm_cache_migration *mg, bool promote)
static void copy(struct dm_cache_migration *mg, bool promote)
{
	int r;
	struct dm_io_region o_region, c_region;
	struct cache *cache = mg->cache;

@@ -1203,11 +1202,9 @@ static int copy(struct dm_cache_migration *mg, bool promote)
	c_region.count = cache->sectors_per_block;

	if (promote)
		r = dm_kcopyd_copy(cache->copier, &o_region, 1, &c_region, 0, copy_complete, &mg->k);
		dm_kcopyd_copy(cache->copier, &o_region, 1, &c_region, 0, copy_complete, &mg->k);
	else
		r = dm_kcopyd_copy(cache->copier, &c_region, 1, &o_region, 0, copy_complete, &mg->k);

	return r;
		dm_kcopyd_copy(cache->copier, &c_region, 1, &o_region, 0, copy_complete, &mg->k);
}

static void bio_drop_shared_lock(struct cache *cache, struct bio *bio)
@@ -1449,12 +1446,7 @@ static void mg_full_copy(struct work_struct *ws)
	}

	init_continuation(&mg->k, mg_upgrade_lock);

	if (copy(mg, is_policy_promote)) {
		DMERR_LIMIT("%s: migration copy failed", cache_device_name(cache));
		mg->k.input = BLK_STS_IOERR;
		mg_complete(mg, false);
	}
	copy(mg, is_policy_promote);
}

static void mg_copy(struct work_struct *ws)
@@ -2250,7 +2242,7 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
		{0, 2, "Invalid number of cache feature arguments"},
	};

	int r;
	int r, mode_ctr = 0;
	unsigned argc;
	const char *arg;
	struct cache_features *cf = &ca->features;
@@ -2264,14 +2256,20 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
	while (argc--) {
		arg = dm_shift_arg(as);

		if (!strcasecmp(arg, "writeback"))
		if (!strcasecmp(arg, "writeback")) {
			cf->io_mode = CM_IO_WRITEBACK;
			mode_ctr++;
		}

		else if (!strcasecmp(arg, "writethrough"))
		else if (!strcasecmp(arg, "writethrough")) {
			cf->io_mode = CM_IO_WRITETHROUGH;
			mode_ctr++;
		}

		else if (!strcasecmp(arg, "passthrough"))
		else if (!strcasecmp(arg, "passthrough")) {
			cf->io_mode = CM_IO_PASSTHROUGH;
			mode_ctr++;
		}

		else if (!strcasecmp(arg, "metadata2"))
			cf->metadata_version = 2;
@@ -2282,6 +2280,11 @@ static int parse_features(struct cache_args *ca, struct dm_arg_set *as,
		}
	}

	if (mode_ctr > 1) {
		*error = "Duplicate cache io_mode features requested";
		return -EINVAL;
	}

	return 0;
}

Loading