// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2017 Western Digital Corporation or its affiliates.
 *
 * This file is released under the GPL.
 */

#include "dm-zoned.h"

#include <linux/module.h>
#include <linux/crc32.h>
#include <linux/sched/mm.h>

#define	DM_MSG_PREFIX		"zoned metadata"

/*
 * Metadata version.
 */
#define DMZ_META_VER	2

/*
 * On-disk super block magic.
 */
#define DMZ_MAGIC	((((unsigned int)('D')) << 24) | \
			 (((unsigned int)('Z')) << 16) | \
			 (((unsigned int)('B')) <<  8) | \
			 ((unsigned int)('D')))

/*
 * On disk super block.
 * This uses only 512 B but uses on disk a full 4KB block. This block is
 * followed on disk by the mapping table of chunks to zones and the bitmap
 * blocks indicating zone block validity.
 * The overall resulting metadata format is:
 *    (1) Super block (1 block)
 *    (2) Chunk mapping table (nr_map_blocks)
 *    (3) Bitmap blocks (nr_bitmap_blocks)
 * All metadata blocks are stored in conventional zones, starting from
 * the first conventional zone found on disk.
 */
struct dmz_super {
	/* Magic number */
	__le32		magic;			/*   4 */

	/* Metadata version number */
	__le32		version;		/*   8 */

	/* Generation number */
	__le64		gen;			/*  16 */

	/* This block number */
	__le64		sb_block;		/*  24 */

	/* The number of metadata blocks, including this super block */
	__le32		nr_meta_blocks;		/*  28 */

	/* The number of sequential zones reserved for reclaim */
	__le32		nr_reserved_seq;	/*  32 */

	/* The number of entries in the mapping table */
	__le32		nr_chunks;		/*  36 */

	/* The number of blocks used for the chunk mapping table */
	__le32		nr_map_blocks;		/*  40 */

	/* The number of blocks used for the block bitmaps */
	__le32		nr_bitmap_blocks;	/*  44 */

	/* Checksum */
	__le32		crc;			/*  48 */

	/* DM-Zoned label */
	u8		dmz_label[32];		/*  80 */

	/* DM-Zoned UUID */
	u8		dmz_uuid[16];		/*  96 */

	/* Device UUID */
	u8		dev_uuid[16];		/* 112 */

	/* Padding to full 512B sector */
	u8		reserved[400];		/* 512 */
};

/*
 * Chunk mapping entry: entries are indexed by chunk number
 * and give the zone ID (dzone_id) mapping the chunk on disk.
 * This zone may be sequential or random. If it is a sequential
 * zone, a second zone (bzone_id) used as a write buffer may
 * also be specified. This second zone will always be a randomly
 * writeable zone.
 */
struct dmz_map {
	__le32			dzone_id;
	__le32			bzone_id;
};

/*
 * Chunk mapping table metadata: 512 8-bytes entries per 4KB block.
 */
#define DMZ_MAP_ENTRIES		(DMZ_BLOCK_SIZE / sizeof(struct dmz_map))
#define DMZ_MAP_ENTRIES_SHIFT	(ilog2(DMZ_MAP_ENTRIES))
#define DMZ_MAP_ENTRIES_MASK	(DMZ_MAP_ENTRIES - 1)
#define DMZ_MAP_UNMAPPED	UINT_MAX

/*
 * Meta data block descriptor (for cached metadata blocks).
 */
struct dmz_mblock {
	struct rb_node		node;
	struct list_head	link;
	sector_t		no;
	unsigned int		ref;
	unsigned long		state;
	struct page		*page;
	void			*data;
};

/*
 * Metadata block state flags.
 */
enum {
	DMZ_META_DIRTY,
	DMZ_META_READING,
	DMZ_META_WRITING,
	DMZ_META_ERROR,
};

/*
 * Super block information (one per metadata set).
 */
struct dmz_sb {
	sector_t		block;
	struct dmz_dev		*dev;
	struct dmz_mblock	*mblk;
	struct dmz_super	*sb;
	struct dm_zone		*zone;
};

/*
 * In-memory metadata.
 */
struct dmz_metadata {
	struct dmz_dev		*dev;
	unsigned int		nr_devs;

	char			devname[BDEVNAME_SIZE];
	char			label[BDEVNAME_SIZE];
	uuid_t			uuid;

	sector_t		zone_bitmap_size;
	unsigned int		zone_nr_bitmap_blocks;
	unsigned int		zone_bits_per_mblk;

	sector_t		zone_nr_blocks;
	sector_t		zone_nr_blocks_shift;

	sector_t		zone_nr_sectors;
	sector_t		zone_nr_sectors_shift;

	unsigned int		nr_bitmap_blocks;
	unsigned int		nr_map_blocks;

	unsigned int		nr_zones;
	unsigned int		nr_useable_zones;
	unsigned int		nr_meta_blocks;
	unsigned int		nr_meta_zones;
	unsigned int		nr_data_zones;
	unsigned int		nr_cache_zones;
	unsigned int		nr_rnd_zones;
	unsigned int		nr_reserved_seq;
	unsigned int		nr_chunks;

	/* Zone information array */
	struct xarray		zones;

	struct dmz_sb		sb[2];
	unsigned int		mblk_primary;
	unsigned int		sb_version;
	u64			sb_gen;
	unsigned int		min_nr_mblks;
	unsigned int		max_nr_mblks;
	atomic_t		nr_mblks;
	struct rw_semaphore	mblk_sem;
	struct mutex		mblk_flush_lock;
	spinlock_t		mblk_lock;
	struct rb_root		mblk_rbtree;
	struct list_head	mblk_lru_list;
	struct list_head	mblk_dirty_list;
	struct shrinker		*mblk_shrinker;

	/* Zone allocation management */
	struct mutex		map_lock;
	struct dmz_mblock	**map_mblk;

	unsigned int		nr_cache;
	atomic_t		unmap_nr_cache;
	struct list_head	unmap_cache_list;
	struct list_head	map_cache_list;

	atomic_t		nr_reserved_seq_zones;
	struct list_head	reserved_seq_zones_list;

	wait_queue_head_t	free_wq;
};

