Commit 28436ba3 authored by Damien Le Moal's avatar Damien Le Moal Committed by Mike Snitzer
Browse files

dm zone: fix dm_revalidate_zones() memory allocation



Make sure that the zone write pointer offset array is allocated with a
vmalloc in dm_zone_revalidate_cb() by passing GFP_KERNEL gfp flag to
kvcalloc(). However, since we do not want to trigger IOs while
revalidating zones, change dm_revalidate_zones() to have the zone scan
done in GFP_NOIO context using memalloc_noio_save/restore calls.

Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Fixes: bb37d772 ("dm: introduce zone append emulation")
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 326dbde2
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ static int dm_zone_revalidate_cb(struct blk_zone *zone, unsigned int idx,
		if (!md->zwp_offset) {
			md->zwp_offset =
				kvcalloc(q->nr_zones, sizeof(unsigned int),
					 GFP_NOIO);
					 GFP_KERNEL);
			if (!md->zwp_offset)
				return -ENOMEM;
		}
@@ -230,6 +230,7 @@ static int dm_zone_revalidate_cb(struct blk_zone *zone, unsigned int idx,
static int dm_revalidate_zones(struct mapped_device *md, struct dm_table *t)
{
	struct request_queue *q = md->queue;
	unsigned int noio_flag;
	int ret;

	/*
@@ -241,9 +242,14 @@ static int dm_revalidate_zones(struct mapped_device *md, struct dm_table *t)
	if (md->nr_zones)
		return 0;

	/* Scan all zones to initialize everything */
	/*
	 * Scan all zones to initialize everything. Ensure that all vmalloc
	 * operations in this context are done as if GFP_NOIO was specified.
	 */
	noio_flag = memalloc_noio_save();
	ret = dm_blk_do_report_zones(md, t, 0, q->nr_zones,
				     dm_zone_revalidate_cb, md);
	memalloc_noio_restore(noio_flag);
	if (ret < 0)
		goto err;
	if (ret != q->nr_zones) {