Commit 4ed7bdc1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

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

Pull device mapper updates from Mike Snitzer:

 - Eliminate a couple indirect calls from bio-based DM core.

 - Fix DM to allow reads that exceed readahead limits by setting
   io_pages in the backing_dev_info.

 - A couple code cleanups in request-based DM.

 - Fix various DM targets to check for device sector overflow if
   CONFIG_LBDAF is not set.

 - Use u64 instead of sector_t to store iv_offset in DM crypt; sector_t
   isn't large enough on 32bit when CONFIG_LBDAF is not set.

 - Performance fixes to DM's kcopyd and the snapshot target focused on
   limiting memory use and workqueue stalls.

 - Fix typos in the integrity and writecache targets.

 - Log which algorithm is used for dm-crypt's encryption and
   dm-integrity's hashing.

 - Fix false -EBUSY errors in DM raid target's handling of check/repair
   messages.

 - Fix DM flakey target's corrupt_bio_byte feature to reliably corrupt
   the Nth byte in a bio's payload.

* tag 'for-4.21/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm: do not allow readahead to limit IO size
  dm raid: fix false -EBUSY when handling check/repair message
  dm rq: cleanup leftover code from recently removed q->mq_ops branching
  dm verity: log the hash algorithm implementation
  dm crypt: log the encryption algorithm implementation
  dm integrity: fix spelling mistake in workqueue name
  dm flakey: Properly corrupt multi-page bios.
  dm: Check for device sector overflow if CONFIG_LBDAF is not set
  dm crypt: use u64 instead of sector_t to store iv_offset
  dm kcopyd: Fix bug causing workqueue stalls
  dm snapshot: Fix excessive memory usage and workqueue stalls
  dm bufio: update comment in dm-bufio.c
  dm writecache: fix typo in error msg for creating writecache_flush_thread
  dm: remove indirect calls from __send_changing_extent_only()
  dm mpath: only flush workqueue when needed
  dm rq: remove unused arguments from rq_completed()
  dm: avoid indirect call in __dm_make_request
parents 5d24ae67 c6d6e9b0
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@

/*
 * Linking of buffers:
 *	All buffers are linked to cache_hash with their hash_list field.
 *	All buffers are linked to buffer_tree with their node field.
 *
 *	Clean buffers that are not being written (B_WRITING not set)
 *	are linked to lru[LIST_CLEAN] with their lru_list field.
@@ -457,7 +457,7 @@ static void free_buffer(struct dm_buffer *b)
}

/*
 * Link buffer to the hash list and clean or dirty queue.
 * Link buffer to the buffer tree and clean or dirty queue.
 */
static void __link_buffer(struct dm_buffer *b, sector_t block, int dirty)
{
@@ -472,7 +472,7 @@ static void __link_buffer(struct dm_buffer *b, sector_t block, int dirty)
}

/*
 * Unlink buffer from the hash list and dirty or clean queue.
 * Unlink buffer from the buffer tree and dirty or clean queue.
 */