#define dmz_zmd_info(zmd, format, args...)	\
	DMINFO("(%s): " format, (zmd)->label, ## args)

#define dmz_zmd_err(zmd, format, args...)	\
	DMERR("(%s): " format, (zmd)->label, ## args)

#define dmz_zmd_warn(zmd, format, args...)	\
	DMWARN("(%s): " format, (zmd)->label, ## args)

#define dmz_zmd_debug(zmd, format, args...)	\
	DMDEBUG("(%s): " format, (zmd)->label, ## args)
/*
 * Various accessors
 */
static unsigned int dmz_dev_zone_id(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	if (WARN_ON(!zone))
		return 0;

	return zone->id - zone->dev->zone_offset;
}

sector_t dmz_start_sect(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	unsigned int zone_id = dmz_dev_zone_id(zmd, zone);

	return (sector_t)zone_id << zmd->zone_nr_sectors_shift;
}

sector_t dmz_start_block(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	unsigned int zone_id = dmz_dev_zone_id(zmd, zone);

	return (sector_t)zone_id << zmd->zone_nr_blocks_shift;
}

unsigned int dmz_zone_nr_blocks(struct dmz_metadata *zmd)
{
	return zmd->zone_nr_blocks;
}

unsigned int dmz_zone_nr_sectors(struct dmz_metadata *zmd)
{
	return zmd->zone_nr_sectors;
}

unsigned int dmz_zone_nr_sectors_shift(struct dmz_metadata *zmd)
{
	return zmd->zone_nr_sectors_shift;
}

unsigned int dmz_nr_zones(struct dmz_metadata *zmd)
{
	return zmd->nr_zones;
}

unsigned int dmz_nr_chunks(struct dmz_metadata *zmd)
{
	return zmd->nr_chunks;
}

unsigned int dmz_nr_rnd_zones(struct dmz_metadata *zmd, int idx)
{
	return zmd->dev[idx].nr_rnd;
}

unsigned int dmz_nr_unmap_rnd_zones(struct dmz_metadata *zmd, int idx)
{
	return atomic_read(&zmd->dev[idx].unmap_nr_rnd);
}

unsigned int dmz_nr_cache_zones(struct dmz_metadata *zmd)
{
	return zmd->nr_cache;
}

unsigned int dmz_nr_unmap_cache_zones(struct dmz_metadata *zmd)
{
	return atomic_read(&zmd->unmap_nr_cache);
}

unsigned int dmz_nr_seq_zones(struct dmz_metadata *zmd, int idx)
{
	return zmd->dev[idx].nr_seq;
}

unsigned int dmz_nr_unmap_seq_zones(struct dmz_metadata *zmd, int idx)
{
	return atomic_read(&zmd->dev[idx].unmap_nr_seq);
}

static struct dm_zone *dmz_get(struct dmz_metadata *zmd, unsigned int zone_id)
{
	return xa_load(&zmd->zones, zone_id);
}

static struct dm_zone *dmz_insert(struct dmz_metadata *zmd,
				  unsigned int zone_id, struct dmz_dev *dev)
{
	struct dm_zone *zone = kzalloc(sizeof(struct dm_zone), GFP_KERNEL);

	if (!zone)
		return ERR_PTR(-ENOMEM);

	if (xa_insert(&zmd->zones, zone_id, zone, GFP_KERNEL)) {
		kfree(zone);
		return ERR_PTR(-EBUSY);
	}

	INIT_LIST_HEAD(&zone->link);
	atomic_set(&zone->refcount, 0);
	zone->id = zone_id;
	zone->chunk = DMZ_MAP_UNMAPPED;
	zone->dev = dev;

	return zone;
}

const char *dmz_metadata_label(struct dmz_metadata *zmd)
{
	return (const char *)zmd->label;
}

bool dmz_check_dev(struct dmz_metadata *zmd)
{
	unsigned int i;

	for (i = 0; i < zmd->nr_devs; i++) {
		if (!dmz_check_bdev(&zmd->dev[i]))
			return false;
	}
	return true;
}

bool dmz_dev_is_dying(struct dmz_metadata *zmd)
{
	unsigned int i;

	for (i = 0; i < zmd->nr_devs; i++) {
		if (dmz_bdev_is_dying(&zmd->dev[i]))
			return true;
	}
	return false;
}

/*
 * Lock/unlock mapping table.
 * The map lock also protects all the zone lists.
 */
void dmz_lock_map(struct dmz_metadata *zmd)
{
	mutex_lock(&zmd->map_lock);
}

void dmz_unlock_map(struct dmz_metadata *zmd)
{
	mutex_unlock(&zmd->map_lock);
}

/*
 * Lock/unlock metadata access. This is a "read" lock on a semaphore
 * that prevents metadata flush from running while metadata are being
 * modified. The actual metadata write mutual exclusion is achieved with
 * the map lock and zone state management (active and reclaim state are
 * mutually exclusive).
 */
void dmz_lock_metadata(struct dmz_metadata *zmd)
{
	down_read(&zmd->mblk_sem);
}

void dmz_unlock_metadata(struct dmz_metadata *zmd)
{
	up_read(&zmd->mblk_sem);
}

/*
 * Lock/unlock flush: prevent concurrent executions
 * of dmz_flush_metadata as well as metadata modification in reclaim
 * while flush is being executed.
 */
void dmz_lock_flush(struct dmz_metadata *zmd)
{
	mutex_lock(&zmd->mblk_flush_lock);
}

void dmz_unlock_flush(struct dmz_metadata *zmd)
{
	mutex_unlock(&zmd->mblk_flush_lock);
}

/*
 * Allocate a metadata block.
 */
static struct dmz_mblock *dmz_alloc_mblock(struct dmz_metadata *zmd,
					   sector_t mblk_no)
{
	struct dmz_mblock *mblk = NULL;

	/* See if we can reuse cached blocks */
	if (zmd->max_nr_mblks && atomic_read(&zmd->nr_mblks) > zmd->max_nr_mblks) {
		spin_lock(&zmd->mblk_lock);
		mblk = list_first_entry_or_null(&zmd->mblk_lru_list,
						struct dmz_mblock, link);
		if (mblk) {
			list_del_init(&mblk->link);
			rb_erase(&mblk->node, &zmd->mblk_rbtree);
			mblk->no = mblk_no;
		}
		spin_unlock(&zmd->mblk_lock);
		if (mblk)
			return mblk;
	}

	/* Allocate a new block */
	mblk = kmalloc(sizeof(struct dmz_mblock), GFP_NOIO);
	if (!mblk)
		return NULL;

	mblk->page = alloc_page(GFP_NOIO);
	if (!mblk->page) {
		kfree(mblk);
		return NULL;
	}

	RB_CLEAR_NODE(&mblk->node);
	INIT_LIST_HEAD(&mblk->link);
	mblk->ref = 0;
	mblk->state = 0;
	mblk->no = mblk_no;
	mblk->data = page_address(mblk->page);

	atomic_inc(&zmd->nr_mblks);

	return mblk;
}

/*
 * Free a metadata block.
 */
static void dmz_free_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk)
{
	__free_pages(mblk->page, 0);
	kfree(mblk);

	atomic_dec(&zmd->nr_mblks);
}

/*
 * Insert a metadata block in the rbtree.
 */
static void dmz_insert_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk)
{
	struct rb_root *root = &zmd->mblk_rbtree;
	struct rb_node **new = &(root->rb_node), *parent = NULL;
	struct dmz_mblock *b;

	/* Figure out where to put the new node */
	while (*new) {
		b = container_of(*new, struct dmz_mblock, node);
		parent = *new;
		new = (b->no < mblk->no) ? &((*new)->rb_left) : &((*new)->rb_right);
	}

	/* Add new node and rebalance tree */
	rb_link_node(&mblk->node, parent, new);
	rb_insert_color(&mblk->node, root);
}

/*
 * Lookup a metadata block in the rbtree. If the block is found, increment
 * its reference count.
 */
static struct dmz_mblock *dmz_get_mblock_fast(struct dmz_metadata *zmd,
					      sector_t mblk_no)
{
	struct rb_root *root = &zmd->mblk_rbtree;
	struct rb_node *node = root->rb_node;
	struct dmz_mblock *mblk;

	while (node) {
		mblk = container_of(node, struct dmz_mblock, node);
		if (mblk->no == mblk_no) {
			/*
			 * If this is the first reference to the block,
			 * remove it from the LRU list.
			 */
			mblk->ref++;
			if (mblk->ref == 1 &&
			    !test_bit(DMZ_META_DIRTY, &mblk->state))
				list_del_init(&mblk->link);
			return mblk;
		}
		node = (mblk->no < mblk_no) ? node->rb_left : node->rb_right;
	}

	return NULL;
}

/*
 * Metadata block BIO end callback.
 */
static void dmz_mblock_bio_end_io(struct bio *bio)
{
	struct dmz_mblock *mblk = bio->bi_private;
	int flag;

	if (bio->bi_status)
		set_bit(DMZ_META_ERROR, &mblk->state);

	if (bio_op(bio) == REQ_OP_WRITE)
		flag = DMZ_META_WRITING;
	else
		flag = DMZ_META_READING;

	clear_bit_unlock(flag, &mblk->state);
	smp_mb__after_atomic();
	wake_up_bit(&mblk->state, flag);

	bio_put(bio);
}

/*
 * Read an uncached metadata block from disk and add it to the cache.
 */
static struct dmz_mblock *dmz_get_mblock_slow(struct dmz_metadata *zmd,
					      sector_t mblk_no)
{
	struct dmz_mblock *mblk, *m;
	sector_t block = zmd->sb[zmd->mblk_primary].block + mblk_no;
	struct dmz_dev *dev = zmd->sb[zmd->mblk_primary].dev;
	struct bio *bio;

	if (dmz_bdev_is_dying(dev))
		return ERR_PTR(-EIO);

	/* Get a new block and a BIO to read it */
	mblk = dmz_alloc_mblock(zmd, mblk_no);
	if (!mblk)
		return ERR_PTR(-ENOMEM);

	bio = bio_alloc(dev->bdev, 1, REQ_OP_READ | REQ_META | REQ_PRIO,
			GFP_NOIO);

	spin_lock(&zmd->mblk_lock);

	/*
	 * Make sure that another context did not start reading
	 * the block already.
	 */
	m = dmz_get_mblock_fast(zmd, mblk_no);
	if (m) {
		spin_unlock(&zmd->mblk_lock);
		dmz_free_mblock(zmd, mblk);
		bio_put(bio);
		return m;
	}

	mblk->ref++;
	set_bit(DMZ_META_READING, &mblk->state);
	dmz_insert_mblock(zmd, mblk);

	spin_unlock(&zmd->mblk_lock);

	/* Submit read BIO */
	bio->bi_iter.bi_sector = dmz_blk2sect(block);
	bio->bi_private = mblk;
	bio->bi_end_io = dmz_mblock_bio_end_io;
	__bio_add_page(bio, mblk->page, DMZ_BLOCK_SIZE, 0);
	submit_bio(bio);

	return mblk;
}

/*
 * Free metadata blocks.
 */
static unsigned long dmz_shrink_mblock_cache(struct dmz_metadata *zmd,
					     unsigned long limit)
{
	struct dmz_mblock *mblk;
	unsigned long count = 0;

	if (!zmd->max_nr_mblks)
		return 0;

	while (!list_empty(&zmd->mblk_lru_list) &&
	       atomic_read(&zmd->nr_mblks) > zmd->min_nr_mblks &&
	       count < limit) {
		mblk = list_first_entry(&zmd->mblk_lru_list,
					struct dmz_mblock, link);
		list_del_init(&mblk->link);
		rb_erase(&mblk->node, &zmd->mblk_rbtree);
		dmz_free_mblock(zmd, mblk);
		count++;
	}

	return count;
}

/*
 * For mblock shrinker: get the number of unused metadata blocks in the cache.
 */
static unsigned long dmz_mblock_shrinker_count(struct shrinker *shrink,
					       struct shrink_control *sc)
{
	struct dmz_metadata *zmd = shrink->private_data;

	return atomic_read(&zmd->nr_mblks);
}

/*
 * For mblock shrinker: scan unused metadata blocks and shrink the cache.
 */
static unsigned long dmz_mblock_shrinker_scan(struct shrinker *shrink,
					      struct shrink_control *sc)
{
	struct dmz_metadata *zmd = shrink->private_data;
	unsigned long count;

	spin_lock(&zmd->mblk_lock);
	count = dmz_shrink_mblock_cache(zmd, sc->nr_to_scan);
	spin_unlock(&zmd->mblk_lock);

	return count ? count : SHRINK_STOP;
}

/*
 * Release a metadata block.
 */
static void dmz_release_mblock(struct dmz_metadata *zmd,
			       struct dmz_mblock *mblk)
{

	if (!mblk)
		return;

	spin_lock(&zmd->mblk_lock);

	mblk->ref--;
	if (mblk->ref == 0) {
		if (test_bit(DMZ_META_ERROR, &mblk->state)) {
			rb_erase(&mblk->node, &zmd->mblk_rbtree);
			dmz_free_mblock(zmd, mblk);
		} else if (!test_bit(DMZ_META_DIRTY, &mblk->state)) {
			list_add_tail(&mblk->link, &zmd->mblk_lru_list);
			dmz_shrink_mblock_cache(zmd, 1);
		}
	}

	spin_unlock(&zmd->mblk_lock);
}

/*
 * Get a metadata block from the rbtree. If the block
 * is not present, read it from disk.
 */
static struct dmz_mblock *dmz_get_mblock(struct dmz_metadata *zmd,
					 sector_t mblk_no)
{
	struct dmz_mblock *mblk;
	struct dmz_dev *dev = zmd->sb[zmd->mblk_primary].dev;

	/* Check rbtree */
	spin_lock(&zmd->mblk_lock);
	mblk = dmz_get_mblock_fast(zmd, mblk_no);
	spin_unlock(&zmd->mblk_lock);

	if (!mblk) {
		/* Cache miss: read the block from disk */
		mblk = dmz_get_mblock_slow(zmd, mblk_no);
		if (IS_ERR(mblk))
			return mblk;
	}

	/* Wait for on-going read I/O and check for error */
	wait_on_bit_io(&mblk->state, DMZ_META_READING,
		       TASK_UNINTERRUPTIBLE);
	if (test_bit(DMZ_META_ERROR, &mblk->state)) {
		dmz_release_mblock(zmd, mblk);
		dmz_check_bdev(dev);
		return ERR_PTR(-EIO);
	}

	return mblk;
}

/*
 * Mark a metadata block dirty.
 */
static void dmz_dirty_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk)
{
	spin_lock(&zmd->mblk_lock);
	if (!test_and_set_bit(DMZ_META_DIRTY, &mblk->state))
		list_add_tail(&mblk->link, &zmd->mblk_dirty_list);
	spin_unlock(&zmd->mblk_lock);
}

/*
 * Issue a metadata block write BIO.
 */
static int dmz_write_mblock(struct dmz_metadata *zmd, struct dmz_mblock *mblk,
			    unsigned int set)
{
	struct dmz_dev *dev = zmd->sb[set].dev;
	sector_t block = zmd->sb[set].block + mblk->no;
	struct bio *bio;

	if (dmz_bdev_is_dying(dev))
		return -EIO;

	bio = bio_alloc(dev->bdev, 1, REQ_OP_WRITE | REQ_META | REQ_PRIO,
			GFP_NOIO);

	set_bit(DMZ_META_WRITING, &mblk->state);

	bio->bi_iter.bi_sector = dmz_blk2sect(block);
	bio->bi_private = mblk;
	bio->bi_end_io = dmz_mblock_bio_end_io;
	__bio_add_page(bio, mblk->page, DMZ_BLOCK_SIZE, 0);
	submit_bio(bio);

	return 0;
}

/*
 * Read/write a metadata block.
 */
static int dmz_rdwr_block(struct dmz_dev *dev, enum req_op op,
			  sector_t block, struct page *page)
{
	struct bio *bio;
	int ret;

	if (WARN_ON(!dev))
		return -EIO;

	if (dmz_bdev_is_dying(dev))
		return -EIO;

	bio = bio_alloc(dev->bdev, 1, op | REQ_SYNC | REQ_META | REQ_PRIO,
			GFP_NOIO);
	bio->bi_iter.bi_sector = dmz_blk2sect(block);
	__bio_add_page(bio, page, DMZ_BLOCK_SIZE, 0);
	ret = submit_bio_wait(bio);
	bio_put(bio);

	if (ret)
		dmz_check_bdev(dev);
	return ret;
}

/*
 * Write super block of the specified metadata set.
 */
static int dmz_write_sb(struct dmz_metadata *zmd, unsigned int set)
{
	struct dmz_mblock *mblk = zmd->sb[set].mblk;
	struct dmz_super *sb = zmd->sb[set].sb;
	struct dmz_dev *dev = zmd->sb[set].dev;
	sector_t sb_block;
	u64 sb_gen = zmd->sb_gen + 1;
	int ret;

	sb->magic = cpu_to_le32(DMZ_MAGIC);

	sb->version = cpu_to_le32(zmd->sb_version);
	if (zmd->sb_version > 1) {
		BUILD_BUG_ON(UUID_SIZE != 16);
		export_uuid(sb->dmz_uuid, &zmd->uuid);
		memcpy(sb->dmz_label, zmd->label, BDEVNAME_SIZE);
		export_uuid(sb->dev_uuid, &dev->uuid);
	}

	sb->gen = cpu_to_le64(sb_gen);

	/*
	 * The metadata always references the absolute block address,
	 * ie relative to the entire block range, not the per-device
	 * block address.
	 */
	sb_block = zmd->sb[set].zone->id << zmd->zone_nr_blocks_shift;
	sb->sb_block = cpu_to_le64(sb_block);
	sb->nr_meta_blocks = cpu_to_le32(zmd->nr_meta_blocks);
	sb->nr_reserved_seq = cpu_to_le32(zmd->nr_reserved_seq);
	sb->nr_chunks = cpu_to_le32(zmd->nr_chunks);

	sb->nr_map_blocks = cpu_to_le32(zmd->nr_map_blocks);
	sb->nr_bitmap_blocks = cpu_to_le32(zmd->nr_bitmap_blocks);

	sb->crc = 0;
	sb->crc = cpu_to_le32(crc32_le(sb_gen, (unsigned char *)sb, DMZ_BLOCK_SIZE));

	ret = dmz_rdwr_block(dev, REQ_OP_WRITE, zmd->sb[set].block,
			     mblk->page);
	if (ret == 0)
		ret = blkdev_issue_flush(dev->bdev);

	return ret;
}

/*
 * Write dirty metadata blocks to the specified set.
 */
static int dmz_write_dirty_mblocks(struct dmz_metadata *zmd,
				   struct list_head *write_list,
				   unsigned int set)
{
	struct dmz_mblock *mblk;
	struct dmz_dev *dev = zmd->sb[set].dev;
	struct blk_plug plug;
	int ret = 0, nr_mblks_submitted = 0;

	/* Issue writes */
	blk_start_plug(&plug);
	list_for_each_entry(mblk, write_list, link) {
		ret = dmz_write_mblock(zmd, mblk, set);
		if (ret)
			break;
		nr_mblks_submitted++;
	}
	blk_finish_plug(&plug);

	/* Wait for completion */
	list_for_each_entry(mblk, write_list, link) {
		if (!nr_mblks_submitted)
			break;
		wait_on_bit_io(&mblk->state, DMZ_META_WRITING,
			       TASK_UNINTERRUPTIBLE);
		if (test_bit(DMZ_META_ERROR, &mblk->state)) {
			clear_bit(DMZ_META_ERROR, &mblk->state);
			dmz_check_bdev(dev);
			ret = -EIO;
		}
		nr_mblks_submitted--;
	}

	/* Flush drive cache (this will also sync data) */
	if (ret == 0)
		ret = blkdev_issue_flush(dev->bdev);

	return ret;
}

/*
 * Log dirty metadata blocks.
 */
static int dmz_log_dirty_mblocks(struct dmz_metadata *zmd,
				 struct list_head *write_list)
{
	unsigned int log_set = zmd->mblk_primary ^ 0x1;
	int ret;

	/* Write dirty blocks to the log */
	ret = dmz_write_dirty_mblocks(zmd, write_list, log_set);
	if (ret)
		return ret;

	/*
	 * No error so far: now validate the log by updating the
	 * log index super block generation.
	 */
	ret = dmz_write_sb(zmd, log_set);
	if (ret)
		return ret;

	return 0;
}

/*
 * Flush dirty metadata blocks.
 */
int dmz_flush_metadata(struct dmz_metadata *zmd)
{
	struct dmz_mblock *mblk;
	struct list_head write_list;
	struct dmz_dev *dev;
	int ret;

	if (WARN_ON(!zmd))
		return 0;

	INIT_LIST_HEAD(&write_list);

	/*
	 * Make sure that metadata blocks are stable before logging: take
	 * the write lock on the metadata semaphore to prevent target BIOs
	 * from modifying metadata.
	 */
	down_write(&zmd->mblk_sem);
	dev = zmd->sb[zmd->mblk_primary].dev;

	/*
	 * This is called from the target flush work and reclaim work.
	 * Concurrent execution is not allowed.
	 */
	dmz_lock_flush(zmd);

	if (dmz_bdev_is_dying(dev)) {
		ret = -EIO;
		goto out;
	}

	/* Get dirty blocks */
	spin_lock(&zmd->mblk_lock);
	list_splice_init(&zmd->mblk_dirty_list, &write_list);
	spin_unlock(&zmd->mblk_lock);

	/* If there are no dirty metadata blocks, just flush the device cache */
	if (list_empty(&write_list)) {
		ret = blkdev_issue_flush(dev->bdev);
		goto err;
	}

	/*
	 * The primary metadata set is still clean. Keep it this way until
	 * all updates are successful in the secondary set. That is, use
	 * the secondary set as a log.
	 */
	ret = dmz_log_dirty_mblocks(zmd, &write_list);
	if (ret)
		goto err;

	/*
	 * The log is on disk. It is now safe to update in place
	 * in the primary metadata set.
	 */
	ret = dmz_write_dirty_mblocks(zmd, &write_list, zmd->mblk_primary);
	if (ret)
		goto err;

	ret = dmz_write_sb(zmd, zmd->mblk_primary);
	if (ret)
		goto err;

	while (!list_empty(&write_list)) {
		mblk = list_first_entry(&write_list, struct dmz_mblock, link);
		list_del_init(&mblk->link);

		spin_lock(&zmd->mblk_lock);
		clear_bit(DMZ_META_DIRTY, &mblk->state);
		if (mblk->ref == 0)
			list_add_tail(&mblk->link, &zmd->mblk_lru_list);
		spin_unlock(&zmd->mblk_lock);
	}

	zmd->sb_gen++;
out:
	dmz_unlock_flush(zmd);
	up_write(&zmd->mblk_sem);

	return ret;

err:
	if (!list_empty(&write_list)) {
		spin_lock(&zmd->mblk_lock);
		list_splice(&write_list, &zmd->mblk_dirty_list);
		spin_unlock(&zmd->mblk_lock);
	}
	if (!dmz_check_bdev(dev))
		ret = -EIO;
	goto out;
}

/*
 * Check super block.
 */
static int dmz_check_sb(struct dmz_metadata *zmd, struct dmz_sb *dsb,
			bool tertiary)
{
	struct dmz_super *sb = dsb->sb;
	struct dmz_dev *dev = dsb->dev;
	unsigned int nr_meta_zones, nr_data_zones;
	u32 crc, stored_crc;
	u64 gen, sb_block;

	if (le32_to_cpu(sb->magic) != DMZ_MAGIC) {
		dmz_dev_err(dev, "Invalid meta magic (needed 0x%08x, got 0x%08x)",
			    DMZ_MAGIC, le32_to_cpu(sb->magic));
		return -ENXIO;
	}

	zmd->sb_version = le32_to_cpu(sb->version);
	if (zmd->sb_version > DMZ_META_VER) {
		dmz_dev_err(dev, "Invalid meta version (needed %d, got %d)",
			    DMZ_META_VER, zmd->sb_version);
		return -EINVAL;
	}
	if (zmd->sb_version < 2 && tertiary) {
		dmz_dev_err(dev, "Tertiary superblocks are not supported");
		return -EINVAL;
	}

	gen = le64_to_cpu(sb->gen);
	stored_crc = le32_to_cpu(sb->crc);
	sb->crc = 0;
	crc = crc32_le(gen, (unsigned char *)sb, DMZ_BLOCK_SIZE);
	if (crc != stored_crc) {
		dmz_dev_err(dev, "Invalid checksum (needed 0x%08x, got 0x%08x)",
			    crc, stored_crc);
		return -ENXIO;
	}

	sb_block = le64_to_cpu(sb->sb_block);
	if (sb_block != (u64)dsb->zone->id << zmd->zone_nr_blocks_shift) {
		dmz_dev_err(dev, "Invalid superblock position (is %llu expected %llu)",
			    sb_block, (u64)dsb->zone->id << zmd->zone_nr_blocks_shift);
		return -EINVAL;
	}
	if (zmd->sb_version > 1) {
		uuid_t sb_uuid;

		import_uuid(&sb_uuid, sb->dmz_uuid);
		if (uuid_is_null(&sb_uuid)) {
			dmz_dev_err(dev, "NULL DM-Zoned uuid");
			return -ENXIO;
		} else if (uuid_is_null(&zmd->uuid)) {
			uuid_copy(&zmd->uuid, &sb_uuid);
		} else if (!uuid_equal(&zmd->uuid, &sb_uuid)) {
			dmz_dev_err(dev, "mismatching DM-Zoned uuid, is %pUl expected %pUl",
				    &sb_uuid, &zmd->uuid);
			return -ENXIO;
		}
		if (!strlen(zmd->label))
			memcpy(zmd->label, sb->dmz_label, BDEVNAME_SIZE);
		else if (memcmp(zmd->label, sb->dmz_label, BDEVNAME_SIZE)) {
			dmz_dev_err(dev, "mismatching DM-Zoned label, is %s expected %s",
				    sb->dmz_label, zmd->label);
			return -ENXIO;
		}
		import_uuid(&dev->uuid, sb->dev_uuid);
		if (uuid_is_null(&dev->uuid)) {
			dmz_dev_err(dev, "NULL device uuid");
			return -ENXIO;
		}

		if (tertiary) {
			/*
			 * Generation number should be 0, but it doesn't
			 * really matter if it isn't.
			 */
			if (gen != 0)
				dmz_dev_warn(dev, "Invalid generation %llu",
					    gen);
			return 0;
		}
	}

	nr_meta_zones = (le32_to_cpu(sb->nr_meta_blocks) + zmd->zone_nr_blocks - 1)
		>> zmd->zone_nr_blocks_shift;
	if (!nr_meta_zones ||
	    (zmd->nr_devs <= 1 && nr_meta_zones >= zmd->nr_rnd_zones) ||
	    (zmd->nr_devs > 1 && nr_meta_zones >= zmd->nr_cache_zones)) {
		dmz_dev_err(dev, "Invalid number of metadata blocks");
		return -ENXIO;
	}

	if (!le32_to_cpu(sb->nr_reserved_seq) ||
	    le32_to_cpu(sb->nr_reserved_seq) >= (zmd->nr_useable_zones - nr_meta_zones)) {
		dmz_dev_err(dev, "Invalid number of reserved sequential zones");
		return -ENXIO;
	}

	nr_data_zones = zmd->nr_useable_zones -
		(nr_meta_zones * 2 + le32_to_cpu(sb->nr_reserved_seq));
	if (le32_to_cpu(sb->nr_chunks) > nr_data_zones) {
		dmz_dev_err(dev, "Invalid number of chunks %u / %u",
			    le32_to_cpu(sb->nr_chunks), nr_data_zones);
		return -ENXIO;
	}

	/* OK */
	zmd->nr_meta_blocks = le32_to_cpu(sb->nr_meta_blocks);
	zmd->nr_reserved_seq = le32_to_cpu(sb->nr_reserved_seq);
	zmd->nr_chunks = le32_to_cpu(sb->nr_chunks);
	zmd->nr_map_blocks = le32_to_cpu(sb->nr_map_blocks);
	zmd->nr_bitmap_blocks = le32_to_cpu(sb->nr_bitmap_blocks);
	zmd->nr_meta_zones = nr_meta_zones;
	zmd->nr_data_zones = nr_data_zones;

	return 0;
}

/*
 * Read the first or second super block from disk.
 */
static int dmz_read_sb(struct dmz_metadata *zmd, struct dmz_sb *sb, int set)
{
	dmz_zmd_debug(zmd, "read superblock set %d dev %pg block %llu",
		      set, sb->dev->bdev, sb->block);

	return dmz_rdwr_block(sb->dev, REQ_OP_READ,
			      sb->block, sb->mblk->page);
}

/*
 * Determine the position of the secondary super blocks on disk.
 * This is used only if a corruption of the primary super block
 * is detected.
 */
static int dmz_lookup_secondary_sb(struct dmz_metadata *zmd)
{
	unsigned int zone_nr_blocks = zmd->zone_nr_blocks;
	struct dmz_mblock *mblk;
	unsigned int zone_id = zmd->sb[0].zone->id;
	int i;

	/* Allocate a block */
	mblk = dmz_alloc_mblock(zmd, 0);
	if (!mblk)
		return -ENOMEM;

	zmd->sb[1].mblk = mblk;
	zmd->sb[1].sb = mblk->data;

	/* Bad first super block: search for the second one */
	zmd->sb[1].block = zmd->sb[0].block + zone_nr_blocks;
	zmd->sb[1].zone = dmz_get(zmd, zone_id + 1);
	zmd->sb[1].dev = zmd->sb[0].dev;
	for (i = 1; i < zmd->nr_rnd_zones; i++) {
		if (dmz_read_sb(zmd, &zmd->sb[1], 1) != 0)
			break;
		if (le32_to_cpu(zmd->sb[1].sb->magic) == DMZ_MAGIC)
			return 0;
		zmd->sb[1].block += zone_nr_blocks;
		zmd->sb[1].zone = dmz_get(zmd, zone_id + i);
	}

	dmz_free_mblock(zmd, mblk);
	zmd->sb[1].mblk = NULL;
	zmd->sb[1].zone = NULL;
	zmd->sb[1].dev = NULL;

	return -EIO;
}

/*
 * Read a super block from disk.
 */
static int dmz_get_sb(struct dmz_metadata *zmd, struct dmz_sb *sb, int set)
{
	struct dmz_mblock *mblk;
	int ret;

	/* Allocate a block */
	mblk = dmz_alloc_mblock(zmd, 0);
	if (!mblk)
		return -ENOMEM;

	sb->mblk = mblk;
	sb->sb = mblk->data;

	/* Read super block */
	ret = dmz_read_sb(zmd, sb, set);
	if (ret) {
		dmz_free_mblock(zmd, mblk);
		sb->mblk = NULL;
		return ret;
	}

	return 0;
}

/*
 * Recover a metadata set.
 */
static int dmz_recover_mblocks(struct dmz_metadata *zmd, unsigned int dst_set)
{
	unsigned int src_set = dst_set ^ 0x1;
	struct page *page;
	int i, ret;

	dmz_dev_warn(zmd->sb[dst_set].dev,
		     "Metadata set %u invalid: recovering", dst_set);

	if (dst_set == 0)
		zmd->sb[0].block = dmz_start_block(zmd, zmd->sb[0].zone);
	else
		zmd->sb[1].block = dmz_start_block(zmd, zmd->sb[1].zone);

	page = alloc_page(GFP_NOIO);
	if (!page)
		return -ENOMEM;

	/* Copy metadata blocks */
	for (i = 1; i < zmd->nr_meta_blocks; i++) {
		ret = dmz_rdwr_block(zmd->sb[src_set].dev, REQ_OP_READ,
				     zmd->sb[src_set].block + i, page);
		if (ret)
			goto out;
		ret = dmz_rdwr_block(zmd->sb[dst_set].dev, REQ_OP_WRITE,
				     zmd->sb[dst_set].block + i, page);
		if (ret)
			goto out;
	}

	/* Finalize with the super block */
	if (!zmd->sb[dst_set].mblk) {
		zmd->sb[dst_set].mblk = dmz_alloc_mblock(zmd, 0);
		if (!zmd->sb[dst_set].mblk) {
			ret = -ENOMEM;
			goto out;
		}
		zmd->sb[dst_set].sb = zmd->sb[dst_set].mblk->data;
	}

	ret = dmz_write_sb(zmd, dst_set);
out:
	__free_pages(page, 0);

	return ret;
}

/*
 * Get super block from disk.
 */
static int dmz_load_sb(struct dmz_metadata *zmd)
{
	bool sb_good[2] = {false, false};
	u64 sb_gen[2] = {0, 0};
	int ret;

	if (!zmd->sb[0].zone) {
		dmz_zmd_err(zmd, "Primary super block zone not set");
		return -ENXIO;
	}

	/* Read and check the primary super block */
	zmd->sb[0].block = dmz_start_block(zmd, zmd->sb[0].zone);
	zmd->sb[0].dev = zmd->sb[0].zone->dev;
	ret = dmz_get_sb(zmd, &zmd->sb[0], 0);
	if (ret) {
		dmz_dev_err(zmd->sb[0].dev, "Read primary super block failed");
		return ret;
	}

	ret = dmz_check_sb(zmd, &zmd->sb[0], false);

	/* Read and check secondary super block */
	if (ret == 0) {
		sb_good[0] = true;
		if (!zmd->sb[1].zone) {
			unsigned int zone_id =
				zmd->sb[0].zone->id + zmd->nr_meta_zones;

			zmd->sb[1].zone = dmz_get(zmd, zone_id);
		}
		zmd->sb[1].block = dmz_start_block(zmd, zmd->sb[1].zone);
		zmd->sb[1].dev = zmd->sb[0].dev;
		ret = dmz_get_sb(zmd, &zmd->sb[1], 1);
	} else
		ret = dmz_lookup_secondary_sb(zmd);

	if (ret) {
		dmz_dev_err(zmd->sb[1].dev, "Read secondary super block failed");
		return ret;
	}

	ret = dmz_check_sb(zmd, &zmd->sb[1], false);
	if (ret == 0)
		sb_good[1] = true;

	/* Use highest generation sb first */
	if (!sb_good[0] && !sb_good[1]) {
		dmz_zmd_err(zmd, "No valid super block found");
		return -EIO;
	}

	if (sb_good[0])
		sb_gen[0] = le64_to_cpu(zmd->sb[0].sb->gen);
	else {
		ret = dmz_recover_mblocks(zmd, 0);
		if (ret) {
			dmz_dev_err(zmd->sb[0].dev,
				    "Recovery of superblock 0 failed");
			return -EIO;
		}
	}

	if (sb_good[1])
		sb_gen[1] = le64_to_cpu(zmd->sb[1].sb->gen);
	else {
		ret = dmz_recover_mblocks(zmd, 1);

		if (ret) {
			dmz_dev_err(zmd->sb[1].dev,
				    "Recovery of superblock 1 failed");
			return -EIO;
		}
	}

	if (sb_gen[0] >= sb_gen[1]) {
		zmd->sb_gen = sb_gen[0];
		zmd->mblk_primary = 0;
	} else {
		zmd->sb_gen = sb_gen[1];
		zmd->mblk_primary = 1;
	}

	dmz_dev_debug(zmd->sb[zmd->mblk_primary].dev,
		      "Using super block %u (gen %llu)",
		      zmd->mblk_primary, zmd->sb_gen);

	if (zmd->sb_version > 1) {
		int i;
		struct dmz_sb *sb;

		sb = kzalloc(sizeof(struct dmz_sb), GFP_KERNEL);
		if (!sb)
			return -ENOMEM;
		for (i = 1; i < zmd->nr_devs; i++) {
			sb->block = 0;
			sb->zone = dmz_get(zmd, zmd->dev[i].zone_offset);
			sb->dev = &zmd->dev[i];
			if (!dmz_is_meta(sb->zone)) {
				dmz_dev_err(sb->dev,
					    "Tertiary super block zone %u not marked as metadata zone",
					    sb->zone->id);
				ret = -EINVAL;
				goto out_kfree;
			}
			ret = dmz_get_sb(zmd, sb, i + 1);
			if (ret) {
				dmz_dev_err(sb->dev,
					    "Read tertiary super block failed");
				dmz_free_mblock(zmd, sb->mblk);
				goto out_kfree;
			}
			ret = dmz_check_sb(zmd, sb, true);
			dmz_free_mblock(zmd, sb->mblk);
			if (ret == -EINVAL)
				goto out_kfree;
		}
out_kfree:
		kfree(sb);
	}
	return ret;
}

/*
 * Initialize a zone descriptor.
 */
static int dmz_init_zone(struct blk_zone *blkz, unsigned int num, void *data)
{
	struct dmz_dev *dev = data;
	struct dmz_metadata *zmd = dev->metadata;
	int idx = num + dev->zone_offset;
	struct dm_zone *zone;

	zone = dmz_insert(zmd, idx, dev);
	if (IS_ERR(zone))
		return PTR_ERR(zone);

	if (blkz->len != zmd->zone_nr_sectors) {
		if (zmd->sb_version > 1) {
			/* Ignore the eventual runt (smaller) zone */
			set_bit(DMZ_OFFLINE, &zone->flags);
			return 0;
		} else if (blkz->start + blkz->len == dev->capacity)
			return 0;
		return -ENXIO;
	}

	/*
	 * Devices that have zones with a capacity smaller than the zone size
	 * (e.g. NVMe zoned namespaces) are not supported.
	 */
	if (blkz->capacity != blkz->len)
		return -ENXIO;

	switch (blkz->type) {
	case BLK_ZONE_TYPE_CONVENTIONAL:
		set_bit(DMZ_RND, &zone->flags);
		break;
	case BLK_ZONE_TYPE_SEQWRITE_REQ:
	case BLK_ZONE_TYPE_SEQWRITE_PREF:
		set_bit(DMZ_SEQ, &zone->flags);
		break;
	default:
		return -ENXIO;
	}

	if (dmz_is_rnd(zone))
		zone->wp_block = 0;
	else
		zone->wp_block = dmz_sect2blk(blkz->wp - blkz->start);

	if (blkz->cond == BLK_ZONE_COND_OFFLINE)
		set_bit(DMZ_OFFLINE, &zone->flags);
	else if (blkz->cond == BLK_ZONE_COND_READONLY)
		set_bit(DMZ_READ_ONLY, &zone->flags);
	else {
		zmd->nr_useable_zones++;
		if (dmz_is_rnd(zone)) {
			zmd->nr_rnd_zones++;
			if (zmd->nr_devs == 1 && !zmd->sb[0].zone) {
				/* Primary super block zone */
				zmd->sb[0].zone = zone;
			}
		}
		if (zmd->nr_devs > 1 && num == 0) {
			/*
			 * Tertiary superblock zones are always at the
			 * start of the zoned devices, so mark them
			 * as metadata zone.
			 */
			set_bit(DMZ_META, &zone->flags);
		}
	}
	return 0;
}

static int dmz_emulate_zones(struct dmz_metadata *zmd, struct dmz_dev *dev)
{
	int idx;
	sector_t zone_offset = 0;

	for (idx = 0; idx < dev->nr_zones; idx++) {
		struct dm_zone *zone;

		zone = dmz_insert(zmd, idx, dev);
		if (IS_ERR(zone))
			return PTR_ERR(zone);
		set_bit(DMZ_CACHE, &zone->flags);
		zone->wp_block = 0;
		zmd->nr_cache_zones++;
		zmd->nr_useable_zones++;
		if (dev->capacity - zone_offset < zmd->zone_nr_sectors) {
			/* Disable runt zone */
			set_bit(DMZ_OFFLINE, &zone->flags);
			break;
		}
		zone_offset += zmd->zone_nr_sectors;
	}
	return 0;
}

/*
 * Free zones descriptors.
 */
static void dmz_drop_zones(struct dmz_metadata *zmd)
{
	int idx;

	for (idx = 0; idx < zmd->nr_zones; idx++) {
		struct dm_zone *zone = xa_load(&zmd->zones, idx);

		kfree(zone);
		xa_erase(&zmd->zones, idx);
	}
	xa_destroy(&zmd->zones);
}

/*
 * Allocate and initialize zone descriptors using the zone
 * information from disk.
 */
static int dmz_init_zones(struct dmz_metadata *zmd)
{
	int i, ret;
	struct dmz_dev *zoned_dev = &zmd->dev[0];

	/* Init */
	zmd->zone_nr_sectors = zmd->dev[0].zone_nr_sectors;
	zmd->zone_nr_sectors_shift = ilog2(zmd->zone_nr_sectors);
	zmd->zone_nr_blocks = dmz_sect2blk(zmd->zone_nr_sectors);
	zmd->zone_nr_blocks_shift = ilog2(zmd->zone_nr_blocks);
	zmd->zone_bitmap_size = zmd->zone_nr_blocks >> 3;
	zmd->zone_nr_bitmap_blocks =
		max_t(sector_t, 1, zmd->zone_bitmap_size >> DMZ_BLOCK_SHIFT);
	zmd->zone_bits_per_mblk = min_t(sector_t, zmd->zone_nr_blocks,
					DMZ_BLOCK_SIZE_BITS);

	/* Allocate zone array */
	zmd->nr_zones = 0;
	for (i = 0; i < zmd->nr_devs; i++) {
		struct dmz_dev *dev = &zmd->dev[i];

		dev->metadata = zmd;
		zmd->nr_zones += dev->nr_zones;

		atomic_set(&dev->unmap_nr_rnd, 0);
		INIT_LIST_HEAD(&dev->unmap_rnd_list);
		INIT_LIST_HEAD(&dev->map_rnd_list);

		atomic_set(&dev->unmap_nr_seq, 0);
		INIT_LIST_HEAD(&dev->unmap_seq_list);
		INIT_LIST_HEAD(&dev->map_seq_list);
	}

	if (!zmd->nr_zones) {
		DMERR("(%s): No zones found", zmd->devname);
		return -ENXIO;
	}
	xa_init(&zmd->zones);

	DMDEBUG("(%s): Using %zu B for zone information",
		zmd->devname, sizeof(struct dm_zone) * zmd->nr_zones);

	if (zmd->nr_devs > 1) {
		ret = dmz_emulate_zones(zmd, &zmd->dev[0]);
		if (ret < 0) {
			DMDEBUG("(%s): Failed to emulate zones, error %d",
				zmd->devname, ret);
			dmz_drop_zones(zmd);
			return ret;
		}

		/*
		 * Primary superblock zone is always at zone 0 when multiple
		 * drives are present.
		 */
		zmd->sb[0].zone = dmz_get(zmd, 0);

		for (i = 1; i < zmd->nr_devs; i++) {
			zoned_dev = &zmd->dev[i];

			ret = blkdev_report_zones(zoned_dev->bdev, 0,
						  BLK_ALL_ZONES,
						  dmz_init_zone, zoned_dev);
			if (ret < 0) {
				DMDEBUG("(%s): Failed to report zones, error %d",
					zmd->devname, ret);
				dmz_drop_zones(zmd);
				return ret;
			}
		}
		return 0;
	}

	/*
	 * Get zone information and initialize zone descriptors.  At the same
	 * time, determine where the super block should be: first block of the
	 * first randomly writable zone.
	 */
	ret = blkdev_report_zones(zoned_dev->bdev, 0, BLK_ALL_ZONES,
				  dmz_init_zone, zoned_dev);
	if (ret < 0) {
		DMDEBUG("(%s): Failed to report zones, error %d",
			zmd->devname, ret);
		dmz_drop_zones(zmd);
		return ret;
	}

	return 0;
}

static int dmz_update_zone_cb(struct blk_zone *blkz, unsigned int idx,
			      void *data)
{
	struct dm_zone *zone = data;

	clear_bit(DMZ_OFFLINE, &zone->flags);
	clear_bit(DMZ_READ_ONLY, &zone->flags);
	if (blkz->cond == BLK_ZONE_COND_OFFLINE)
		set_bit(DMZ_OFFLINE, &zone->flags);
	else if (blkz->cond == BLK_ZONE_COND_READONLY)
		set_bit(DMZ_READ_ONLY, &zone->flags);

	if (dmz_is_seq(zone))
		zone->wp_block = dmz_sect2blk(blkz->wp - blkz->start);
	else
		zone->wp_block = 0;
	return 0;
}

/*
 * Update a zone information.
 */
static int dmz_update_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	struct dmz_dev *dev = zone->dev;
	unsigned int noio_flag;
	int ret;

	if (dev->flags & DMZ_BDEV_REGULAR)
		return 0;

	/*
	 * Get zone information from disk. Since blkdev_report_zones() uses
	 * GFP_KERNEL by default for memory allocations, set the per-task
	 * PF_MEMALLOC_NOIO flag so that all allocations are done as if
	 * GFP_NOIO was specified.
	 */
	noio_flag = memalloc_noio_save();
	ret = blkdev_report_zones(dev->bdev, dmz_start_sect(zmd, zone), 1,
				  dmz_update_zone_cb, zone);
	memalloc_noio_restore(noio_flag);

	if (ret == 0)
		ret = -EIO;
	if (ret < 0) {
		dmz_dev_err(dev, "Get zone %u report failed",
			    zone->id);
		dmz_check_bdev(dev);
		return ret;
	}

	return 0;
}

