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

Commit 542f9038 authored by Mike Snitzer's avatar Mike Snitzer Committed by Alasdair G Kergon
Browse files

dm: support non power of two target max_io_len



Remove the restriction that limits a target's specified maximum incoming
I/O size to be a power of 2.

Rename this setting from 'split_io' to the less-ambiguous 'max_io_len'.
Change it from sector_t to uint32_t, which is plenty big enough, and
introduce a wrapper function dm_set_target_max_io_len() to set it.
Use sector_div() to process it now that it is not necessarily a power of 2.

Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 1df05483
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -353,6 +353,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
{
	unsigned i, rebuild_cnt = 0;
	unsigned long value, region_size = 0;
	sector_t max_io_len;
	char *key;

	/*
@@ -522,14 +523,12 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
		return -EINVAL;

	if (rs->md.chunk_sectors)
		rs->ti->split_io = rs->md.chunk_sectors;
		max_io_len = rs->md.chunk_sectors;
	else
		rs->ti->split_io = region_size;
		max_io_len = region_size;

	if (rs->md.chunk_sectors)
		rs->ti->split_io = rs->md.chunk_sectors;
	else
		rs->ti->split_io = region_size;
	if (dm_set_target_max_io_len(rs->ti, max_io_len))
		return -EINVAL;

	/* Assume there are no metadata devices until the drives are parsed */
	rs->md.persistent = 0;
+5 −1
Original line number Diff line number Diff line
@@ -1081,7 +1081,11 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	}

	ti->private = ms;
	ti->split_io = dm_rh_get_region_size(ms->rh);

	r = dm_set_target_max_io_len(ti, dm_rh_get_region_size(ms->rh));
	if (r)
		goto err_free_context;

	ti->num_flush_requests = 1;
	ti->num_discard_requests = 1;
	ti->discard_zeroes_data_unsupported = 1;
+15 −12
Original line number Diff line number Diff line
@@ -691,7 +691,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new)
 * Return a minimum chunk size of all snapshots that have the specified origin.
 * Return zero if the origin has no snapshots.
 */
static sector_t __minimum_chunk_size(struct origin *o)
static uint32_t __minimum_chunk_size(struct origin *o)
{
	struct dm_snapshot *snap;
	unsigned chunk_size = 0;
@@ -701,7 +701,7 @@ static sector_t __minimum_chunk_size(struct origin *o)
			chunk_size = min_not_zero(chunk_size,
						  snap->store->chunk_size);

	return chunk_size;
	return (uint32_t) chunk_size;
}

/*
@@ -1172,7 +1172,10 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
		ti->error = "Chunk size not set";
		goto bad_read_metadata;
	}
	ti->split_io = s->store->chunk_size;

	r = dm_set_target_max_io_len(ti, s->store->chunk_size);
	if (r)
		goto bad_read_metadata;

	return 0;

@@ -1239,7 +1242,7 @@ static void __handover_exceptions(struct dm_snapshot *snap_src,
	snap_dest->store->snap = snap_dest;
	snap_src->store->snap = snap_src;

	snap_dest->ti->split_io = snap_dest->store->chunk_size;
	snap_dest->ti->max_io_len = snap_dest->store->chunk_size;
	snap_dest->valid = snap_src->valid;

	/*
@@ -1817,9 +1820,9 @@ static void snapshot_resume(struct dm_target *ti)
	up_write(&s->lock);
}

static sector_t get_origin_minimum_chunksize(struct block_device *bdev)
static uint32_t get_origin_minimum_chunksize(struct block_device *bdev)
{
	sector_t min_chunksize;
	uint32_t min_chunksize;

	down_read(&_origins_lock);
	min_chunksize = __minimum_chunk_size(__lookup_origin(bdev));
@@ -1838,9 +1841,9 @@ static void snapshot_merge_resume(struct dm_target *ti)
	snapshot_resume(ti);

	/*
	 * snapshot-merge acts as an origin, so set ti->split_io
	 * snapshot-merge acts as an origin, so set ti->max_io_len
	 */
	ti->split_io = get_origin_minimum_chunksize(s->origin->bdev);
	ti->max_io_len = get_origin_minimum_chunksize(s->origin->bdev);

	start_merge(s);
}
@@ -2073,12 +2076,12 @@ static int origin_write_extent(struct dm_snapshot *merging_snap,
	struct origin *o;

	/*
	 * The origin's __minimum_chunk_size() got stored in split_io
	 * The origin's __minimum_chunk_size() got stored in max_io_len
	 * by snapshot_merge_resume().
	 */
	down_read(&_origins_lock);
	o = __lookup_origin(merging_snap->origin->bdev);
	for (n = 0; n < size; n += merging_snap->ti->split_io)
	for (n = 0; n < size; n += merging_snap->ti->max_io_len)
		if (__origin_write(&o->snapshots, sector + n, NULL) ==
		    DM_MAPIO_SUBMITTED)
			must_wait = 1;
@@ -2138,14 +2141,14 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
}

/*
 * Set the target "split_io" field to the minimum of all the snapshots'
 * Set the target "max_io_len" field to the minimum of all the snapshots'
 * chunk sizes.
 */
static void origin_resume(struct dm_target *ti)
{
	struct dm_dev *dev = ti->private;

	ti->split_io = get_origin_minimum_chunksize(dev->bdev);
	ti->max_io_len = get_origin_minimum_chunksize(dev->bdev);
}

static int origin_status(struct dm_target *ti, status_type_t type, char *result,
+4 −1
Original line number Diff line number Diff line
@@ -165,7 +165,10 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
	else
		sc->stripes_shift = __ffs(stripes);

	ti->split_io = chunk_size;
	r = dm_set_target_max_io_len(ti, chunk_size);
	if (r)
		return r;

	ti->num_flush_requests = stripes;
	ti->num_discard_requests = stripes;

+4 −1
Original line number Diff line number Diff line
@@ -2628,7 +2628,10 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
		goto bad_thin_open;
	}

	ti->split_io = tc->pool->sectors_per_block;
	r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block);
	if (r)
		goto bad_thin_open;

	ti->num_flush_requests = 1;

	/* In case the pool supports discards, pass them on. */
Loading