static void __unlink_buffer(struct dm_buffer *b)
{
@@ -993,7 +993,7 @@ static struct dm_buffer *__bufio_new(struct dm_bufio_client *c, sector_t block,

	/*
	 * We've had a period where the mutex was unlocked, so need to
	 * recheck the hash table.
	 * recheck the buffer tree.
	 */
	b = __find(c, block);
	if (b) {
@@ -1327,7 +1327,7 @@ again:
EXPORT_SYMBOL_GPL(dm_bufio_write_dirty_buffers);

/*
 * Use dm-io to send and empty barrier flush the device.
 * Use dm-io to send an empty barrier to flush the device.
 */
int dm_bufio_issue_flush(struct dm_bufio_client *c)
{
@@ -1356,7 +1356,7 @@ EXPORT_SYMBOL_GPL(dm_bufio_issue_flush);
 * Then, we write the buffer to the original location if it was dirty.
 *
 * Then, if we are the only one who is holding the buffer, relink the buffer
 * in the hash queue for the new location.
 * in the buffer tree for the new location.
 *
 * If there was someone else holding the buffer, we write it to the new
 * location but not relink it, because that other user needs to have the buffer
+13 −4
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ struct convert_context {
	struct bio *bio_out;
	struct bvec_iter iter_in;
	struct bvec_iter iter_out;
	sector_t cc_sector;
	u64 cc_sector;
	atomic_t cc_pending;
	union {
		struct skcipher_request *req;
@@ -81,7 +81,7 @@ struct dm_crypt_request {
	struct convert_context *ctx;
	struct scatterlist sg_in[4];
	struct scatterlist sg_out[4];
	sector_t iv_sector;
	u64 iv_sector;
};

struct crypt_config;
@@ -160,7 +160,7 @@ struct crypt_config {
		struct iv_lmk_private lmk;
		struct iv_tcw_private tcw;
	} iv_gen_private;
	sector_t iv_offset;
	u64 iv_offset;
	unsigned int iv_size;
	unsigned short int sector_size;
	unsigned char sector_shift;
@@ -1885,6 +1885,13 @@ static int crypt_alloc_tfms_skcipher(struct crypt_config *cc, char *ciphermode)
		}
	}

	/*
	 * dm-crypt performance can vary greatly depending on which crypto
	 * algorithm implementation is used.  Help people debug performance
	 * problems by logging the ->cra_driver_name.
	 */
	DMINFO("%s using implementation \"%s\"", ciphermode,
	       crypto_skcipher_alg(any_tfm(cc))->base.cra_driver_name);
	return 0;
}

@@ -1903,6 +1910,8 @@ static int crypt_alloc_tfms_aead(struct crypt_config *cc, char *ciphermode)
		return err;
	}

	DMINFO("%s using implementation \"%s\"", ciphermode,
	       crypto_aead_alg(any_tfm_aead(cc))->base.cra_driver_name);
	return 0;
}

@@ -2781,7 +2790,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	}

	ret = -EINVAL;
	if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
	if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
		ti->error = "Invalid device sector";
		goto bad;
	}
+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ static int delay_class_ctr(struct dm_target *ti, struct delay_class *c, char **a
	unsigned long long tmpll;
	char dummy;

	if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) {
	if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
		ti->error = "Invalid device sector";
		return -EINVAL;
	}
+23 −12
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	devname = dm_shift_arg(&as);

	r = -EINVAL;
	if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1) {
	if (sscanf(dm_shift_arg(&as), "%llu%c", &tmpll, &dummy) != 1 || tmpll != (sector_t)tmpll) {
		ti->error = "Invalid device sector";
		goto bad;
	}
@@ -287,20 +287,31 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)

static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
{
	unsigned bio_bytes = bio_cur_bytes(bio);
	char *data = bio_data(bio);
	unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1;

	struct bvec_iter iter;
	struct bio_vec bvec;

	if (!bio_has_data(bio))
		return;

	/*
	 * Overwrite the Nth byte of the data returned.
	 * Overwrite the Nth byte of the bio's data, on whichever page
	 * it falls.
	 */
	if (data && bio_bytes >= fc->corrupt_bio_byte) {
		data[fc->corrupt_bio_byte - 1] = fc->corrupt_bio_value;

	bio_for_each_segment(bvec, bio, iter) {
		if (bio_iter_len(bio, iter) > corrupt_bio_byte) {
			char *segment = (page_address(bio_iter_page(bio, iter))
					 + bio_iter_offset(bio, iter));
			segment[corrupt_bio_byte] = fc->corrupt_bio_value;
			DMDEBUG("Corrupting data bio=%p by writing %u to byte %u "
			"(rw=%c bi_opf=%u bi_sector=%llu cur_bytes=%u)\n",
				"(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n",
				bio, fc->corrupt_bio_value, fc->corrupt_bio_byte,
				(bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf,
			(unsigned long long)bio->bi_iter.bi_sector, bio_bytes);
				(unsigned long long)bio->bi_iter.bi_sector, bio->bi_iter.bi_size);
			break;
		}
		corrupt_bio_byte -= bio_iter_len(bio, iter);
	}
}

+1 −1
Original line number Diff line number Diff line
@@ -3460,7 +3460,7 @@ try_smaller_buffer:
			ti->error = "Recalculate is only valid with internal hash";
			goto bad;
		}
		ic->recalc_wq = alloc_workqueue("dm-intergrity-recalc", WQ_MEM_RECLAIM, 1);
		ic->recalc_wq = alloc_workqueue("dm-integrity-recalc", WQ_MEM_RECLAIM, 1);
		if (!ic->recalc_wq ) {
			ti->error = "Cannot allocate workqueue";
			r = -ENOMEM;
Loading