/*
 * Check a zone write pointer position when the zone is marked
 * with the sequential write error flag.
 */
static int dmz_handle_seq_write_err(struct dmz_metadata *zmd,
				    struct dm_zone *zone)
{
	struct dmz_dev *dev = zone->dev;
	unsigned int wp = 0;
	int ret;

	wp = zone->wp_block;
	ret = dmz_update_zone(zmd, zone);
	if (ret)
		return ret;

	dmz_dev_warn(dev, "Processing zone %u write error (zone wp %u/%u)",
		     zone->id, zone->wp_block, wp);

	if (zone->wp_block < wp) {
		dmz_invalidate_blocks(zmd, zone, zone->wp_block,
				      wp - zone->wp_block);
	}

	return 0;
}

/*
 * Reset a zone write pointer.
 */
static int dmz_reset_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	int ret;

	/*
	 * Ignore offline zones, read only zones,
	 * and conventional zones.
	 */
	if (dmz_is_offline(zone) ||
	    dmz_is_readonly(zone) ||
	    dmz_is_rnd(zone))
		return 0;

	if (!dmz_is_empty(zone) || dmz_seq_write_err(zone)) {
		struct dmz_dev *dev = zone->dev;
		unsigned int noio_flag;

		noio_flag = memalloc_noio_save();
		ret = blkdev_zone_mgmt(dev->bdev, REQ_OP_ZONE_RESET,
				       dmz_start_sect(zmd, zone),
				       zmd->zone_nr_sectors);
		memalloc_noio_restore(noio_flag);
		if (ret) {
			dmz_dev_err(dev, "Reset zone %u failed %d",
				    zone->id, ret);
			return ret;
		}
	}

	/* Clear write error bit and rewind write pointer position */
	clear_bit(DMZ_SEQ_WRITE_ERR, &zone->flags);
	zone->wp_block = 0;

	return 0;
}

static void dmz_get_zone_weight(struct dmz_metadata *zmd, struct dm_zone *zone);

/*
 * Initialize chunk mapping.
 */
static int dmz_load_mapping(struct dmz_metadata *zmd)
{
	struct dm_zone *dzone, *bzone;
	struct dmz_mblock *dmap_mblk = NULL;
	struct dmz_map *dmap;
	unsigned int i = 0, e = 0, chunk = 0;
	unsigned int dzone_id;
	unsigned int bzone_id;

	/* Metadata block array for the chunk mapping table */
	zmd->map_mblk = kcalloc(zmd->nr_map_blocks,
				sizeof(struct dmz_mblk *), GFP_KERNEL);
	if (!zmd->map_mblk)
		return -ENOMEM;

	/* Get chunk mapping table blocks and initialize zone mapping */
	while (chunk < zmd->nr_chunks) {
		if (!dmap_mblk) {
			/* Get mapping block */
			dmap_mblk = dmz_get_mblock(zmd, i + 1);
			if (IS_ERR(dmap_mblk))
				return PTR_ERR(dmap_mblk);
			zmd->map_mblk[i] = dmap_mblk;
			dmap = dmap_mblk->data;
			i++;
			e = 0;
		}

		/* Check data zone */
		dzone_id = le32_to_cpu(dmap[e].dzone_id);
		if (dzone_id == DMZ_MAP_UNMAPPED)
			goto next;

		if (dzone_id >= zmd->nr_zones) {
			dmz_zmd_err(zmd, "Chunk %u mapping: invalid data zone ID %u",
				    chunk, dzone_id);
			return -EIO;
		}

		dzone = dmz_get(zmd, dzone_id);
		if (!dzone) {
			dmz_zmd_err(zmd, "Chunk %u mapping: data zone %u not present",
				    chunk, dzone_id);
			return -EIO;
		}
		set_bit(DMZ_DATA, &dzone->flags);
		dzone->chunk = chunk;
		dmz_get_zone_weight(zmd, dzone);

		if (dmz_is_cache(dzone))
			list_add_tail(&dzone->link, &zmd->map_cache_list);
		else if (dmz_is_rnd(dzone))
			list_add_tail(&dzone->link, &dzone->dev->map_rnd_list);
		else
			list_add_tail(&dzone->link, &dzone->dev->map_seq_list);

		/* Check buffer zone */
		bzone_id = le32_to_cpu(dmap[e].bzone_id);
		if (bzone_id == DMZ_MAP_UNMAPPED)
			goto next;

		if (bzone_id >= zmd->nr_zones) {
			dmz_zmd_err(zmd, "Chunk %u mapping: invalid buffer zone ID %u",
				    chunk, bzone_id);
			return -EIO;
		}

		bzone = dmz_get(zmd, bzone_id);
		if (!bzone) {
			dmz_zmd_err(zmd, "Chunk %u mapping: buffer zone %u not present",
				    chunk, bzone_id);
			return -EIO;
		}
		if (!dmz_is_rnd(bzone) && !dmz_is_cache(bzone)) {
			dmz_zmd_err(zmd, "Chunk %u mapping: invalid buffer zone %u",
				    chunk, bzone_id);
			return -EIO;
		}

		set_bit(DMZ_DATA, &bzone->flags);
		set_bit(DMZ_BUF, &bzone->flags);
		bzone->chunk = chunk;
		bzone->bzone = dzone;
		dzone->bzone = bzone;
		dmz_get_zone_weight(zmd, bzone);
		if (dmz_is_cache(bzone))
			list_add_tail(&bzone->link, &zmd->map_cache_list);
		else
			list_add_tail(&bzone->link, &bzone->dev->map_rnd_list);
next:
		chunk++;
		e++;
		if (e >= DMZ_MAP_ENTRIES)
			dmap_mblk = NULL;
	}

	/*
	 * At this point, only meta zones and mapped data zones were
	 * fully initialized. All remaining zones are unmapped data
	 * zones. Finish initializing those here.
	 */
	for (i = 0; i < zmd->nr_zones; i++) {
		dzone = dmz_get(zmd, i);
		if (!dzone)
			continue;
		if (dmz_is_meta(dzone))
			continue;
		if (dmz_is_offline(dzone))
			continue;

		if (dmz_is_cache(dzone))
			zmd->nr_cache++;
		else if (dmz_is_rnd(dzone))
			dzone->dev->nr_rnd++;
		else
			dzone->dev->nr_seq++;

		if (dmz_is_data(dzone)) {
			/* Already initialized */
			continue;
		}

		/* Unmapped data zone */
		set_bit(DMZ_DATA, &dzone->flags);
		dzone->chunk = DMZ_MAP_UNMAPPED;
		if (dmz_is_cache(dzone)) {
			list_add_tail(&dzone->link, &zmd->unmap_cache_list);
			atomic_inc(&zmd->unmap_nr_cache);
		} else if (dmz_is_rnd(dzone)) {
			list_add_tail(&dzone->link,
				      &dzone->dev->unmap_rnd_list);
			atomic_inc(&dzone->dev->unmap_nr_rnd);
		} else if (atomic_read(&zmd->nr_reserved_seq_zones) < zmd->nr_reserved_seq) {
			list_add_tail(&dzone->link, &zmd->reserved_seq_zones_list);
			set_bit(DMZ_RESERVED, &dzone->flags);
			atomic_inc(&zmd->nr_reserved_seq_zones);
			dzone->dev->nr_seq--;
		} else {
			list_add_tail(&dzone->link,
				      &dzone->dev->unmap_seq_list);
			atomic_inc(&dzone->dev->unmap_nr_seq);
		}
	}

	return 0;
}

/*
 * Set a data chunk mapping.
 */
static void dmz_set_chunk_mapping(struct dmz_metadata *zmd, unsigned int chunk,
				  unsigned int dzone_id, unsigned int bzone_id)
{
	struct dmz_mblock *dmap_mblk = zmd->map_mblk[chunk >> DMZ_MAP_ENTRIES_SHIFT];
	struct dmz_map *dmap = dmap_mblk->data;
	int map_idx = chunk & DMZ_MAP_ENTRIES_MASK;

	dmap[map_idx].dzone_id = cpu_to_le32(dzone_id);
	dmap[map_idx].bzone_id = cpu_to_le32(bzone_id);
	dmz_dirty_mblock(zmd, dmap_mblk);
}

/*
 * The list of mapped zones is maintained in LRU order.
 * This rotates a zone at the end of its map list.
 */
static void __dmz_lru_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	if (list_empty(&zone->link))
		return;

	list_del_init(&zone->link);
	if (dmz_is_seq(zone)) {
		/* LRU rotate sequential zone */
		list_add_tail(&zone->link, &zone->dev->map_seq_list);
	} else if (dmz_is_cache(zone)) {
		/* LRU rotate cache zone */
		list_add_tail(&zone->link, &zmd->map_cache_list);
	} else {
		/* LRU rotate random zone */
		list_add_tail(&zone->link, &zone->dev->map_rnd_list);
	}
}

/*
 * The list of mapped random zones is maintained
 * in LRU order. This rotates a zone at the end of the list.
 */
static void dmz_lru_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	__dmz_lru_zone(zmd, zone);
	if (zone->bzone)
		__dmz_lru_zone(zmd, zone->bzone);
}

/*
 * Wait for any zone to be freed.
 */
static void dmz_wait_for_free_zones(struct dmz_metadata *zmd)
{
	DEFINE_WAIT(wait);

	prepare_to_wait(&zmd->free_wq, &wait, TASK_UNINTERRUPTIBLE);
	dmz_unlock_map(zmd);
	dmz_unlock_metadata(zmd);

	io_schedule_timeout(HZ);

	dmz_lock_metadata(zmd);
	dmz_lock_map(zmd);
	finish_wait(&zmd->free_wq, &wait);
}

/*
 * Lock a zone for reclaim (set the zone RECLAIM bit).
 * Returns false if the zone cannot be locked or if it is already locked
 * and 1 otherwise.
 */
int dmz_lock_zone_reclaim(struct dm_zone *zone)
{
	/* Active zones cannot be reclaimed */
	if (dmz_is_active(zone))
		return 0;

	return !test_and_set_bit(DMZ_RECLAIM, &zone->flags);
}

/*
 * Clear a zone reclaim flag.
 */
void dmz_unlock_zone_reclaim(struct dm_zone *zone)
{
	WARN_ON(dmz_is_active(zone));
	WARN_ON(!dmz_in_reclaim(zone));

	clear_bit_unlock(DMZ_RECLAIM, &zone->flags);
	smp_mb__after_atomic();
	wake_up_bit(&zone->flags, DMZ_RECLAIM);
}

/*
 * Wait for a zone reclaim to complete.
 */
static void dmz_wait_for_reclaim(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	dmz_unlock_map(zmd);
	dmz_unlock_metadata(zmd);
	set_bit(DMZ_RECLAIM_TERMINATE, &zone->flags);
	wait_on_bit_timeout(&zone->flags, DMZ_RECLAIM, TASK_UNINTERRUPTIBLE, HZ);
	clear_bit(DMZ_RECLAIM_TERMINATE, &zone->flags);
	dmz_lock_metadata(zmd);
	dmz_lock_map(zmd);
}

/*
 * Select a cache or random write zone for reclaim.
 */
static struct dm_zone *dmz_get_rnd_zone_for_reclaim(struct dmz_metadata *zmd,
						    unsigned int idx, bool idle)
{
	struct dm_zone *dzone = NULL;
	struct dm_zone *zone, *maxw_z = NULL;
	struct list_head *zone_list;

	/* If we have cache zones select from the cache zone list */
	if (zmd->nr_cache) {
		zone_list = &zmd->map_cache_list;
		/* Try to relaim random zones, too, when idle */
		if (idle && list_empty(zone_list))
			zone_list = &zmd->dev[idx].map_rnd_list;
	} else
		zone_list = &zmd->dev[idx].map_rnd_list;

	/*
	 * Find the buffer zone with the heaviest weight or the first (oldest)
	 * data zone that can be reclaimed.
	 */
	list_for_each_entry(zone, zone_list, link) {
		if (dmz_is_buf(zone)) {
			dzone = zone->bzone;
			if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx)
				continue;
			if (!maxw_z || maxw_z->weight < dzone->weight)
				maxw_z = dzone;
		} else {
			dzone = zone;
			if (dmz_lock_zone_reclaim(dzone))
				return dzone;
		}
	}

	if (maxw_z && dmz_lock_zone_reclaim(maxw_z))
		return maxw_z;

	/*
	 * If we come here, none of the zones inspected could be locked for
	 * reclaim. Try again, being more aggressive, that is, find the
	 * first zone that can be reclaimed regardless of its weitght.
	 */
	list_for_each_entry(zone, zone_list, link) {
		if (dmz_is_buf(zone)) {
			dzone = zone->bzone;
			if (dmz_is_rnd(dzone) && dzone->dev->dev_idx != idx)
				continue;
		} else
			dzone = zone;
		if (dmz_lock_zone_reclaim(dzone))
			return dzone;
	}

	return NULL;
}

/*
 * Select a buffered sequential zone for reclaim.
 */
static struct dm_zone *dmz_get_seq_zone_for_reclaim(struct dmz_metadata *zmd,
						    unsigned int idx)
{
	struct dm_zone *zone;

	list_for_each_entry(zone, &zmd->dev[idx].map_seq_list, link) {
		if (!zone->bzone)
			continue;
		if (dmz_lock_zone_reclaim(zone))
			return zone;
	}

	return NULL;
}

/*
 * Select a zone for reclaim.
 */
struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd,
					 unsigned int dev_idx, bool idle)
{
	struct dm_zone *zone = NULL;

	/*
	 * Search for a zone candidate to reclaim: 2 cases are possible.
	 * (1) There is no free sequential zones. Then a random data zone
	 *     cannot be reclaimed. So choose a sequential zone to reclaim so
	 *     that afterward a random zone can be reclaimed.
	 * (2) At least one free sequential zone is available, then choose
	 *     the oldest random zone (data or buffer) that can be locked.
	 */
	dmz_lock_map(zmd);
	if (list_empty(&zmd->reserved_seq_zones_list))
		zone = dmz_get_seq_zone_for_reclaim(zmd, dev_idx);
	if (!zone)
		zone = dmz_get_rnd_zone_for_reclaim(zmd, dev_idx, idle);
	dmz_unlock_map(zmd);

	return zone;
}

/*
 * Get the zone mapping a chunk, if the chunk is mapped already.
 * If no mapping exist and the operation is WRITE, a zone is
 * allocated and used to map the chunk.
 * The zone returned will be set to the active state.
 */
struct dm_zone *dmz_get_chunk_mapping(struct dmz_metadata *zmd,
				      unsigned int chunk, enum req_op op)
{
	struct dmz_mblock *dmap_mblk = zmd->map_mblk[chunk >> DMZ_MAP_ENTRIES_SHIFT];
	struct dmz_map *dmap = dmap_mblk->data;
	int dmap_idx = chunk & DMZ_MAP_ENTRIES_MASK;
	unsigned int dzone_id;
	struct dm_zone *dzone = NULL;
	int ret = 0;
	int alloc_flags = zmd->nr_cache ? DMZ_ALLOC_CACHE : DMZ_ALLOC_RND;

	dmz_lock_map(zmd);
again:
	/* Get the chunk mapping */
	dzone_id = le32_to_cpu(dmap[dmap_idx].dzone_id);
	if (dzone_id == DMZ_MAP_UNMAPPED) {
		/*
		 * Read or discard in unmapped chunks are fine. But for
		 * writes, we need a mapping, so get one.
		 */
		if (op != REQ_OP_WRITE)
			goto out;

		/* Allocate a random zone */
		dzone = dmz_alloc_zone(zmd, 0, alloc_flags);
		if (!dzone) {
			if (dmz_dev_is_dying(zmd)) {
				dzone = ERR_PTR(-EIO);
				goto out;
			}
			dmz_wait_for_free_zones(zmd);
			goto again;
		}

		dmz_map_zone(zmd, dzone, chunk);

	} else {
		/* The chunk is already mapped: get the mapping zone */
		dzone = dmz_get(zmd, dzone_id);
		if (!dzone) {
			dzone = ERR_PTR(-EIO);
			goto out;
		}
		if (dzone->chunk != chunk) {
			dzone = ERR_PTR(-EIO);
			goto out;
		}

		/* Repair write pointer if the sequential dzone has error */
		if (dmz_seq_write_err(dzone)) {
			ret = dmz_handle_seq_write_err(zmd, dzone);
			if (ret) {
				dzone = ERR_PTR(-EIO);
				goto out;
			}
			clear_bit(DMZ_SEQ_WRITE_ERR, &dzone->flags);
		}
	}

	/*
	 * If the zone is being reclaimed, the chunk mapping may change
	 * to a different zone. So wait for reclaim and retry. Otherwise,
	 * activate the zone (this will prevent reclaim from touching it).
	 */
	if (dmz_in_reclaim(dzone)) {
		dmz_wait_for_reclaim(zmd, dzone);
		goto again;
	}
	dmz_activate_zone(dzone);
	dmz_lru_zone(zmd, dzone);
out:
	dmz_unlock_map(zmd);

	return dzone;
}

/*
 * Write and discard change the block validity of data zones and their buffer
 * zones. Check here that valid blocks are still present. If all blocks are
 * invalid, the zones can be unmapped on the fly without waiting for reclaim
 * to do it.
 */
void dmz_put_chunk_mapping(struct dmz_metadata *zmd, struct dm_zone *dzone)
{
	struct dm_zone *bzone;

	dmz_lock_map(zmd);

	bzone = dzone->bzone;
	if (bzone) {
		if (dmz_weight(bzone))
			dmz_lru_zone(zmd, bzone);
		else {
			/* Empty buffer zone: reclaim it */
			dmz_unmap_zone(zmd, bzone);
			dmz_free_zone(zmd, bzone);
			bzone = NULL;
		}
	}

	/* Deactivate the data zone */
	dmz_deactivate_zone(dzone);
	if (dmz_is_active(dzone) || bzone || dmz_weight(dzone))
		dmz_lru_zone(zmd, dzone);
	else {
		/* Unbuffered inactive empty data zone: reclaim it */
		dmz_unmap_zone(zmd, dzone);
		dmz_free_zone(zmd, dzone);
	}

	dmz_unlock_map(zmd);
}

/*
 * Allocate and map a random zone to buffer a chunk
 * already mapped to a sequential zone.
 */
struct dm_zone *dmz_get_chunk_buffer(struct dmz_metadata *zmd,
				     struct dm_zone *dzone)
{
	struct dm_zone *bzone;
	int alloc_flags = zmd->nr_cache ? DMZ_ALLOC_CACHE : DMZ_ALLOC_RND;

	dmz_lock_map(zmd);
again:
	bzone = dzone->bzone;
	if (bzone)
		goto out;

	/* Allocate a random zone */
	bzone = dmz_alloc_zone(zmd, 0, alloc_flags);
	if (!bzone) {
		if (dmz_dev_is_dying(zmd)) {
			bzone = ERR_PTR(-EIO);
			goto out;
		}
		dmz_wait_for_free_zones(zmd);
		goto again;
	}

	/* Update the chunk mapping */
	dmz_set_chunk_mapping(zmd, dzone->chunk, dzone->id, bzone->id);

	set_bit(DMZ_BUF, &bzone->flags);
	bzone->chunk = dzone->chunk;
	bzone->bzone = dzone;
	dzone->bzone = bzone;
	if (dmz_is_cache(bzone))
		list_add_tail(&bzone->link, &zmd->map_cache_list);
	else
		list_add_tail(&bzone->link, &bzone->dev->map_rnd_list);
out:
	dmz_unlock_map(zmd);

	return bzone;
}

/*
 * Get an unmapped (free) zone.
 * This must be called with the mapping lock held.
 */
struct dm_zone *dmz_alloc_zone(struct dmz_metadata *zmd, unsigned int dev_idx,
			       unsigned long flags)
{
	struct list_head *list;
	struct dm_zone *zone;
	int i;

	/* Schedule reclaim to ensure free zones are available */
	if (!(flags & DMZ_ALLOC_RECLAIM)) {
		for (i = 0; i < zmd->nr_devs; i++)
			dmz_schedule_reclaim(zmd->dev[i].reclaim);
	}

	i = 0;
again:
	if (flags & DMZ_ALLOC_CACHE)
		list = &zmd->unmap_cache_list;
	else if (flags & DMZ_ALLOC_RND)
		list = &zmd->dev[dev_idx].unmap_rnd_list;
	else
		list = &zmd->dev[dev_idx].unmap_seq_list;

	if (list_empty(list)) {
		/*
		 * No free zone: return NULL if this is for not reclaim.
		 */
		if (!(flags & DMZ_ALLOC_RECLAIM))
			return NULL;
		/*
		 * Try to allocate from other devices
		 */
		if (i < zmd->nr_devs) {
			dev_idx = (dev_idx + 1) % zmd->nr_devs;
			i++;
			goto again;
		}

		/*
		 * Fallback to the reserved sequential zones
		 */
		zone = list_first_entry_or_null(&zmd->reserved_seq_zones_list,
						struct dm_zone, link);
		if (zone) {
			list_del_init(&zone->link);
			atomic_dec(&zmd->nr_reserved_seq_zones);
		}
		return zone;
	}

	zone = list_first_entry(list, struct dm_zone, link);
	list_del_init(&zone->link);

	if (dmz_is_cache(zone))
		atomic_dec(&zmd->unmap_nr_cache);
	else if (dmz_is_rnd(zone))
		atomic_dec(&zone->dev->unmap_nr_rnd);
	else
		atomic_dec(&zone->dev->unmap_nr_seq);

	if (dmz_is_offline(zone)) {
		dmz_zmd_warn(zmd, "Zone %u is offline", zone->id);
		zone = NULL;
		goto again;
	}
	if (dmz_is_meta(zone)) {
		dmz_zmd_warn(zmd, "Zone %u has metadata", zone->id);
		zone = NULL;
		goto again;
	}
	return zone;
}

/*
 * Free a zone.
 * This must be called with the mapping lock held.
 */
void dmz_free_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	/* If this is a sequential zone, reset it */
	if (dmz_is_seq(zone))
		dmz_reset_zone(zmd, zone);

	/* Return the zone to its type unmap list */
	if (dmz_is_cache(zone)) {
		list_add_tail(&zone->link, &zmd->unmap_cache_list);
		atomic_inc(&zmd->unmap_nr_cache);
	} else if (dmz_is_rnd(zone)) {
		list_add_tail(&zone->link, &zone->dev->unmap_rnd_list);
		atomic_inc(&zone->dev->unmap_nr_rnd);
	} else if (dmz_is_reserved(zone)) {
		list_add_tail(&zone->link, &zmd->reserved_seq_zones_list);
		atomic_inc(&zmd->nr_reserved_seq_zones);
	} else {
		list_add_tail(&zone->link, &zone->dev->unmap_seq_list);
		atomic_inc(&zone->dev->unmap_nr_seq);
	}

	wake_up_all(&zmd->free_wq);
}

/*
 * Map a chunk to a zone.
 * This must be called with the mapping lock held.
 */
void dmz_map_zone(struct dmz_metadata *zmd, struct dm_zone *dzone,
		  unsigned int chunk)
{
	/* Set the chunk mapping */
	dmz_set_chunk_mapping(zmd, chunk, dzone->id,
			      DMZ_MAP_UNMAPPED);
	dzone->chunk = chunk;
	if (dmz_is_cache(dzone))
		list_add_tail(&dzone->link, &zmd->map_cache_list);
	else if (dmz_is_rnd(dzone))
		list_add_tail(&dzone->link, &dzone->dev->map_rnd_list);
	else
		list_add_tail(&dzone->link, &dzone->dev->map_seq_list);
}

/*
 * Unmap a zone.
 * This must be called with the mapping lock held.
 */
void dmz_unmap_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	unsigned int chunk = zone->chunk;
	unsigned int dzone_id;

	if (chunk == DMZ_MAP_UNMAPPED) {
		/* Already unmapped */
		return;
	}

	if (test_and_clear_bit(DMZ_BUF, &zone->flags)) {
		/*
		 * Unmapping the chunk buffer zone: clear only
		 * the chunk buffer mapping
		 */
		dzone_id = zone->bzone->id;
		zone->bzone->bzone = NULL;
		zone->bzone = NULL;

	} else {
		/*
		 * Unmapping the chunk data zone: the zone must
		 * not be buffered.
		 */
		if (WARN_ON(zone->bzone)) {
			zone->bzone->bzone = NULL;
			zone->bzone = NULL;
		}
		dzone_id = DMZ_MAP_UNMAPPED;
	}

	dmz_set_chunk_mapping(zmd, chunk, dzone_id, DMZ_MAP_UNMAPPED);

	zone->chunk = DMZ_MAP_UNMAPPED;
	list_del_init(&zone->link);
}

/*
 * Set @nr_bits bits in @bitmap starting from @bit.
 * Return the number of bits changed from 0 to 1.
 */
static unsigned int dmz_set_bits(unsigned long *bitmap,
				 unsigned int bit, unsigned int nr_bits)
{
	unsigned long *addr;
	unsigned int end = bit + nr_bits;
	unsigned int n = 0;

	while (bit < end) {
		if (((bit & (BITS_PER_LONG - 1)) == 0) &&
		    ((end - bit) >= BITS_PER_LONG)) {
			/* Try to set the whole word at once */
			addr = bitmap + BIT_WORD(bit);
			if (*addr == 0) {
				*addr = ULONG_MAX;
				n += BITS_PER_LONG;
				bit += BITS_PER_LONG;
				continue;
			}
		}

		if (!test_and_set_bit(bit, bitmap))
			n++;
		bit++;
	}

	return n;
}

/*
 * Get the bitmap block storing the bit for chunk_block in zone.
 */
static struct dmz_mblock *dmz_get_bitmap(struct dmz_metadata *zmd,
					 struct dm_zone *zone,
					 sector_t chunk_block)
{
	sector_t bitmap_block = 1 + zmd->nr_map_blocks +
		(sector_t)(zone->id * zmd->zone_nr_bitmap_blocks) +
		(chunk_block >> DMZ_BLOCK_SHIFT_BITS);

	return dmz_get_mblock(zmd, bitmap_block);
}

/*
 * Copy the valid blocks bitmap of from_zone to the bitmap of to_zone.
 */
int dmz_copy_valid_blocks(struct dmz_metadata *zmd, struct dm_zone *from_zone,
			  struct dm_zone *to_zone)
{
	struct dmz_mblock *from_mblk, *to_mblk;
	sector_t chunk_block = 0;

	/* Get the zones bitmap blocks */
	while (chunk_block < zmd->zone_nr_blocks) {
		from_mblk = dmz_get_bitmap(zmd, from_zone, chunk_block);
		if (IS_ERR(from_mblk))
			return PTR_ERR(from_mblk);
		to_mblk = dmz_get_bitmap(zmd, to_zone, chunk_block);
		if (IS_ERR(to_mblk)) {
			dmz_release_mblock(zmd, from_mblk);
			return PTR_ERR(to_mblk);
		}

		memcpy(to_mblk->data, from_mblk->data, DMZ_BLOCK_SIZE);
		dmz_dirty_mblock(zmd, to_mblk);

		dmz_release_mblock(zmd, to_mblk);
		dmz_release_mblock(zmd, from_mblk);

		chunk_block += zmd->zone_bits_per_mblk;
	}

	to_zone->weight = from_zone->weight;

	return 0;
}

/*
 * Merge the valid blocks bitmap of from_zone into the bitmap of to_zone,
 * starting from chunk_block.
 */
int dmz_merge_valid_blocks(struct dmz_metadata *zmd, struct dm_zone *from_zone,
			   struct dm_zone *to_zone, sector_t chunk_block)
{
	unsigned int nr_blocks;
	int ret;

	/* Get the zones bitmap blocks */
	while (chunk_block < zmd->zone_nr_blocks) {
		/* Get a valid region from the source zone */
		ret = dmz_first_valid_block(zmd, from_zone, &chunk_block);
		if (ret <= 0)
			return ret;

		nr_blocks = ret;
		ret = dmz_validate_blocks(zmd, to_zone, chunk_block, nr_blocks);
		if (ret)
			return ret;

		chunk_block += nr_blocks;
	}

	return 0;
}

/*
 * Validate all the blocks in the range [block..block+nr_blocks-1].
 */
int dmz_validate_blocks(struct dmz_metadata *zmd, struct dm_zone *zone,
			sector_t chunk_block, unsigned int nr_blocks)
{
	unsigned int count, bit, nr_bits;
	unsigned int zone_nr_blocks = zmd->zone_nr_blocks;
	struct dmz_mblock *mblk;
	unsigned int n = 0;

	dmz_zmd_debug(zmd, "=> VALIDATE zone %u, block %llu, %u blocks",
		      zone->id, (unsigned long long)chunk_block,
		      nr_blocks);

	WARN_ON(chunk_block + nr_blocks > zone_nr_blocks);

	while (nr_blocks) {
		/* Get bitmap block */
		mblk = dmz_get_bitmap(zmd, zone, chunk_block);
		if (IS_ERR(mblk))
			return PTR_ERR(mblk);

		/* Set bits */
		bit = chunk_block & DMZ_BLOCK_MASK_BITS;
		nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit);

		count = dmz_set_bits((unsigned long *)mblk->data, bit, nr_bits);
		if (count) {
			dmz_dirty_mblock(zmd, mblk);
			n += count;
		}
		dmz_release_mblock(zmd, mblk);

		nr_blocks -= nr_bits;
		chunk_block += nr_bits;
	}

	if (likely(zone->weight + n <= zone_nr_blocks))
		zone->weight += n;
	else {
		dmz_zmd_warn(zmd, "Zone %u: weight %u should be <= %u",
			     zone->id, zone->weight,
			     zone_nr_blocks - n);
		zone->weight = zone_nr_blocks;
	}

	return 0;
}

/*
 * Clear nr_bits bits in bitmap starting from bit.
 * Return the number of bits cleared.
 */
static int dmz_clear_bits(unsigned long *bitmap, int bit, int nr_bits)
{
	unsigned long *addr;
	int end = bit + nr_bits;
	int n = 0;

	while (bit < end) {
		if (((bit & (BITS_PER_LONG - 1)) == 0) &&
		    ((end - bit) >= BITS_PER_LONG)) {
			/* Try to clear whole word at once */
			addr = bitmap + BIT_WORD(bit);
			if (*addr == ULONG_MAX) {
				*addr = 0;
				n += BITS_PER_LONG;
				bit += BITS_PER_LONG;
				continue;
			}
		}

		if (test_and_clear_bit(bit, bitmap))
			n++;
		bit++;
	}

	return n;
}

/*
 * Invalidate all the blocks in the range [block..block+nr_blocks-1].
 */
int dmz_invalidate_blocks(struct dmz_metadata *zmd, struct dm_zone *zone,
			  sector_t chunk_block, unsigned int nr_blocks)
{
	unsigned int count, bit, nr_bits;
	struct dmz_mblock *mblk;
	unsigned int n = 0;

	dmz_zmd_debug(zmd, "=> INVALIDATE zone %u, block %llu, %u blocks",
		      zone->id, (u64)chunk_block, nr_blocks);

	WARN_ON(chunk_block + nr_blocks > zmd->zone_nr_blocks);

	while (nr_blocks) {
		/* Get bitmap block */
		mblk = dmz_get_bitmap(zmd, zone, chunk_block);
		if (IS_ERR(mblk))
			return PTR_ERR(mblk);

		/* Clear bits */
		bit = chunk_block & DMZ_BLOCK_MASK_BITS;
		nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit);

		count = dmz_clear_bits((unsigned long *)mblk->data,
				       bit, nr_bits);
		if (count) {
			dmz_dirty_mblock(zmd, mblk);
			n += count;
		}
		dmz_release_mblock(zmd, mblk);

		nr_blocks -= nr_bits;
		chunk_block += nr_bits;
	}

	if (zone->weight >= n)
		zone->weight -= n;
	else {
		dmz_zmd_warn(zmd, "Zone %u: weight %u should be >= %u",
			     zone->id, zone->weight, n);
		zone->weight = 0;
	}

	return 0;
}

/*
 * Get a block bit value.
 */
static int dmz_test_block(struct dmz_metadata *zmd, struct dm_zone *zone,
			  sector_t chunk_block)
{
	struct dmz_mblock *mblk;
	int ret;

	WARN_ON(chunk_block >= zmd->zone_nr_blocks);

	/* Get bitmap block */
	mblk = dmz_get_bitmap(zmd, zone, chunk_block);
	if (IS_ERR(mblk))
		return PTR_ERR(mblk);

	/* Get offset */
	ret = test_bit(chunk_block & DMZ_BLOCK_MASK_BITS,
		       (unsigned long *) mblk->data) != 0;

	dmz_release_mblock(zmd, mblk);

	return ret;
}

/*
 * Return the number of blocks from chunk_block to the first block with a bit
 * value specified by set. Search at most nr_blocks blocks from chunk_block.
 */
static int dmz_to_next_set_block(struct dmz_metadata *zmd, struct dm_zone *zone,
				 sector_t chunk_block, unsigned int nr_blocks,
				 int set)
{
	struct dmz_mblock *mblk;
	unsigned int bit, set_bit, nr_bits;
	unsigned int zone_bits = zmd->zone_bits_per_mblk;
	unsigned long *bitmap;
	int n = 0;

	WARN_ON(chunk_block + nr_blocks > zmd->zone_nr_blocks);

	while (nr_blocks) {
		/* Get bitmap block */
		mblk = dmz_get_bitmap(zmd, zone, chunk_block);
		if (IS_ERR(mblk))
			return PTR_ERR(mblk);

		/* Get offset */
		bitmap = (unsigned long *) mblk->data;
		bit = chunk_block & DMZ_BLOCK_MASK_BITS;
		nr_bits = min(nr_blocks, zone_bits - bit);
		if (set)
			set_bit = find_next_bit(bitmap, zone_bits, bit);
		else
			set_bit = find_next_zero_bit(bitmap, zone_bits, bit);
		dmz_release_mblock(zmd, mblk);

		n += set_bit - bit;
		if (set_bit < zone_bits)
			break;

		nr_blocks -= nr_bits;
		chunk_block += nr_bits;
	}

	return n;
}

/*
 * Test if chunk_block is valid. If it is, the number of consecutive
 * valid blocks from chunk_block will be returned.
 */
int dmz_block_valid(struct dmz_metadata *zmd, struct dm_zone *zone,
		    sector_t chunk_block)
{
	int valid;

	valid = dmz_test_block(zmd, zone, chunk_block);
	if (valid <= 0)
		return valid;

	/* The block is valid: get the number of valid blocks from block */
	return dmz_to_next_set_block(zmd, zone, chunk_block,
				     zmd->zone_nr_blocks - chunk_block, 0);
}

/*
 * Find the first valid block from @chunk_block in @zone.
 * If such a block is found, its number is returned using
 * @chunk_block and the total number of valid blocks from @chunk_block
 * is returned.
 */
int dmz_first_valid_block(struct dmz_metadata *zmd, struct dm_zone *zone,
			  sector_t *chunk_block)
{
	sector_t start_block = *chunk_block;
	int ret;

	ret = dmz_to_next_set_block(zmd, zone, start_block,
				    zmd->zone_nr_blocks - start_block, 1);
	if (ret < 0)
		return ret;

	start_block += ret;
	*chunk_block = start_block;

	return dmz_to_next_set_block(zmd, zone, start_block,
				     zmd->zone_nr_blocks - start_block, 0);
}

/*
 * Count the number of bits set starting from bit up to bit + nr_bits - 1.
 */
static int dmz_count_bits(void *bitmap, int bit, int nr_bits)
{
	unsigned long *addr;
	int end = bit + nr_bits;
	int n = 0;

	while (bit < end) {
		if (((bit & (BITS_PER_LONG - 1)) == 0) &&
		    ((end - bit) >= BITS_PER_LONG)) {
			addr = (unsigned long *)bitmap + BIT_WORD(bit);
			if (*addr == ULONG_MAX) {
				n += BITS_PER_LONG;
				bit += BITS_PER_LONG;
				continue;
			}
		}

		if (test_bit(bit, bitmap))
			n++;
		bit++;
	}

	return n;
}

/*
 * Get a zone weight.
 */
static void dmz_get_zone_weight(struct dmz_metadata *zmd, struct dm_zone *zone)
{
	struct dmz_mblock *mblk;
	sector_t chunk_block = 0;
	unsigned int bit, nr_bits;
	unsigned int nr_blocks = zmd->zone_nr_blocks;
	void *bitmap;
	int n = 0;

	while (nr_blocks) {
		/* Get bitmap block */
		mblk = dmz_get_bitmap(zmd, zone, chunk_block);
		if (IS_ERR(mblk)) {
			n = 0;
			break;
		}

		/* Count bits in this block */
		bitmap = mblk->data;
		bit = chunk_block & DMZ_BLOCK_MASK_BITS;
		nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit);
		n += dmz_count_bits(bitmap, bit, nr_bits);

		dmz_release_mblock(zmd, mblk);

		nr_blocks -= nr_bits;
		chunk_block += nr_bits;
	}

	zone->weight = n;
}

/*
 * Cleanup the zoned metadata resources.
 */
static void dmz_cleanup_metadata(struct dmz_metadata *zmd)
{
	struct rb_root *root;
	struct dmz_mblock *mblk, *next;
	int i;

	/* Release zone mapping resources */
	if (zmd->map_mblk) {
		for (i = 0; i < zmd->nr_map_blocks; i++)
			dmz_release_mblock(zmd, zmd->map_mblk[i]);
		kfree(zmd->map_mblk);
		zmd->map_mblk = NULL;
	}

	/* Release super blocks */
	for (i = 0; i < 2; i++) {
		if (zmd->sb[i].mblk) {
			dmz_free_mblock(zmd, zmd->sb[i].mblk);
			zmd->sb[i].mblk = NULL;
		}
	}

	/* Free cached blocks */
	while (!list_empty(&zmd->mblk_dirty_list)) {
		mblk = list_first_entry(&zmd->mblk_dirty_list,
					struct dmz_mblock, link);
		dmz_zmd_warn(zmd, "mblock %llu still in dirty list (ref %u)",
			     (u64)mblk->no, mblk->ref);
		list_del_init(&mblk->link);
		rb_erase(&mblk->node, &zmd->mblk_rbtree);
		dmz_free_mblock(zmd, mblk);
	}

	while (!list_empty(&zmd->mblk_lru_list)) {
		mblk = list_first_entry(&zmd->mblk_lru_list,
					struct dmz_mblock, link);
		list_del_init(&mblk->link);
		rb_erase(&mblk->node, &zmd->mblk_rbtree);
		dmz_free_mblock(zmd, mblk);
	}

	/* Sanity checks: the mblock rbtree should now be empty */
	root = &zmd->mblk_rbtree;
	rbtree_postorder_for_each_entry_safe(mblk, next, root, node) {
		dmz_zmd_warn(zmd, "mblock %llu ref %u still in rbtree",
			     (u64)mblk->no, mblk->ref);
		mblk->ref = 0;
		dmz_free_mblock(zmd, mblk);
	}

	/* Free the zone descriptors */
	dmz_drop_zones(zmd);

	mutex_destroy(&zmd->mblk_flush_lock);
	mutex_destroy(&zmd->map_lock);
}

static void dmz_print_dev(struct dmz_metadata *zmd, int num)
{
	struct dmz_dev *dev = &zmd->dev[num];

	if (!bdev_is_zoned(dev->bdev))
		dmz_dev_info(dev, "Regular block device");
	else
		dmz_dev_info(dev, "Host-managed zoned block device");

	if (zmd->sb_version > 1) {
		sector_t sector_offset =
			dev->zone_offset << zmd->zone_nr_sectors_shift;

		dmz_dev_info(dev, "  %llu 512-byte logical sectors (offset %llu)",
			     (u64)dev->capacity, (u64)sector_offset);
		dmz_dev_info(dev, "  %u zones of %llu 512-byte logical sectors (offset %llu)",
			     dev->nr_zones, (u64)zmd->zone_nr_sectors,
			     (u64)dev->zone_offset);
	} else {
		dmz_dev_info(dev, "  %llu 512-byte logical sectors",
			     (u64)dev->capacity);
		dmz_dev_info(dev, "  %u zones of %llu 512-byte logical sectors",
			     dev->nr_zones, (u64)zmd->zone_nr_sectors);
	}
}

/*
 * Initialize the zoned metadata.
 */
int dmz_ctr_metadata(struct dmz_dev *dev, int num_dev,
		     struct dmz_metadata **metadata,
		     const char *devname)
{
	struct dmz_metadata *zmd;
	unsigned int i;
	struct dm_zone *zone;
	int ret;

	zmd = kzalloc(sizeof(struct dmz_metadata), GFP_KERNEL);
	if (!zmd)
		return -ENOMEM;

	strcpy(zmd->devname, devname);
	zmd->dev = dev;
	zmd->nr_devs = num_dev;
	zmd->mblk_rbtree = RB_ROOT;
	init_rwsem(&zmd->mblk_sem);
	mutex_init(&zmd->mblk_flush_lock);
	spin_lock_init(&zmd->mblk_lock);
	INIT_LIST_HEAD(&zmd->mblk_lru_list);
	INIT_LIST_HEAD(&zmd->mblk_dirty_list);

	mutex_init(&zmd->map_lock);

	atomic_set(&zmd->unmap_nr_cache, 0);
	INIT_LIST_HEAD(&zmd->unmap_cache_list);
	INIT_LIST_HEAD(&zmd->map_cache_list);

	atomic_set(&zmd->nr_reserved_seq_zones, 0);
	INIT_LIST_HEAD(&zmd->reserved_seq_zones_list);

	init_waitqueue_head(&zmd->free_wq);

	/* Initialize zone descriptors */
	ret = dmz_init_zones(zmd);
	if (ret)
		goto err;

	/* Get super block */
	ret = dmz_load_sb(zmd);
	if (ret)
		goto err;

	/* Set metadata zones starting from sb_zone */
	for (i = 0; i < zmd->nr_meta_zones << 1; i++) {
		zone = dmz_get(zmd, zmd->sb[0].zone->id + i);
		if (!zone) {
			dmz_zmd_err(zmd,
				    "metadata zone %u not present", i);
			ret = -ENXIO;
			goto err;
		}
		if (!dmz_is_rnd(zone) && !dmz_is_cache(zone)) {
			dmz_zmd_err(zmd,
				    "metadata zone %d is not random", i);
			ret = -ENXIO;
			goto err;
		}
		set_bit(DMZ_META, &zone->flags);
	}
	/* Load mapping table */
	ret = dmz_load_mapping(zmd);
	if (ret)
		goto err;

	/*
	 * Cache size boundaries: allow at least 2 super blocks, the chunk map
	 * blocks and enough blocks to be able to cache the bitmap blocks of
	 * up to 16 zones when idle (min_nr_mblks). Otherwise, if busy, allow
	 * the cache to add 512 more metadata blocks.
	 */
	zmd->min_nr_mblks = 2 + zmd->nr_map_blocks + zmd->zone_nr_bitmap_blocks * 16;
	zmd->max_nr_mblks = zmd->min_nr_mblks + 512;

	/* Metadata cache shrinker */
	zmd->mblk_shrinker = shrinker_alloc(0,  "dm-zoned-meta:(%u:%u)",
					    MAJOR(dev->bdev->bd_dev),
					    MINOR(dev->bdev->bd_dev));
	if (!zmd->mblk_shrinker) {
		ret = -ENOMEM;
		dmz_zmd_err(zmd, "Allocate metadata cache shrinker failed");
		goto err;
	}

	zmd->mblk_shrinker->count_objects = dmz_mblock_shrinker_count;
	zmd->mblk_shrinker->scan_objects = dmz_mblock_shrinker_scan;
	zmd->mblk_shrinker->private_data = zmd;

	shrinker_register(zmd->mblk_shrinker);

	dmz_zmd_info(zmd, "DM-Zoned metadata version %d", zmd->sb_version);
	for (i = 0; i < zmd->nr_devs; i++)
		dmz_print_dev(zmd, i);

	dmz_zmd_info(zmd, "  %u zones of %llu 512-byte logical sectors",
		     zmd->nr_zones, (u64)zmd->zone_nr_sectors);
	dmz_zmd_debug(zmd, "  %u metadata zones",
		      zmd->nr_meta_zones * 2);
	dmz_zmd_debug(zmd, "  %u data zones for %u chunks",
		      zmd->nr_data_zones, zmd->nr_chunks);
	dmz_zmd_debug(zmd, "    %u cache zones (%u unmapped)",
		      zmd->nr_cache, atomic_read(&zmd->unmap_nr_cache));
	for (i = 0; i < zmd->nr_devs; i++) {
		dmz_zmd_debug(zmd, "    %u random zones (%u unmapped)",
			      dmz_nr_rnd_zones(zmd, i),
			      dmz_nr_unmap_rnd_zones(zmd, i));
		dmz_zmd_debug(zmd, "    %u sequential zones (%u unmapped)",
			      dmz_nr_seq_zones(zmd, i),
			      dmz_nr_unmap_seq_zones(zmd, i));
	}
	dmz_zmd_debug(zmd, "  %u reserved sequential data zones",
		      zmd->nr_reserved_seq);
	dmz_zmd_debug(zmd, "Format:");
	dmz_zmd_debug(zmd, "%u metadata blocks per set (%u max cache)",
		      zmd->nr_meta_blocks, zmd->max_nr_mblks);
	dmz_zmd_debug(zmd, "  %u data zone mapping blocks",
		      zmd->nr_map_blocks);
	dmz_zmd_debug(zmd, "  %u bitmap blocks",
		      zmd->nr_bitmap_blocks);

	*metadata = zmd;

	return 0;
err:
	dmz_cleanup_metadata(zmd);
	kfree(zmd);
	*metadata = NULL;

	return ret;
}

/*
 * Cleanup the zoned metadata resources.
 */
void dmz_dtr_metadata(struct dmz_metadata *zmd)
{
	shrinker_free(zmd->mblk_shrinker);
	dmz_cleanup_metadata(zmd);
	kfree(zmd);
}
