/*
 * Copyright (C) 2016 Red Hat, Inc. All rights reserved.
 *
 * _stats_get_extents_for_file() based in part on filefrag_fiemap() from
 * e2fsprogs/misc/filefrag.c. Copyright 2003 by Theodore Ts'o.
 *
 * This file is part of the device-mapper userspace tools.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "dmlib.h"

#include "math.h" /* log10() */

#include <sys/ioctl.h>
#include <sys/vfs.h> /* fstatfs */

#ifdef __linux__
  #include <linux/fs.h> /* FS_IOC_FIEMAP */
#endif

#ifdef HAVE_LINUX_FIEMAP_H
  #include <linux/fiemap.h> /* fiemap */
#endif

#ifdef HAVE_LINUX_MAGIC_H
  #include <linux/magic.h> /* BTRFS_SUPER_MAGIC */
#endif

#define DM_STATS_REGION_NOT_PRESENT UINT64_MAX
#define DM_STATS_GROUP_NOT_PRESENT DM_STATS_GROUP_NONE

#define NSEC_PER_USEC   1000L
#define NSEC_PER_MSEC   1000000L
#define NSEC_PER_SEC    1000000000L

#define PRECISE_ARG "precise_timestamps"
#define HISTOGRAM_ARG "histogram:"

#define STATS_ROW_BUF_LEN 4096
#define STATS_MSG_BUF_LEN 1024
#define STATS_FIE_BUF_LEN 2048

#define SECTOR_SHIFT 9L

/* Histogram bin */
struct dm_histogram_bin {
	uint64_t upper; /* Upper bound on this bin. */
	uint64_t count; /* Count value for this bin. */
};

struct dm_histogram {
	/* The stats handle this histogram belongs to. */
	const struct dm_stats *dms;
	/* The region this histogram belongs to. */
	const struct dm_stats_region *region;
	uint64_t sum; /* Sum of histogram bin counts. */
	int nr_bins; /* Number of histogram bins assigned. */
	struct dm_histogram_bin bins[0];
};

/*
 * See Documentation/device-mapper/statistics.txt for full descriptions
 * of the device-mapper statistics counter fields.
 */
struct dm_stats_counters {
	uint64_t reads;		    /* Num reads completed */
	uint64_t reads_merged;	    /* Num reads merged */
	uint64_t read_sectors;	    /* Num sectors read */
	uint64_t read_nsecs;	    /* Num milliseconds spent reading */
	uint64_t writes;	    /* Num writes completed */
	uint64_t writes_merged;	    /* Num writes merged */
	uint64_t write_sectors;	    /* Num sectors written */
	uint64_t write_nsecs;	    /* Num milliseconds spent writing */
	uint64_t io_in_progress;    /* Num I/Os currently in progress */
	uint64_t io_nsecs;	    /* Num milliseconds spent doing I/Os */
	uint64_t weighted_io_nsecs; /* Weighted num milliseconds doing I/Os */
	uint64_t total_read_nsecs;  /* Total time spent reading in milliseconds */
	uint64_t total_write_nsecs; /* Total time spent writing in milliseconds */
	struct dm_histogram *histogram; /* Histogram. */
};

struct dm_stats_region {
	uint64_t region_id; /* as returned by @stats_list */
	uint64_t group_id;
	uint64_t start;
	uint64_t len;
	uint64_t step;
	char *program_id;
	char *aux_data;
	uint64_t timescale; /* precise_timestamps is per-region */
	struct dm_histogram *bounds; /* histogram configuration */
	struct dm_histogram *histogram; /* aggregate cache */
	struct dm_stats_counters *counters;
};

struct dm_stats_group {
	uint64_t group_id;
	const char *alias;
	dm_bitset_t regions;
	struct dm_histogram *histogram;
};

struct dm_stats {
	/* device binding */
	int bind_major;  /* device major that this dm_stats object is bound to */
	int bind_minor;  /* device minor that this dm_stats object is bound to */
	char *bind_name; /* device-mapper device name */
	char *bind_uuid; /* device-mapper UUID */
	char *program_id; /* default program_id for this handle */
	const char *name; /* cached device_name used for reporting */
	struct dm_pool *mem; /* memory pool for region and counter tables */
	struct dm_pool *hist_mem; /* separate pool for histogram tables */
	struct dm_pool *group_mem; /* separate pool for group tables */
	uint64_t nr_regions; /* total number of present regions */
	uint64_t max_region; /* size of the regions table */
	uint64_t interval_ns;  /* sampling interval in nanoseconds */
	uint64_t timescale; /* default sample value multiplier */
	int precise; /* use precise_timestamps when creating regions */
	struct dm_stats_region *regions;
	struct dm_stats_group *groups;
	/* statistics cursor */
	uint64_t walk_flags; /* walk control flags */
	uint64_t cur_flags;
	uint64_t cur_group;
	uint64_t cur_region;
	uint64_t cur_area;
};

#define PROC_SELF_COMM "/proc/self/comm"
static char *_program_id_from_proc(void)
{
	FILE *comm = NULL;
	char buf[STATS_ROW_BUF_LEN];

	if (!(comm = fopen(PROC_SELF_COMM, "r")))
		return_NULL;

	if (!fgets(buf, sizeof(buf), comm)) {
		log_error("Could not read from %s", PROC_SELF_COMM);
		if (fclose(comm))
			stack;
		return NULL;
	}

	if (fclose(comm))
		stack;

	return dm_strdup(buf);
}

static uint64_t _nr_areas(uint64_t len, uint64_t step)
{
	/* Default is one area. */
	if (!len || !step)
		return 1;
	/*
	 * drivers/md/dm-stats.c::message_stats_create()
	 * A region may be sub-divided into areas with their own counters.
	 * Any partial area at the end of the region is treated as an
	 * additional complete area.
	 */
	return (len + step - 1) / step;
}

static uint64_t _nr_areas_region(struct dm_stats_region *region)
{
	return _nr_areas(region->len, region->step);
}

struct dm_stats *dm_stats_create(const char *program_id)
{
	size_t hist_hint = sizeof(struct dm_histogram_bin);
	size_t group_hint = sizeof(struct dm_stats_group);
	struct dm_stats *dms = NULL;

	if (!(dms = dm_zalloc(sizeof(*dms))))
		return_NULL;

	/* FIXME: better hint. */
	if (!(dms->mem = dm_pool_create("stats_pool", 4096))) {
		dm_free(dms);
		return_NULL;
	}

	if (!(dms->hist_mem = dm_pool_create("histogram_pool", hist_hint)))
		goto_bad;

	if (!(dms->group_mem = dm_pool_create("group_pool", group_hint)))
		goto_bad;

	if (!program_id || !strlen(program_id))
		dms->program_id = _program_id_from_proc();
	else
		dms->program_id = dm_strdup(program_id);

	if (!dms->program_id) {
		log_error("Could not allocate memory for program_id");
		goto bad;
	}

	dms->bind_major = -1;
	dms->bind_minor = -1;
	dms->bind_name = NULL;
	dms->bind_uuid = NULL;

	dms->name = NULL;

	/* by default all regions use msec precision */
	dms->timescale = NSEC_PER_MSEC;
	dms->precise = 0;

	dms->nr_regions = DM_STATS_REGION_NOT_PRESENT;
	dms->max_region = DM_STATS_REGION_NOT_PRESENT;
	dms->regions = NULL;

	/* maintain compatibility with earlier walk version */
	dms->walk_flags = dms->cur_flags = DM_STATS_WALK_DEFAULT;

	return dms;

bad:
	dm_pool_destroy(dms->mem);
	if (dms->hist_mem)
		dm_pool_destroy(dms->hist_mem);
	if (dms->group_mem)
		dm_pool_destroy(dms->group_mem);
	dm_free(dms);
	return NULL;
}

/*
 * Test whether the stats region pointed to by region is present.
 */
static int _stats_region_present(const struct dm_stats_region *region)
{
	return !(region->region_id == DM_STATS_REGION_NOT_PRESENT);
}

/*
 * Test whether the stats group pointed to by group is present.
 */
static int _stats_group_present(const struct dm_stats_group *group)
{
	return !(group->group_id == DM_STATS_GROUP_NOT_PRESENT);
}

/*
 * Test whether a stats group id is present.
 */
static int _stats_group_id_present(const struct dm_stats *dms, uint64_t id)
{
	struct dm_stats_group *group = NULL;

	if (!dms || !dms->regions)
		return_0;

	if (id > dms->max_region)
		return 0;

	group = &dms->groups[id];

	return _stats_group_present(group);
}

/*
 * Test whether the given region_id is a member of any group.
 */
static uint64_t _stats_region_is_grouped(const struct dm_stats* dms,
					 uint64_t region_id)
{
	uint64_t group_id;

	if (region_id == DM_STATS_GROUP_NOT_PRESENT)
		return 0;

	if (!_stats_region_present(&dms->regions[region_id]))
		return 0;

	group_id = dms->regions[region_id].group_id;

	return group_id != DM_STATS_GROUP_NOT_PRESENT;
}

static void _stats_histograms_destroy(struct dm_pool *mem,
				      struct dm_stats_region *region)
{
	/* Unpopulated handle. */
	if (!region->counters)
		return;

	/*
	 * Free everything in the pool back to the first histogram.
	 */
	if (region->counters[0].histogram)
		dm_pool_free(mem, region->counters[0].histogram);
}

static void _stats_region_destroy(struct dm_stats_region *region)
{
	if (!_stats_region_present(region))
		return;

	region->start = region->len = region->step = 0;
	region->timescale = 0;

	/*
	 * Don't free counters and histogram bounds here: they are
	 * dropped from the pool along with the corresponding
	 * regions table.
	 *
	 * The following objects are all allocated with dm_malloc.
	 */

	region->counters = NULL;
	region->bounds = NULL;

	if (region->program_id)
		dm_free(region->program_id);
	region->program_id = NULL;
	if (region->aux_data)
		dm_free(region->aux_data);
	region->aux_data = NULL;
	region->region_id = DM_STATS_REGION_NOT_PRESENT;
}

static void _stats_regions_destroy(struct dm_stats *dms)
{
	struct dm_pool *mem = dms->mem;
	uint64_t i;

	if (!dms->regions)
		return;

	/* walk backwards to obey pool order */
	for (i = dms->max_region; (i != DM_STATS_REGION_NOT_PRESENT); i--) {
		_stats_histograms_destroy(dms->hist_mem, &dms->regions[i]);
		_stats_region_destroy(&dms->regions[i]);
	}

	dm_pool_free(mem, dms->regions);
}

static void _stats_group_destroy(struct dm_stats_group *group)
{
	if (!_stats_group_present(group))
		return;

	group->histogram = NULL;

	if (group->alias) {
		dm_free((char *) group->alias);
		group->alias = NULL;
	}
	if (group->regions) {
		dm_bitset_destroy(group->regions);
		group->regions = NULL;
	}
	group->group_id = DM_STATS_GROUP_NOT_PRESENT;
}

static void _stats_groups_destroy(struct dm_stats *dms)
{
	uint64_t i;

	if (!dms->groups)
		return;

	for (i = dms->max_region; (i != DM_STATS_REGION_NOT_PRESENT); i--)
		_stats_group_destroy(&dms->groups[i]);
	dm_pool_free(dms->group_mem, dms->groups);
}

static int _set_stats_device(struct dm_stats *dms, struct dm_task *dmt)
{
	if (dms->bind_name)
		return dm_task_set_name(dmt, dms->bind_name);
	if (dms->bind_uuid)
		return dm_task_set_uuid(dmt, dms->bind_uuid);
	if (dms->bind_major > 0)
		return dm_task_set_major(dmt, dms->bind_major)
			&& dm_task_set_minor(dmt, dms->bind_minor);
	return_0;
}

static int _stats_bound(const struct dm_stats *dms)
{
	if (dms->bind_major > 0 || dms->bind_name || dms->bind_uuid)
		return 1;
	/* %p format specifier expects a void pointer. */
	log_debug("Stats handle at %p is not bound.", (void *) dms);
	return 0;
}

static void _stats_clear_binding(struct dm_stats *dms)
{
	if (dms->bind_name)
		dm_pool_free(dms->mem, dms->bind_name);
	if (dms->bind_uuid)
		dm_pool_free(dms->mem, dms->bind_uuid);
	if (dms->name)
		dm_free((char *) dms->name);

	dms->bind_name = dms->bind_uuid = NULL;
	dms->bind_major = dms->bind_minor = -1;
	dms->name = NULL;
}

int dm_stats_bind_devno(struct dm_stats *dms, int major, int minor)
{
	_stats_clear_binding(dms);
	_stats_regions_destroy(dms);
	_stats_groups_destroy(dms);

	dms->bind_major = major;
	dms->bind_minor = minor;

	return 1;
}

int dm_stats_bind_name(struct dm_stats *dms, const char *name)
{
	_stats_clear_binding(dms);
	_stats_regions_destroy(dms);
	_stats_groups_destroy(dms);

	if (!(dms->bind_name = dm_pool_strdup(dms->mem, name)))
		return_0;

	return 1;
}

int dm_stats_bind_uuid(struct dm_stats *dms, const char *uuid)
{
	_stats_clear_binding(dms);
	_stats_regions_destroy(dms);
	_stats_groups_destroy(dms);

	if (!(dms->bind_uuid = dm_pool_strdup(dms->mem, uuid)))
		return_0;

	return 1;
}

static int _stats_check_precise_timestamps(const struct dm_stats *dms)
{
	/* Already checked? */
	if (dms && dms->precise)
		return 1;

	return dm_message_supports_precise_timestamps();
}

int dm_stats_driver_supports_precise(void)
{
	return _stats_check_precise_timestamps(NULL);
}

int dm_stats_driver_supports_histogram(void)
{
	return _stats_check_precise_timestamps(NULL);
}

static int _fill_hist_arg(char *hist_arg, size_t hist_len, uint64_t scale,
			  struct dm_histogram *bounds)
{
	int i, l, len = 0, nr_bins;
	char *arg = hist_arg;
	uint64_t value;

	nr_bins = bounds->nr_bins;

	for (i = 0; i < nr_bins; i++) {
		value = bounds->bins[i].upper / scale;
		if ((l = dm_snprintf(arg, hist_len - len, FMTu64"%s", value,
				     (i == (nr_bins - 1)) ? "" : ",")) < 0)
			return_0;
		len += l;
		arg += l;
	}
	return 1;
}

static void *_get_hist_arg(struct dm_histogram *bounds, uint64_t scale,
			   size_t *len)
{
	struct dm_histogram_bin *entry, *bins;
	size_t hist_len = 1; /* terminating '\0' */
	double value;

	entry = bins = bounds->bins;

	entry += bounds->nr_bins - 1;
	while(entry >= bins) {
		value = (double) (entry--)->upper;
		/* Use lround to avoid size_t -> double cast warning. */
		hist_len += 1 + (size_t) lround(log10(value / scale));
		if (entry != bins)
			hist_len++; /* ',' */
	}

	*len = hist_len;

	return dm_zalloc(hist_len);
}

static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
{
	struct dm_histogram_bin *entry, *bins;
	size_t hist_len;
	char *hist_arg;
	uint64_t scale;

	entry = bins = bounds->bins;

	/* Empty histogram is invalid. */
	if (!bounds->nr_bins) {
		log_error("Cannot format empty histogram description.");
		return NULL;
	}

	/* Validate entries and set *precise if precision < 1ms. */
	entry += bounds->nr_bins - 1;
	while (entry >= bins) {
		if (entry != bins) {
			if (entry->upper < (entry - 1)->upper) {
				log_error("Histogram boundaries must be in "
					  "order of increasing magnitude.");
				return 0;
			}
		}

		/*
		 * Only enable precise_timestamps automatically if any
		 * value in the histogram bounds uses precision < 1ms.
		 */
		if (((entry--)->upper % NSEC_PER_MSEC) && !*precise)
			*precise = 1;
	}

	scale = (*precise) ? 1 : NSEC_PER_MSEC;

	/* Calculate hist_len and allocate a character buffer. */
	if (!(hist_arg = _get_hist_arg(bounds, scale, &hist_len))) {
		log_error("Could not allocate memory for histogram argument.");
		return 0;
	}

	/* Fill hist_arg with boundary strings. */
	if (!_fill_hist_arg(hist_arg, hist_len, scale, bounds))
		goto_bad;

	return hist_arg;

bad:
	log_error("Could not build histogram arguments.");
	dm_free(hist_arg);

	return NULL;
}

static struct dm_task *_stats_send_message(struct dm_stats *dms, char *msg)
{
	struct dm_task *dmt;

	if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
		return_0;

	if (!_set_stats_device(dms, dmt))
		goto_bad;

	if (!dm_task_set_message(dmt, msg))
		goto_bad;

	if (!dm_task_run(dmt))
		goto_bad;

	return dmt;

bad:
	dm_task_destroy(dmt);
	return NULL;
}

/*
 * Cache the dm device_name for the device bound to dms.
 */
static int _stats_set_name_cache(struct dm_stats *dms)
{
	struct dm_task *dmt;

	if (dms->name)
		return 1;

	if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
		return_0;

	if (!_set_stats_device(dms, dmt))
		goto_bad;

	if (!dm_task_run(dmt))
		goto_bad;

	if (!(dms->name = dm_strdup(dm_task_get_name(dmt))))
		goto_bad;

	dm_task_destroy(dmt);

	return 1;

bad:
	log_error("Could not retrieve device-mapper name for device.");
	dm_task_destroy(dmt);
	return 0;
}

/*
 * update region group_id values
 */
static void _stats_update_groups(struct dm_stats *dms)
{
	struct dm_stats_group *group;
	uint64_t group_id, i;

	for (group_id = 0; group_id < dms->max_region + 1; group_id++) {
		if (!_stats_group_id_present(dms, group_id))
			continue;

		group = &dms->groups[group_id];

		for (i = dm_bit_get_first(group->regions);
		     i != DM_STATS_GROUP_NOT_PRESENT;
		     i = dm_bit_get_next(group->regions, i))
			dms->regions[i].group_id = group_id;
	}
}

/*
 * Parse a DMS_GROUP group descriptor embedded in a region's aux_data.
 *
 * DMS_GROUP="ALIAS:MEMBERS"
 *
 * ALIAS: group alias
 * MEMBERS: list of group member region ids.
 *
 */
#define DMS_GROUP_TAG "DMS_GROUP="
#define DMS_GROUP_TAG_LEN (sizeof(DMS_GROUP_TAG) - 1)
#define DMS_GROUP_SEP ':'
#define DMS_AUX_SEP "#"
static int _parse_aux_data_group(struct dm_stats *dms,
				 struct dm_stats_region *region,
				 struct dm_stats_group *group)
{
	char *alias, *c, *end;
	dm_bitset_t regions;

	memset(group, 0, sizeof(*group));
	group->group_id = DM_STATS_GROUP_NOT_PRESENT;

	/* find start of group tag */
	c = strstr(region->aux_data, DMS_GROUP_TAG);
	if (!c)
		return 1; /* no group is not an error */

	alias = c + strlen(DMS_GROUP_TAG);

	c = strchr(c, DMS_GROUP_SEP);

	if (!c) {
		log_error("Found malformed group tag while reading aux_data");
		return 0;
	}

	/* terminate alias and advance to members */
	*(c++) = '\0';

	log_debug("Read alias '%s' from aux_data", alias);

	if (!c) {
		log_error("Found malformed group descriptor while "
			  "reading aux_data, expected '%c'", DMS_GROUP_SEP);
		return 0;
	}

	/* if user aux_data follows make sure we have a terminated
	 * string to pass to dm_bitset_parse_list().
	 */
	end = strstr(c, DMS_AUX_SEP);
	if (!end)
		end = c + strlen(c);
	*(end++) = '\0';

	if (!(regions = dm_bitset_parse_list(c, NULL))) {
		log_error("Could not parse member list while "
			  "reading group aux_data");
		return 0;
	}

	group->group_id = dm_bit_get_first(regions);
	group->regions = regions;

	group->alias = NULL;
	if (strlen(alias)) {
		group->alias = dm_strdup(alias);
		if (!group->alias) {
			log_error("Could not allocate memory for group alias");
			goto bad;
		}
	}

	/* separate group tag from user aux_data */
	if ((strlen(end) > 1) || strncmp(end, "-", 1))
		c = dm_strdup(end);
	else
		c = dm_strdup("");

	if (!c) {
		log_error("Could not allocate memory for user aux_data");
		goto bad_alias;
	}

	dm_free(region->aux_data);
	region->aux_data = c;

	log_debug("Found group_id " FMTu64 ": alias=\"%s\"", group->group_id,
		  (group->alias) ? group->alias : "");

	return 1;

bad_alias:
	dm_free((char *) group->alias);
bad:
	dm_bitset_destroy(regions);
	return 0;
}

/*
 * Parse a histogram specification returned by the kernel in a
 * @stats_list response.
 */
static int _stats_parse_histogram_spec(struct dm_stats *dms,
				       struct dm_stats_region *region,
				       const char *histogram)
{
	static const char _valid_chars[] = "0123456789,";
	uint64_t scale = region->timescale, this_val = 0;
	struct dm_pool *mem = dms->hist_mem;
	struct dm_histogram_bin cur;
	struct dm_histogram hist;
	int nr_bins = 1;
	const char *c, *v, *val_start;
	char *p, *endptr = NULL;

	/* Advance past "histogram:". */
	histogram = strchr(histogram, ':');
	if (!histogram) {
		log_error("Could not parse histogram description.");
		return 0;
	}
	histogram++;

	/* @stats_list rows are newline terminated. */
	if ((p = strchr(histogram, '\n')))
		*p = '\0';

	if (!dm_pool_begin_object(mem, sizeof(cur)))
		return_0;

	memset(&hist, 0, sizeof(hist));

	hist.nr_bins = 0; /* fix later */
	hist.region = region;
	hist.dms = dms;

	if (!dm_pool_grow_object(mem, &hist, sizeof(hist)))
		goto_bad;

	c = histogram;
	do {
		for (v = _valid_chars; *v; v++)
			if (*c == *v)
				break;
		if (!*v) {
			stack;
			goto badchar;
		}

		if (*c == ',') {
			log_error("Invalid histogram description: %s",
				  histogram);
			goto bad;
		} else {
			val_start = c;
			endptr = NULL;

			this_val = strtoull(val_start, &endptr, 10);
			if (!endptr) {
				log_error("Could not parse histogram boundary.");
				goto bad;
			}

			c = endptr; /* Advance to units, comma, or end. */

			if (*c == ',')
				c++;
			else if (*c || (*c == ' ')) { /* Expected ',' or NULL. */
				stack;
				goto badchar;
			}

			if (*c == ',')
				c++;

			cur.upper = scale * this_val;
			cur.count = 0;

			if (!dm_pool_grow_object(mem, &cur, sizeof(cur)))
				goto_bad;

			nr_bins++;
		}
	} while (*c && (*c != ' '));

	/* final upper bound. */
	cur.upper = UINT64_MAX;
	if (!dm_pool_grow_object(mem, &cur, sizeof(cur)))
		goto_bad;

	region->bounds = dm_pool_end_object(mem);

	if (!region->bounds)
		return_0;

	region->bounds->nr_bins = nr_bins;

	log_debug("Added region histogram spec with %d entries.", nr_bins);
	return 1;

badchar:
	log_error("Invalid character in histogram: '%c' (0x%x)", *c, *c);
bad:
	dm_pool_abandon_object(mem);
	return 0;
}

static int _stats_parse_list_region(struct dm_stats *dms,
				    struct dm_stats_region *region, char *line)
{
	char *p = NULL, string_data[STATS_ROW_BUF_LEN];
	char *program_id, *aux_data, *stats_args;
	char *empty_string = (char *) "";
	int r;

	memset(string_data, 0, sizeof(string_data));

	/*
	 * Parse fixed fields, line format:
	 *
	 * <region_id>: <start_sector>+<length> <step> <string data>
	 *
	 * Maximum string data size is 4096 - 1 bytes.
	 */
	r = sscanf(line, FMTu64 ": " FMTu64 "+" FMTu64 " " FMTu64 " %4095c",
		   &region->region_id, &region->start, &region->len,
		   &region->step, string_data);

	if (r != 5)
		return_0;

	/* program_id is guaranteed to be first. */
	program_id = string_data;

	/*
	 * FIXME: support embedded '\ ' in string data:
	 *   s/strchr/_find_unescaped_space()/
	 */
	if ((p = strchr(string_data, ' '))) {
		/* terminate program_id string. */
		*p = '\0';
		if (!strncmp(program_id, "-", 1))
			program_id = empty_string;
		aux_data = p + 1;
		if ((p = strchr(aux_data, ' '))) {
			/* terminate aux_data string. */
			*p = '\0';
			stats_args = p + 1;
		} else
			stats_args = empty_string;

		/* no aux_data? */
		if (!strncmp(aux_data, "-", 1))
			aux_data = empty_string;
		else
			/* remove trailing newline */
			aux_data[strlen(aux_data) - 1] = '\0';
	} else
		aux_data = stats_args = empty_string;

	if (strstr(stats_args, PRECISE_ARG))
		region->timescale = 1;
	else
		region->timescale = NSEC_PER_MSEC;

	if ((p = strstr(stats_args, HISTOGRAM_ARG))) {
		if (!_stats_parse_histogram_spec(dms, region, p))
			return_0;
	} else
		region->bounds = NULL;

	/* clear aggregate cache */
	region->histogram = NULL;

	region->group_id = DM_STATS_GROUP_NOT_PRESENT;

	if (!(region->program_id = dm_strdup(program_id)))
		return_0;
	if (!(region->aux_data = dm_strdup(aux_data))) {
		dm_free(region->program_id);
		return_0;
	}

	region->counters = NULL;
	return 1;
}

static int _stats_parse_list(struct dm_stats *dms, const char *resp)
{
	uint64_t max_region = 0, nr_regions = 0;
	struct dm_stats_region cur, fill;
	struct dm_stats_group cur_group;
	struct dm_pool *mem = dms->mem, *group_mem = dms->group_mem;
	char line[STATS_ROW_BUF_LEN];
	FILE *list_rows;

	if (!resp) {
		log_error("Could not parse NULL @stats_list response.");
		return 0;
	}

	_stats_regions_destroy(dms);
	_stats_groups_destroy(dms);

	/* no regions */
	if (!strlen(resp)) {
		dms->nr_regions = dms->max_region = 0;
		dms->regions = NULL;
		return 1;
	}

	/*
	 * dm_task_get_message_response() returns a 'const char *' but
	 * since fmemopen also permits "w" it expects a 'char *'.
	 */
	if (!(list_rows = fmemopen((char *)resp, strlen(resp), "r")))
		return_0;

	/* begin region table */
	if (!dm_pool_begin_object(mem, 1024))
		goto_bad;

	/* begin group table */
	if (!dm_pool_begin_object(group_mem, 32))
		goto_bad;

	while(fgets(line, sizeof(line), list_rows)) {

		cur_group.group_id = DM_STATS_GROUP_NOT_PRESENT;
		cur_group.regions = NULL;
		cur_group.alias = NULL;

		if (!_stats_parse_list_region(dms, &cur, line))
			goto_bad;

		/* handle holes in the list of region_ids */
		if (cur.region_id > max_region) {
			memset(&fill, 0, sizeof(fill));
			memset(&cur_group, 0, sizeof(cur_group));
			fill.region_id = DM_STATS_REGION_NOT_PRESENT;
			cur_group.group_id = DM_STATS_GROUP_NOT_PRESENT;
			do {
				if (!dm_pool_grow_object(mem, &fill, sizeof(fill)))
					goto_bad;
				if (!dm_pool_grow_object(group_mem, &cur_group,
							 sizeof(cur_group)))
					goto_bad;
			} while (max_region++ < (cur.region_id - 1));
		}

		if (cur.aux_data)
			if (!_parse_aux_data_group(dms, &cur, &cur_group))
				log_error("Failed to parse group descriptor "
					  "from region_id " FMTu64 " aux_data:"
					  "'%s'", cur.region_id, cur.aux_data);
				/* continue */

		if (!dm_pool_grow_object(mem, &cur, sizeof(cur)))
			goto_bad;

		if (!dm_pool_grow_object(group_mem, &cur_group,
					 sizeof(cur_group)))
			goto_bad;

		max_region++;
		nr_regions++;
	}

	if (!nr_regions)
		/* no region data read from @stats_list */
		goto bad;

	dms->nr_regions = nr_regions;
	dms->max_region = max_region - 1;
	dms->regions = dm_pool_end_object(mem);
	dms->groups = dm_pool_end_object(group_mem);

	_stats_update_groups(dms);

	if (fclose(list_rows))
		stack;

	return 1;

bad:
	if (fclose(list_rows))
		stack;
	dm_pool_abandon_object(mem);
	dm_pool_abandon_object(group_mem);

	return 0;
}

int dm_stats_list(struct dm_stats *dms, const char *program_id)
{
	char msg[STATS_MSG_BUF_LEN];
	struct dm_task *dmt;
	int r;

	if (!_stats_bound(dms))
		return_0;

	/* allow zero-length program_id for list */
	if (!program_id)
		program_id = dms->program_id;

	if (!_stats_set_name_cache(dms))
		return_0;

	r = dm_snprintf(msg, sizeof(msg), "@stats_list %s", program_id);

	if (r < 0) {
		log_error("Failed to prepare stats message.");
		return 0;
	}

	if (!(dmt = _stats_send_message(dms, msg)))
		return_0;

	if (!_stats_parse_list(dms, dm_task_get_message_response(dmt))) {
		log_error("Could not parse @stats_list response.");
		goto bad;
	}

	dm_task_destroy(dmt);
	return 1;

bad:
	dm_task_destroy(dmt);
	return 0;
}

/*
 * Parse histogram data returned from a @stats_print operation.
 */
static int _stats_parse_histogram(struct dm_pool *mem, char *hist_str,
				  struct dm_histogram **histogram,
				  struct dm_stats_region *region)
{
	static const char _valid_chars[] = "0123456789:";
	struct dm_histogram *bounds = region->bounds;
	struct dm_histogram hist = {
		.nr_bins = region->bounds->nr_bins
	};
	const char *c, *v, *val_start;
	struct dm_histogram_bin cur;
	uint64_t sum = 0, this_val;
	char *endptr = NULL;
	int bin = 0;

	c = hist_str;

	if (!dm_pool_begin_object(mem, sizeof(cur)))
		return_0;

	if (!dm_pool_grow_object(mem, &hist, sizeof(hist)))
		goto_bad;

	do {
		memset(&cur, 0, sizeof(cur));
		for (v = _valid_chars; *v; v++)
			if (*c == *v)
				break;
		if (!*v)
			goto badchar;

		if (*c == ',')
			goto badchar;
		else {
			val_start = c;
			endptr = NULL;

			this_val = strtoull(val_start, &endptr, 10);
			if (!endptr) {
				log_error("Could not parse histogram value.");
				goto bad;
			}
			c = endptr; /* Advance to colon, or end. */

			if (*c == ':')
				c++;
			else if (*c & (*c != '\n'))
				/* Expected ':', '\n', or NULL. */
				goto badchar;

			if (*c == ':')
				c++;

			cur.upper = bounds->bins[bin].upper;
			cur.count = this_val;
			sum += this_val;

			if (!dm_pool_grow_object(mem, &cur, sizeof(cur)))
				goto_bad;

			bin++;
		}
	} while (*c && (*c != '\n'));

	log_debug("Added region histogram data with %d entries.", hist.nr_bins);

	*histogram = dm_pool_end_object(mem);
	(*histogram)->sum = sum;

	return 1;

badchar:
	log_error("Invalid character in histogram data: '%c' (0x%x)", *c, *c);
bad:
	dm_pool_abandon_object(mem);
	return 0;
}

static int _stats_parse_region(struct dm_stats *dms, const char *resp,
			       struct dm_stats_region *region,
			       uint64_t timescale)
{
	struct dm_histogram *hist = NULL;
	struct dm_pool *mem = dms->mem;
	struct dm_stats_counters cur;
	FILE *stats_rows = NULL;
	uint64_t start = 0, len = 0;
	char row[STATS_ROW_BUF_LEN];
	int r;

	if (!resp) {
		log_error("Could not parse empty @stats_print response.");
		return 0;
	}

	region->start = UINT64_MAX;

	if (!dm_pool_begin_object(mem, 512))
		goto_bad;

	/*
	 * dm_task_get_message_response() returns a 'const char *' but
	 * since fmemopen also permits "w" it expects a 'char *'.
	 */
	stats_rows = fmemopen((char *)resp, strlen(resp), "r");
	if (!stats_rows)
		goto_bad;

	/*
	 * Output format for each step-sized area of a region:
	 *
	 * <start_sector>+<length> counters
	 *
	 * The first 11 counters have the same meaning as
	 * /sys/block/ * /stat or /proc/diskstats.
	 *
	 * Please refer to Documentation/iostats.txt for details.
	 *
	 * 1. the number of reads completed
	 * 2. the number of reads merged
	 * 3. the number of sectors read
	 * 4. the number of milliseconds spent reading
	 * 5. the number of writes completed
	 * 6. the number of writes merged
	 * 7. the number of sectors written
	 * 8. the number of milliseconds spent writing
	 * 9. the number of I/Os currently in progress
	 * 10. the number of milliseconds spent doing I/Os
	 * 11. the weighted number of milliseconds spent doing I/Os
	 *
	 * Additional counters:
	 * 12. the total time spent reading in milliseconds
	 * 13. the total time spent writing in milliseconds
	 *
	*/
	while (fgets(row, sizeof(row), stats_rows)) {
		r = sscanf(row, FMTu64 "+" FMTu64 /* start+len */
			   /* reads */
			   FMTu64 " " FMTu64 " " FMTu64 " " FMTu64 " "
			   /* writes */
			   FMTu64 " " FMTu64 " " FMTu64 " " FMTu64 " "
			   /* in flight & io nsecs */
			   FMTu64 " " FMTu64 " " FMTu64 " "
			   /* tot read/write nsecs */
			   FMTu64 " " FMTu64, &start, &len,
			   &cur.reads, &cur.reads_merged, &cur.read_sectors,
			   &cur.read_nsecs,
			   &cur.writes, &cur.writes_merged, &cur.write_sectors,
			   &cur.write_nsecs,
			   &cur.io_in_progress,
			   &cur.io_nsecs, &cur.weighted_io_nsecs,
			   &cur.total_read_nsecs, &cur.total_write_nsecs);
		if (r != 15) {
			log_error("Could not parse @stats_print row.");
			goto bad;
		}

		/* scale time values up if needed */
		if (timescale != 1) {
			cur.read_nsecs *= timescale;
			cur.write_nsecs *= timescale;
			cur.io_nsecs *= timescale;
			cur.weighted_io_nsecs *= timescale;
			cur.total_read_nsecs *= timescale;
			cur.total_write_nsecs *= timescale;
		}

		if (region->bounds) {
			/* Find first histogram separator. */
			char *hist_str = strchr(row, ':');
			if (!hist_str) {
				log_error("Could not parse histogram value.");
				goto bad;
			}
			/* Find space preceding histogram. */
			while (hist_str && *(hist_str - 1) != ' ')
				hist_str--;

			/* Use a separate pool for histogram objects since we
			 * are growing the area table and each area's histogram
			 * table simultaneously.
			 */
			if (!_stats_parse_histogram(dms->hist_mem, hist_str,
						    &hist, region))
				goto_bad;
			hist->dms = dms;
			hist->region = region;
		}

		cur.histogram = hist;

		if (!dm_pool_grow_object(mem, &cur, sizeof(cur)))
			goto_bad;

		if (region->start == UINT64_MAX) {
			region->start = start;
			region->step = len; /* area size is always uniform. */
		}
	}

	if (region->start == UINT64_MAX)
		/* no area data read from @stats_print */
		goto bad;

	region->len = (start + len) - region->start;
	region->timescale = timescale;
	region->counters = dm_pool_end_object(mem);

	if (fclose(stats_rows))
		stack;

	return 1;

bad:
	if (stats_rows)
		if (fclose(stats_rows))
			stack;
	dm_pool_abandon_object(mem);

	return 0;
}

static void _stats_walk_next_present(const struct dm_stats *dms,
				     uint64_t *flags,
				     uint64_t *cur_r, uint64_t *cur_a,
				     uint64_t *cur_g)
{
	struct dm_stats_region *cur = NULL;

	/* start of walk: region loop advances *cur_r to 0. */
	if (*cur_r != DM_STATS_REGION_NOT_PRESENT)
		cur = &dms->regions[*cur_r];

	/* within current region? */
	if (cur && (*flags & DM_STATS_WALK_AREA)) {
		if (++(*cur_a) < _nr_areas_region(cur))
			return;
		else
			*cur_a = 0;
	}

	/* advance to next present, non-skipped region or end */
	while (++(*cur_r) <= dms->max_region) {
		cur = &dms->regions[*cur_r];
		if (!_stats_region_present(cur))
			continue;
		if ((*flags & DM_STATS_WALK_SKIP_SINGLE_AREA))
			if (!(*flags & DM_STATS_WALK_AREA))
				if (_nr_areas_region(cur) < 2)
					continue;
		/* matching region found */
		break;
	}
	return;
}

static void _stats_walk_next(const struct dm_stats *dms, uint64_t *flags,
			     uint64_t *cur_r, uint64_t *cur_a, uint64_t *cur_g)
{
	if (!dms || !dms->regions)
		return;

	if (*flags & DM_STATS_WALK_AREA) {
		/* advance to next area, region, or end */
		_stats_walk_next_present(dms, flags, cur_r, cur_a, cur_g);
		return;
	}

	if (*flags & DM_STATS_WALK_REGION) {
		/* enable region aggregation */
		*cur_a = DM_STATS_WALK_REGION;
		_stats_walk_next_present(dms, flags, cur_r, cur_a, cur_g);
		return;
	}

	if (*flags & DM_STATS_WALK_GROUP) {
		/* enable group aggregation */
		*cur_r = *cur_a = DM_STATS_WALK_GROUP;
		while (!_stats_group_id_present(dms, ++(*cur_g))
		       && (*cur_g) < dms->max_region + 1)
			; /* advance to next present group or end */
		return;
	}

	log_error("stats_walk_next called with empty walk flags");
}

static void _group_walk_start(const struct dm_stats *dms, uint64_t *flags,
			      uint64_t *cur_r, uint64_t *cur_a, uint64_t *cur_g)
{
	if (!(*flags & DM_STATS_WALK_GROUP))
		return;

	*cur_a = *cur_r = DM_STATS_WALK_GROUP;
	*cur_g = 0;

	/* advance to next present group or end */
	while ((*cur_g) <= dms->max_region) {
	        if (_stats_region_is_grouped(dms, *cur_g))
			break;
		(*cur_g)++;
	}

	if (*cur_g > dms->max_region)
		/* no groups to walk */
		*flags &= ~DM_STATS_WALK_GROUP;
}

static void _stats_walk_start(const struct dm_stats *dms, uint64_t *flags,
			      uint64_t *cur_r, uint64_t *cur_a,
			      uint64_t *cur_g)
{
	log_debug("starting stats walk with %s %s %s %s",
		  (*flags & DM_STATS_WALK_AREA) ? "AREA" : "",
		  (*flags & DM_STATS_WALK_REGION) ? "REGION" : "",
		  (*flags & DM_STATS_WALK_GROUP) ? "GROUP" : "",
		  (*flags & DM_STATS_WALK_SKIP_SINGLE_AREA) ? "SKIP" : "");

	if (!dms->regions)
		return;

	if (!(*flags & (DM_STATS_WALK_AREA | DM_STATS_WALK_REGION)))
		return _group_walk_start(dms, flags, cur_r, cur_a, cur_g);

	/* initialise cursor state */
	*cur_a = 0;
	*cur_r = DM_STATS_REGION_NOT_PRESENT;
	*cur_g = DM_STATS_GROUP_NOT_PRESENT;

	if (!(*flags & DM_STATS_WALK_AREA))
		*cur_a = DM_STATS_WALK_REGION;

	/* advance to first present, non-skipped region */
	_stats_walk_next_present(dms, flags, cur_r, cur_a, cur_g);
}

#define DM_STATS_WALK_MASK (DM_STATS_WALK_AREA			\
			    | DM_STATS_WALK_REGION		\
			    | DM_STATS_WALK_GROUP		\
			    | DM_STATS_WALK_SKIP_SINGLE_AREA)

int dm_stats_walk_init(struct dm_stats *dms, uint64_t flags)
{
	if (!dms)
		return_0;

	if (flags & ~DM_STATS_WALK_MASK) {
		log_error("Unknown value in walk flags: 0x" FMTx64,
			  (uint64_t) (flags & ~DM_STATS_WALK_MASK));
		return 0;
	}
	dms->walk_flags = flags;
	log_debug("dm_stats_walk_init: initialised flags to " FMTx64, flags);
	return 1;
}

void dm_stats_walk_start(struct dm_stats *dms)
{
	if (!dms || !dms->regions)
		return;

	dms->cur_flags = dms->walk_flags;

	_stats_walk_start(dms, &dms->cur_flags,
			  &dms->cur_region, &dms->cur_area,
			  &dms->cur_group);
}

void dm_stats_walk_next(struct dm_stats *dms)
{
	_stats_walk_next(dms, &dms->cur_flags,
			 &dms->cur_region, &dms->cur_area,
			 &dms->cur_group);
}

void dm_stats_walk_next_region(struct dm_stats *dms)
{
	dms->cur_flags &= ~DM_STATS_WALK_AREA;
	_stats_walk_next(dms, &dms->cur_flags,
			 &dms->cur_region, &dms->cur_area,
			 &dms->cur_group);
}

/*
 * Return 1 if any regions remain that are present and not skipped
 * by the current walk flags or 0 otherwise.
 */
static uint64_t _stats_walk_any_unskipped(const struct dm_stats *dms,
					  uint64_t *flags,
					  uint64_t *cur_r, uint64_t *cur_a)
{
	struct dm_stats_region *region;
	uint64_t i;

	if (*cur_r > dms->max_region)
		return 0;

	for (i = *cur_r; i <= dms->max_region; i++) {
		region = &dms->regions[i];
		if (!_stats_region_present(region))
			continue;
		if ((*flags & DM_STATS_WALK_SKIP_SINGLE_AREA)
		    && !(*flags & DM_STATS_WALK_AREA))
			if (_nr_areas_region(region) < 2)
				continue;
		return 1;
	}
	return 0;
}

static void _stats_walk_end_areas(const struct dm_stats *dms, uint64_t *flags,
				  uint64_t *cur_r, uint64_t *cur_a,
				  uint64_t *cur_g)
{
	int end = !_stats_walk_any_unskipped(dms, flags, cur_r, cur_a);

	if (!(*flags & DM_STATS_WALK_AREA))
		return;

	if (!end)
		return;

	*flags &= ~DM_STATS_WALK_AREA;
	if (*flags & DM_STATS_WALK_REGION) {
		/* start region walk */
		*cur_a = DM_STATS_WALK_REGION;
		*cur_r = DM_STATS_REGION_NOT_PRESENT;
		_stats_walk_next_present(dms, flags, cur_r, cur_a, cur_g);
		if (!_stats_walk_any_unskipped(dms, flags, cur_r, cur_a)) {
			/* no more regions */
			*flags &= ~DM_STATS_WALK_REGION;
			if (!(*flags & DM_STATS_WALK_GROUP))
				*cur_r = dms->max_region;
		}
	}

	if (*flags & DM_STATS_WALK_REGION)
		return;

	if (*flags & DM_STATS_WALK_GROUP)
		_group_walk_start(dms, flags, cur_r, cur_a, cur_g);
}

static int _stats_walk_end(const struct dm_stats *dms, uint64_t *flags,
			   uint64_t *cur_r, uint64_t *cur_a, uint64_t *cur_g)
{
	if (!dms || !dms->regions)
		return 1;

	if (*flags & DM_STATS_WALK_AREA) {
		_stats_walk_end_areas(dms, flags, cur_r, cur_a, cur_g);
		goto out;
	}

	if (*flags & DM_STATS_WALK_REGION) {
		if (!_stats_walk_any_unskipped(dms, flags, cur_r, cur_a)) {
			*flags &= ~DM_STATS_WALK_REGION;
			_group_walk_start(dms, flags, cur_r, cur_a, cur_g);
		}
		goto out;
	}

	if (*flags & DM_STATS_WALK_GROUP) {
		if (*cur_g < dms->max_region)
			goto out;
		*flags &= ~DM_STATS_WALK_GROUP;
	}
out:
	return !(*flags & ~DM_STATS_WALK_SKIP_SINGLE_AREA);
}

int dm_stats_walk_end(struct dm_stats *dms)
{
	if (_stats_walk_end(dms, &dms->cur_flags,
			    &dms->cur_region, &dms->cur_area,
			    &dms->cur_group)) {
		dms->cur_flags = dms->walk_flags;
		return 1;
	}
	return 0;
}

dm_stats_obj_type_t dm_stats_object_type(const struct dm_stats *dms,
					 uint64_t region_id,
					 uint64_t area_id)
{
	uint64_t group_id;

	region_id = (region_id == DM_STATS_REGION_CURRENT)
		     ? dms->cur_region : region_id ;
	area_id = (area_id == DM_STATS_AREA_CURRENT)
		   ? dms->cur_area : area_id ;

	if (region_id == DM_STATS_REGION_NOT_PRESENT)
		/* no region */
		return DM_STATS_OBJECT_TYPE_NONE;

	if (region_id & DM_STATS_WALK_GROUP) {
		if (region_id == DM_STATS_WALK_GROUP)
			/* indirect group_id from cursor */
			group_id = dms->cur_group;
		else
			/* immediate group_id encoded in region_id */
			group_id = region_id & ~DM_STATS_WALK_GROUP;
		if (!_stats_group_id_present(dms, group_id))
			return DM_STATS_OBJECT_TYPE_NONE;
		return DM_STATS_OBJECT_TYPE_GROUP;
	}

	if (region_id > dms->max_region)
		/* end of table */
		return DM_STATS_OBJECT_TYPE_NONE;

	if (area_id & DM_STATS_WALK_REGION)
		/* aggregate region */
		return DM_STATS_OBJECT_TYPE_REGION;

	/* plain region_id and area_id */
	return DM_STATS_OBJECT_TYPE_AREA;
}

dm_stats_obj_type_t dm_stats_current_object_type(const struct dm_stats *dms)
{
	/* dm_stats_object_type will decode region/area */
	return dm_stats_object_type(dms,
				    DM_STATS_REGION_CURRENT,
				    DM_STATS_AREA_CURRENT);
}

uint64_t dm_stats_get_region_nr_areas(const struct dm_stats *dms,
				      uint64_t region_id)
{
	struct dm_stats_region *region = NULL;

	/* groups or aggregate regions cannot be subdivided */
	if (region_id & DM_STATS_WALK_GROUP)
		return 1;

	region = &dms->regions[region_id];
	return _nr_areas_region(region);
}

uint64_t dm_stats_get_current_nr_areas(const struct dm_stats *dms)
{
	/* groups or aggregate regions cannot be subdivided */
	if (dms->cur_region & DM_STATS_WALK_GROUP)
		return 1;

	return dm_stats_get_region_nr_areas(dms, dms->cur_region);
}

uint64_t dm_stats_get_nr_areas(const struct dm_stats *dms)
{
	uint64_t nr_areas = 0, flags = DM_STATS_WALK_AREA;
	/* use a separate cursor */
	uint64_t cur_region = 0, cur_area = 0, cur_group = 0;

	/* no regions to visit? */
	if (!dms->regions)
		return 0;

	flags = DM_STATS_WALK_AREA;
	_stats_walk_start(dms, &flags, &cur_region, &cur_area, &cur_group);
	do {
		nr_areas += dm_stats_get_current_nr_areas(dms);
		_stats_walk_next(dms, &flags,
				 &cur_region, &cur_area,
				 &cur_group);
	} while (!_stats_walk_end(dms, &flags,
				  &cur_region, &cur_area,
				  &cur_group));
	return nr_areas;
}

int dm_stats_group_present(const struct dm_stats *dms, uint64_t group_id)
{
	return _stats_group_id_present(dms, group_id);
}

int dm_stats_get_region_nr_histogram_bins(const struct dm_stats *dms,
					  uint64_t region_id)
{
	region_id = (region_id == DM_STATS_REGION_CURRENT)
		     ? dms->cur_region : region_id ;

	/* FIXME: support group histograms if all region bounds match */
	if (region_id & DM_STATS_WALK_GROUP)
		return 0;

	if (!dms->regions[region_id].bounds)
		return 0;

	return dms->regions[region_id].bounds->nr_bins;
}

/*
 * Fill buf with a list of set regions in the regions bitmap. Consecutive
 * ranges of set region IDs are output using "M-N" range notation.
 *
 * The number of bytes consumed is returned or zero on error.
 */
static size_t _stats_group_tag_fill(const struct dm_stats *dms,
				    dm_bitset_t regions,
				    char *buf, size_t buflen)
{
	int i, j, r, next, last = 0;
	size_t used = 0;

	i = dm_bit_get_first(regions);
	for (; i >= 0; i = dm_bit_get_next(regions, i))
		last = i;

	i = dm_bit_get_first(regions);
	for(; i >= 0; i = dm_bit_get_next(regions, i)) {
		/* find range end */
		j = i;
		do
			next = j + 1;
		while ((j = dm_bit_get_next(regions, j)) == next);

		/* set to last set bit */
		j = next - 1;

		/* handle range vs. single region */
		if (i != j)
			r = dm_snprintf(buf, buflen, FMTu64 "-" FMTu64 "%s",
					(uint64_t) i, (uint64_t) j,
					(j == last) ? "" : ",");
		else
			r = dm_snprintf(buf, buflen, FMTu64 "%s", (uint64_t) i,
					(i == last) ? "" : ",");
		if (r < 0)
			goto_bad;

		i = next; /* skip handled bits if in range */

		buf += r;
		used += r;
	}

	return used;
bad:
	log_error("Could not format group list.");
	return 0;
}

/*
 * Calculate the space required to hold a string description of the group
 * described by the regions bitset using comma separated list in range
 * notation ("A,B,C,M-N").
 */
static size_t _stats_group_tag_len(const struct dm_stats *dms,
				   dm_bitset_t regions)
{
	int i, j, next, nr_regions = 0;
	size_t buflen = 0, id_len = 0;

	/* check region ids and find last set bit */
	i = dm_bit_get_first(regions);
	for (; i >= 0; i = dm_bit_get_next(regions, i)) {
		if (!dm_stats_region_present(dms, i)) {
			log_error("Region identifier %d not found", i);
			return 0;
		}

		/* length of region_id or range start in characters */
		id_len = (i) ? 1 + (size_t) log10(i) : 1;
		buflen += id_len;
		j = i;
		do
			next = j + 1;
		while ((j = dm_bit_get_next(regions, j)) == next);

		/* set to last set bit */
		j = next - 1;

		nr_regions += j - i + 1;

		/* handle range */
		if (i != j) {
			/* j is always > i, which is always >= 0 */
			id_len = 1 + (size_t) log10(j);
			buflen += id_len + 1; /* range end plus "-" */
		}
		buflen++;
		i = next; /* skip bits if handling range */
	}
	return buflen;
}

/*
 * Build a DMS_GROUP="..." tag for the group specified by group_id,
 * to be stored in the corresponding region's aux_data field.
 */
static char *_build_group_tag(struct dm_stats *dms, uint64_t group_id)
{
	char *aux_string, *buf;
	dm_bitset_t regions;
	const char *alias;
	size_t buflen = 0;
	int r;

	regions = dms->groups[group_id].regions;
	alias = dms->groups[group_id].alias;

	buflen = _stats_group_tag_len(dms, regions);

	if (!buflen)
		return_0;

	buflen += DMS_GROUP_TAG_LEN;
	buflen += 1 + (alias ? strlen(alias) : 0); /* 'alias:' */

	buf = aux_string = dm_malloc(buflen);
	if (!buf) {
		log_error("Could not allocate memory for aux_data string.");
		return NULL;
	}

	if (!dm_strncpy(buf, DMS_GROUP_TAG, DMS_GROUP_TAG_LEN + 1))
		goto_bad;

	buf += DMS_GROUP_TAG_LEN;
	buflen -= DMS_GROUP_TAG_LEN;

	r = dm_snprintf(buf, buflen, "%s%c", alias ? alias : "", DMS_GROUP_SEP);
	if (r < 0)
		goto_bad;

	buf += r;
	buflen -= r;

	r = _stats_group_tag_fill(dms, regions, buf, buflen);
	if (!r)
		goto_bad;

	return aux_string;
bad:
	log_error("Could not format group aux_data.");
	dm_free(aux_string);
	return NULL;
}

/*
 * Store updated aux_data for a region. The aux_data is passed to the
 * kernel using the @stats_set_aux message. Any required group tag is
 * generated from the current group table and included in the message.
 */
static int _stats_set_aux(struct dm_stats *dms,
			  uint64_t region_id, const char *aux_data)
{
	const char *group_tag = NULL;
	struct dm_task *dmt = NULL;
	char msg[STATS_MSG_BUF_LEN];

	/* group data required? */
	if (_stats_group_id_present(dms, region_id)) {
		group_tag = _build_group_tag(dms, region_id);
		if (!group_tag) {
			log_error("Could not build group descriptor for "
				  "region ID " FMTu64, region_id);
			goto_bad;
		}
	}

	if (!dm_snprintf(msg, sizeof(msg), "@stats_set_aux " FMTu64 " %s%s%s ",
			 region_id, (group_tag) ? group_tag : "",
			 (group_tag) ? DMS_AUX_SEP : "",
			 (strlen(aux_data)) ? aux_data : "-")) {
		log_error("Could not prepare @stats_set_aux message");
		goto bad;
	}

	if (!(dmt = _stats_send_message(dms, msg)))
		goto_bad;

	dm_free((char *) group_tag);

	/* no response to a @stats_set_aux message */
	dm_task_destroy(dmt);

	return 1;
bad:
	dm_free((char *) group_tag);
	return 0;
}

/*
 * Maximum length of a "start+end" range string:
 * Two 20 digit uint64_t, '+', and NULL.
 */
#define RANGE_LEN 42
static int _stats_create_region(struct dm_stats *dms, uint64_t *region_id,
				uint64_t start, uint64_t len, int64_t step,
				int precise, const char *hist_arg,
				const char *program_id,	const char *aux_data)
{
	char msg[STATS_MSG_BUF_LEN], range[RANGE_LEN], *endptr = NULL;
	const char *err_fmt = "Could not prepare @stats_create %s.";
	const char *precise_str = PRECISE_ARG;
	const char *resp, *opt_args = NULL;
	struct dm_task *dmt = NULL;
	int r = 0, nr_opt = 0;

	if (!_stats_bound(dms))
		return_0;

	if (!program_id || !strlen(program_id))
		program_id = dms->program_id;

	if (start || len) {
		if (!dm_snprintf(range, sizeof(range), FMTu64 "+" FMTu64,
				 start, len)) {
			log_error(err_fmt, "range");
			return 0;
		}
	}

	if (precise < 0)
		precise = dms->precise;

	if (precise)
		nr_opt++;
	else
		precise_str = "";

	if (hist_arg)
		nr_opt++;
	else
		hist_arg = "";

	if (nr_opt) {
		if ((dm_asprintf((char **)&opt_args, "%d %s %s%s", nr_opt,
				 precise_str,
				 (strlen(hist_arg)) ? HISTOGRAM_ARG : "",
				 hist_arg)) < 0) {
			log_error(err_fmt, PRECISE_ARG " option.");
			return 0;
		}
	} else
		opt_args = dm_strdup("");

	if (!dm_snprintf(msg, sizeof(msg), "@stats_create %s %s" FMTu64
			 " %s %s %s", (start || len) ? range : "-",
			 (step < 0) ? "/" : "",
			 (uint64_t)llabs(step),
			 opt_args, program_id, aux_data)) {
		log_error(err_fmt, "message");
		dm_free((void *) opt_args);
		return 0;
	}

	if (!(dmt = _stats_send_message(dms, msg)))
		goto_out;

	resp = dm_task_get_message_response(dmt);
	if (!resp) {
		log_error("Could not parse empty @stats_create response.");
		goto out;
	}

	if (region_id) {
		*region_id = strtoull(resp, &endptr, 10);
		if (resp == endptr)
			goto_out;
	}

	r = 1;

out:
	if (dmt)
		dm_task_destroy(dmt);
	dm_free((void *) opt_args);

	return r;
}

int dm_stats_create_region(struct dm_stats *dms, uint64_t *region_id,
			   uint64_t start, uint64_t len, int64_t step,
			   int precise, struct dm_histogram *bounds,
			   const char *program_id, const char *user_data)
{
	char *hist_arg = NULL;
	int r = 0;

	/* Nanosecond counters and histograms both need precise_timestamps. */
	if ((precise || bounds) && !_stats_check_precise_timestamps(dms))
		return_0;

	if (bounds) {
		/* _build_histogram_arg enables precise if vals < 1ms. */
		if (!(hist_arg = _build_histogram_arg(bounds, &precise)))
			goto_out;
	}

	r = _stats_create_region(dms, region_id, start, len, step,
				 precise, hist_arg, program_id, user_data);
	dm_free(hist_arg);

out:
	return r;
}

static void _stats_clear_group_regions(struct dm_stats *dms, uint64_t group_id)
{
	struct dm_stats_group *group;
	uint64_t i;

	group = &dms->groups[group_id];
	for (i = dm_bit_get_first(group->regions);
	     i != DM_STATS_GROUP_NOT_PRESENT;
	     i = dm_bit_get_next(group->regions, i))
		dms->regions[i].group_id = DM_STATS_GROUP_NOT_PRESENT;
}

static int _stats_remove_region_id_from_group(struct dm_stats *dms,
					      uint64_t region_id)
{
	struct dm_stats_region *region = &dms->regions[region_id];
	uint64_t group_id = region->group_id;
	dm_bitset_t regions = dms->groups[group_id].regions;

	if (!_stats_region_is_grouped(dms, region_id))
		return_0;

	dm_bit_clear(regions, region_id);

	/* removing group leader? */
	if (region_id == group_id) {
		_stats_clear_group_regions(dms, group_id);
		_stats_group_destroy(&dms->groups[group_id]);
	}

	return _stats_set_aux(dms, group_id, dms->regions[group_id].aux_data);
}

int dm_stats_delete_region(struct dm_stats *dms, uint64_t region_id)
{
	char msg[STATS_MSG_BUF_LEN];
	struct dm_task *dmt;

	if (!_stats_bound(dms))
		return_0;

	if (!dms->regions && !dm_stats_list(dms, dms->program_id)) {
		log_error("Could not obtain region list while deleting "
			  "region ID " FMTu64, region_id);
		return 0;
	}

	if (!dm_stats_get_nr_areas(dms)) {
		log_error("Could not delete region ID " FMTu64 ": "
			  "no regions found", region_id);
		return 0;
	}

	/* includes invalid and special region_id values */
	if (!dm_stats_region_present(dms, region_id)) {
		log_error("Region ID " FMTu64 " does not exist", region_id);
		return 0;
	}

	if(_stats_region_is_grouped(dms, region_id))
		if (!_stats_remove_region_id_from_group(dms, region_id)) {
			log_error("Could not remove region ID " FMTu64 " from "
				  "group ID " FMTu64,
				  region_id, dms->regions[region_id].group_id);
			return 0;
		}

	if (!dm_snprintf(msg, sizeof(msg), "@stats_delete " FMTu64, region_id)) {
		log_error("Could not prepare @stats_delete message.");
		return 0;
	}

	dmt = _stats_send_message(dms, msg);
	if (!dmt)
		return_0;
	dm_task_destroy(dmt);

	/* wipe region and mark as not present */
	_stats_region_destroy(&dms->regions[region_id]);

	return 1;
}

int dm_stats_clear_region(struct dm_stats *dms, uint64_t region_id)
{
	char msg[STATS_MSG_BUF_LEN];
	struct dm_task *dmt;

	if (!_stats_bound(dms))
		return_0;

	if (!dm_snprintf(msg, sizeof(msg), "@stats_clear " FMTu64, region_id)) {
		log_error("Could not prepare @stats_clear message.");
		return 0;
	}

	dmt = _stats_send_message(dms, msg);

	if (!dmt)
		return_0;

	dm_task_destroy(dmt);

	return 1;
}

static struct dm_task *_stats_print_region(struct dm_stats *dms,
				    uint64_t region_id, unsigned start_line,
				    unsigned num_lines, unsigned clear)
{
	/* @stats_print[_clear] <region_id> [<start_line> <num_lines>] */
	const char *err_fmt = "Could not prepare @stats_print %s.";
	char msg[STATS_MSG_BUF_LEN], lines[RANGE_LEN];
	struct dm_task *dmt = NULL;

	if (start_line || num_lines)
		if (!dm_snprintf(lines, sizeof(lines),
				 "%u %u", start_line, num_lines)) {
			log_error(err_fmt, "row specification");
			return NULL;
		}

	if (!dm_snprintf(msg, sizeof(msg), "@stats_print%s " FMTu64 " %s",
			 (clear) ? "_clear" : "",
			 region_id, (start_line || num_lines) ? lines : "")) {
		log_error(err_fmt, "message");
		return NULL;
	}

	if (!(dmt = _stats_send_message(dms, msg)))
		return_NULL;

	return dmt;
}

char *dm_stats_print_region(struct dm_stats *dms, uint64_t region_id,
			    unsigned start_line, unsigned num_lines,
			    unsigned clear)
{
	char *resp = NULL;
	struct dm_task *dmt = NULL;
	const char *response;

	if (!_stats_bound(dms))
		return_0;

	/*
	 * FIXME: 'print' can be emulated for groups or aggregate regions
	 * by populating the handle and emitting aggregate counter data
	 * in the kernel print format.
	 */
	if (region_id == DM_STATS_WALK_GROUP)
		return_0;

	dmt = _stats_print_region(dms, region_id,
				  start_line, num_lines, clear);

	if (!dmt)
		return_0;

	if (!(response = dm_task_get_message_response(dmt)))
		goto_out;

	if (!(resp = dm_pool_strdup(dms->mem, response)))
		log_error("Could not allocate memory for response buffer.");
out:
	dm_task_destroy(dmt);

	return resp;
}

void dm_stats_buffer_destroy(struct dm_stats *dms, char *buffer)
{
	dm_pool_free(dms->mem, buffer);
}

uint64_t dm_stats_get_nr_regions(const struct dm_stats *dms)
{
	if (!dms)
		return_0;

	if (!dms->regions)
		return 0;

	return dms->nr_regions;
}

uint64_t dm_stats_get_nr_groups(const struct dm_stats *dms)
{
	uint64_t group_id, nr_groups = 0;

	if (!dms)
		return_0;

	/* no regions or groups? */
	if (!dms->regions || !dms->groups)
		return 0;

	for (group_id = 0; group_id <= dms->max_region; group_id++)
		if (dms->groups[group_id].group_id
		    != DM_STATS_GROUP_NOT_PRESENT)
			nr_groups++;

	return nr_groups;
}

/**
 * Test whether region_id is present in this set of stats data.
 */
int dm_stats_region_present(const struct dm_stats *dms, uint64_t region_id)
{
	if (!dms->regions)
		return_0;

	if (region_id > dms->max_region)
		return 0;

	return _stats_region_present(&dms->regions[region_id]);
}

static int _dm_stats_populate_region(struct dm_stats *dms, uint64_t region_id,
				     const char *resp)
{
	struct dm_stats_region *region = &dms->regions[region_id];

	if (!_stats_bound(dms))
		return_0;

	if (!region || !_stats_parse_region(dms, resp, region, region->timescale)) {
		log_error("Could not parse @stats_print message response.");
		return 0;
	}
	region->region_id = region_id;
	return 1;
}

int dm_stats_populate(struct dm_stats *dms, const char *program_id,
		      uint64_t region_id)
{
	int all_regions = (region_id == DM_STATS_REGIONS_ALL);
	struct dm_task *dmt = NULL; /* @stats_print task */
	uint64_t saved_flags; /* saved walk flags */
	const char *resp;

	/*
	 * We are about do destroy and re-create the region table, so it
	 * is safe to use the cursor embedded in the stats handle: just
	 * save a copy of the current walk_flags to restore later.
	 */
	saved_flags = dms->walk_flags;

	if (!_stats_bound(dms))
		return_0;

	if ((!all_regions) && (region_id & DM_STATS_WALK_GROUP)) {
		log_error("Invalid region_id for dm_stats_populate: "
			  "DM_STATS_WALK_GROUP");
		return 0;
	}

	/* allow zero-length program_id for populate */
	if (!program_id)
		program_id = dms->program_id;

	if (all_regions && !dm_stats_list(dms, program_id)) {
		log_error("Could not parse @stats_list response.");
		goto bad;
	} else if (!_stats_set_name_cache(dms)) {
		goto_bad;
	}

	/* successful list but no regions registered */
	if (!dms->nr_regions)
		return 0;

	dms->walk_flags = DM_STATS_WALK_REGION;
	dm_stats_walk_start(dms);
	do {
		region_id = (all_regions)
			     ? dm_stats_get_current_region(dms) : region_id;

		/* obtain all lines and clear counter values */
		if (!(dmt = _stats_print_region(dms, region_id, 0, 0, 1)))
			goto_bad;

		resp = dm_task_get_message_response(dmt);
		if (!_dm_stats_populate_region(dms, region_id, resp)) {
			dm_task_destroy(dmt);
			goto_bad;
		}

		dm_task_destroy(dmt);
		dm_stats_walk_next(dms);

	} while (all_regions && !dm_stats_walk_end(dms));

	dms->walk_flags = saved_flags;
	return 1;

bad:
	dms->walk_flags = saved_flags;
	_stats_regions_destroy(dms);
	dms->regions = NULL;
	return 0;
}

/**
 * destroy a dm_stats object and all associated regions and counter sets.
 */
void dm_stats_destroy(struct dm_stats *dms)
{
	_stats_regions_destroy(dms);
	_stats_groups_destroy(dms);
	_stats_clear_binding(dms);
	dm_pool_destroy(dms->mem);
	dm_pool_destroy(dms->hist_mem);
	dm_pool_destroy(dms->group_mem);
	dm_free(dms->program_id);
	dm_free((char *) dms->name);
	dm_free(dms);
}

/*
 * Walk each area that is a member of region_id rid.
 * i is a variable of type int that holds the current area_id.
 */
#define _foreach_region_area(dms, rid, i)				\
for ((i) = 0; (i) < _nr_areas_region(&dms->regions[(rid)]); (i)++)	\

/*
 * Walk each region that is a member of group_id gid.
 * i is a variable of type int that holds the current region_id.
 */
#define _foreach_group_region(dms, gid, i)			\
for ((i) = dm_bit_get_first((dms)->groups[(gid)].regions);	\
     (i) != DM_STATS_GROUP_NOT_PRESENT;				\
     (i) = dm_bit_get_next((dms)->groups[(gid)].regions, (i)))	\

/*
 * Walk each region that is a member of group_id gid visiting each
 * area within the region.
 * i is a variable of type int that holds the current region_id.
 * j is a variable of type int variable that holds the current area_id.
 */
#define _foreach_group_area(dms, gid, i, j)			\
_foreach_group_region(dms, gid, i)				\
	_foreach_region_area(dms, i, j)

static uint64_t _stats_get_counter(const struct dm_stats *dms,
				   const struct dm_stats_counters *area,
				   dm_stats_counter_t counter)
{
	switch(counter) {
	case DM_STATS_READS_COUNT:
		return area->reads;
	case DM_STATS_READS_MERGED_COUNT:
		return area->reads_merged;
	case DM_STATS_READ_SECTORS_COUNT:
		return area->read_sectors;
	case DM_STATS_READ_NSECS:
		return area->read_nsecs;
	case DM_STATS_WRITES_COUNT:
		return area->writes;
	case DM_STATS_WRITES_MERGED_COUNT:
		return area->writes_merged;
	case DM_STATS_WRITE_SECTORS_COUNT:
		return area->write_sectors;
	case DM_STATS_WRITE_NSECS:
		return area->write_nsecs;
	case DM_STATS_IO_IN_PROGRESS_COUNT:
		return area->io_in_progress;
	case DM_STATS_IO_NSECS:
		return area->io_nsecs;
	case DM_STATS_WEIGHTED_IO_NSECS:
		return area->weighted_io_nsecs;
	case DM_STATS_TOTAL_READ_NSECS:
		return area->total_read_nsecs;
	case DM_STATS_TOTAL_WRITE_NSECS:
		return area->total_write_nsecs;
	case DM_STATS_NR_COUNTERS:
	default:
		log_error("Attempt to read invalid counter: %d", counter);
	}
	return 0;
}

uint64_t dm_stats_get_counter(const struct dm_stats *dms,
			      dm_stats_counter_t counter,
			      uint64_t region_id, uint64_t area_id)
{
	uint64_t i, j, sum = 0; /* aggregation */
	int sum_regions = 0;
	struct dm_stats_region *region;
	struct dm_stats_counters *area;

	region_id = (region_id == DM_STATS_REGION_CURRENT)
		     ? dms->cur_region : region_id ;
	area_id = (area_id == DM_STATS_REGION_CURRENT)
		   ? dms->cur_area : area_id ;

	sum_regions = !!(region_id & DM_STATS_WALK_GROUP);

	if (region_id == DM_STATS_WALK_GROUP)
		/* group walk using the cursor */
		region_id = dms->cur_group;
	else if (region_id & DM_STATS_WALK_GROUP)
		/* group walk using immediate group_id */
		region_id &= ~DM_STATS_WALK_GROUP;
	region = &dms->regions[region_id];

	/*
	 * All statistics aggregation takes place here: aggregate metrics
	 * are calculated as normal using the aggregated counter values
	 * returned for the region or group specified.
	 */

	if (_stats_region_is_grouped(dms, region_id) && (sum_regions)) {
		/* group */
		if (area_id & DM_STATS_WALK_GROUP)
			_foreach_group_area(dms, region->group_id, i, j) {
				area = &dms->regions[i].counters[j];
				sum += _stats_get_counter(dms, area, counter);
			}
		else
			_foreach_group_region(dms, region->group_id, i) {
				area = &dms->regions[i].counters[area_id];
				sum += _stats_get_counter(dms, area, counter);
			}
	} else if (area_id == DM_STATS_WALK_REGION) {
		/* aggregate region */
		_foreach_region_area(dms, region_id, j) {
			area = &dms->regions[region_id].counters[j];
			sum += _stats_get_counter(dms, area, counter);
		}
	} else {
		/* plain region / area */
		area = &region->counters[area_id];
		sum = _stats_get_counter(dms, area, counter);
	}

	return sum;
}

/*
 * Methods for accessing named counter fields. All methods share the
 * following naming scheme and prototype:
 *
 * uint64_t dm_stats_get_COUNTER(const struct dm_stats *, uint64_t, uint64_t)
 *
 * Where the two integer arguments are the region_id and area_id
 * respectively.
 *
 * name is the name of the counter (lower case)
 * counter is the part of the enum name following DM_STATS_ (upper case)
 */
#define MK_STATS_GET_COUNTER_FN(name, counter)				\
uint64_t dm_stats_get_ ## name(const struct dm_stats *dms,		\
			       uint64_t region_id, uint64_t area_id)	\
{									\
	return dm_stats_get_counter(dms, DM_STATS_ ## counter,		\
				    region_id, area_id);		\
}

MK_STATS_GET_COUNTER_FN(reads, READS_COUNT)
MK_STATS_GET_COUNTER_FN(reads_merged, READS_MERGED_COUNT)
MK_STATS_GET_COUNTER_FN(read_sectors, READ_SECTORS_COUNT)
MK_STATS_GET_COUNTER_FN(read_nsecs, READ_NSECS)
MK_STATS_GET_COUNTER_FN(writes, WRITES_COUNT)
MK_STATS_GET_COUNTER_FN(writes_merged, WRITES_MERGED_COUNT)
MK_STATS_GET_COUNTER_FN(write_sectors, WRITE_SECTORS_COUNT)
MK_STATS_GET_COUNTER_FN(write_nsecs, WRITE_NSECS)
MK_STATS_GET_COUNTER_FN(io_in_progress, IO_IN_PROGRESS_COUNT)
MK_STATS_GET_COUNTER_FN(io_nsecs, IO_NSECS)
MK_STATS_GET_COUNTER_FN(weighted_io_nsecs, WEIGHTED_IO_NSECS)
MK_STATS_GET_COUNTER_FN(total_read_nsecs, TOTAL_READ_NSECS)
MK_STATS_GET_COUNTER_FN(total_write_nsecs, TOTAL_WRITE_NSECS)
#undef MK_STATS_GET_COUNTER_FN

/*
 * Floating point stats metric functions
 *
 * Called from dm_stats_get_metric() to calculate the value of
 * the requested metric.
 *
 * int _metric_name(const struct dm_stats *dms,
 * 		    struct dm_stats_counters *c,
 * 		    double *value);
 *
 * Calculate a metric value from the counter data for the given
 * identifiers and store it in the memory pointed to by value,
 * applying group or region aggregation if enabled.
 *
 * Return one on success or zero on failure.
 *
 * To add a new metric:
 *
 * o Add a new name to the dm_stats_metric_t enum.
 * o Create a _metric_fn() to calculate the new metric.
 * o Add _metric_fn to the _metrics function table
 *   (entries in enum order).
 * o Do not add a new named public function for the metric -
 *   users of new metrics are encouraged to convert to the enum
 *   based metric interface.
 *
 */

static int _rd_merges_per_sec(const struct dm_stats *dms, double *rrqm,
			      uint64_t region_id, uint64_t area_id)
{
	double mrgs;
	mrgs = (double) dm_stats_get_counter(dms, DM_STATS_READS_MERGED_COUNT,
					     region_id, area_id);

	*rrqm = mrgs / (double) dms->interval_ns;

	return 1;
}

static int _wr_merges_per_sec(const struct dm_stats *dms, double *wrqm,
			      uint64_t region_id, uint64_t area_id)
{
	double mrgs;
	mrgs = (double) dm_stats_get_counter(dms, DM_STATS_WRITES_MERGED_COUNT,
					     region_id, area_id);

	*wrqm = mrgs / (double) dms->interval_ns;

	return 1;
}

static int _reads_per_sec(const struct dm_stats *dms, double *rd_s,
			  uint64_t region_id, uint64_t area_id)
{
	double reads;
	reads = (double) dm_stats_get_counter(dms, DM_STATS_READS_COUNT,
					      region_id, area_id);

	*rd_s = (reads * NSEC_PER_SEC) / (double) dms->interval_ns;

	return 1;
}

static int _writes_per_sec(const struct dm_stats *dms, double *wr_s,
			   uint64_t region_id, uint64_t area_id)
{
	double writes;
	writes = (double) dm_stats_get_counter(dms, DM_STATS_WRITES_COUNT,
					       region_id, area_id);

	*wr_s = (writes * NSEC_PER_SEC) / (double) dms->interval_ns;

	return 1;
}

static int _read_sectors_per_sec(const struct dm_stats *dms, double *rsec_s,
				 uint64_t region_id, uint64_t area_id)
{
	double sect;
	sect = (double) dm_stats_get_counter(dms, DM_STATS_READ_SECTORS_COUNT,
					     region_id, area_id);

	*rsec_s = (sect * (double) NSEC_PER_SEC) / (double) dms->interval_ns;

	return 1;
}

static int _write_sectors_per_sec(const struct dm_stats *dms, double *wsec_s,
				  uint64_t region_id, uint64_t area_id)
{
	double sect;
	sect = (double) dm_stats_get_counter(dms, DM_STATS_WRITE_SECTORS_COUNT,
					     region_id, area_id);

	*wsec_s = (sect * (double) NSEC_PER_SEC) / (double) dms->interval_ns;

	return 1;
}

static int _average_request_size(const struct dm_stats *dms, double *arqsz,
				 uint64_t region_id, uint64_t area_id)
{
	double ios, sectors;

	ios = (double) (dm_stats_get_counter(dms, DM_STATS_READS_COUNT,
					     region_id, area_id)
			+ dm_stats_get_counter(dms, DM_STATS_WRITES_COUNT,
					       region_id, area_id));
	sectors = (double) (dm_stats_get_counter(dms, DM_STATS_READ_SECTORS_COUNT,
						 region_id, area_id)
			    + dm_stats_get_counter(dms, DM_STATS_WRITE_SECTORS_COUNT,
						   region_id, area_id));

	if (ios > 0.0)
		*arqsz = sectors / ios;
	else
		*arqsz = 0.0;

	return 1;
}

static int _average_queue_size(const struct dm_stats *dms, double *qusz,
			       uint64_t region_id, uint64_t area_id)
{
	double io_ticks;
	io_ticks = (double) dm_stats_get_counter(dms, DM_STATS_WEIGHTED_IO_NSECS,
						 region_id, area_id);

	if (io_ticks > 0.0)
		*qusz = io_ticks / (double) dms->interval_ns;
	else
		*qusz = 0.0;

	return 1;
}

static int _average_wait_time(const struct dm_stats *dms, double *await,
			      uint64_t region_id, uint64_t area_id)
{
	uint64_t io_ticks, nr_ios;

	io_ticks = dm_stats_get_counter(dms, DM_STATS_READ_NSECS,
					region_id, area_id);
	io_ticks += dm_stats_get_counter(dms, DM_STATS_WRITE_NSECS,
					 region_id, area_id);

	nr_ios = dm_stats_get_counter(dms, DM_STATS_READS_COUNT,
				      region_id, area_id);
	nr_ios += dm_stats_get_counter(dms, DM_STATS_WRITES_COUNT,
				       region_id, area_id);

	if (nr_ios > 0)
		*await = (double) io_ticks / (double) nr_ios;
	else
		*await = 0.0;

	return 1;
}

static int _average_rd_wait_time(const struct dm_stats *dms, double *await,
				 uint64_t region_id, uint64_t area_id)
{
	uint64_t rd_io_ticks, nr_rd_ios;

	rd_io_ticks = dm_stats_get_counter(dms, DM_STATS_READ_NSECS,
					   region_id, area_id);
	nr_rd_ios = dm_stats_get_counter(dms, DM_STATS_READS_COUNT,
					 region_id, area_id);

	/*
	 * If rd_io_ticks is > 0 this should imply that nr_rd_ios is
	 * also > 0 (unless a kernel bug exists). Test for both here
	 * before using the IO count as a divisor (Coverity).
	 */
	if (rd_io_ticks > 0 && nr_rd_ios > 0)
		*await = (double) rd_io_ticks / (double) nr_rd_ios;
	else
		*await = 0.0;

	return 1;
}

static int _average_wr_wait_time(const struct dm_stats *dms, double *await,
				 uint64_t region_id, uint64_t area_id)
{
	uint64_t wr_io_ticks, nr_wr_ios;

	wr_io_ticks = dm_stats_get_counter(dms, DM_STATS_WRITE_NSECS,
					   region_id, area_id);
	nr_wr_ios = dm_stats_get_counter(dms, DM_STATS_WRITES_COUNT,
					 region_id, area_id);

	/*
	 * If wr_io_ticks is > 0 this should imply that nr_wr_ios is
	 * also > 0 (unless a kernel bug exists). Test for both here
	 * before using the IO count as a divisor (Coverity).
	 */
	if (wr_io_ticks > 0 && nr_wr_ios > 0)
		*await = (double) wr_io_ticks / (double) nr_wr_ios;
	else
		*await = 0.0;

	return 1;
}

static int _throughput(const struct dm_stats *dms, double *tput,
		       uint64_t region_id, uint64_t area_id)
{
	uint64_t nr_ios;

	nr_ios = dm_stats_get_counter(dms, DM_STATS_READS_COUNT,
				      region_id, area_id);
	nr_ios += dm_stats_get_counter(dms, DM_STATS_WRITES_COUNT,
				       region_id, area_id);

	*tput = ((double) NSEC_PER_SEC * (double) nr_ios)
		/ (double) (dms->interval_ns);

	return 1;
}

static int _utilization(const struct dm_stats *dms, double *util,
			uint64_t region_id, uint64_t area_id)
{
	uint64_t io_nsecs, interval_ns = dms->interval_ns;

	/**
	 * If io_nsec > interval_ns there is something wrong with the clock
	 * for the last interval; do not allow a value > 100% utilization
	 * to be passed to a dm_make_percent() call. We expect to see these
	 * at startup if counters have not been cleared before the first read.
	 *
	 * A zero interval_ns is also an error since metrics cannot be
	 * calculated without a defined interval - return zero and emit a
	 * backtrace in this case.
	 */
	io_nsecs = dm_stats_get_counter(dms, DM_STATS_IO_NSECS,
					region_id, area_id);

	if (!interval_ns) {
		*util = 0.0;
		return_0;
	}

	io_nsecs = ((io_nsecs < interval_ns) ? io_nsecs : interval_ns);

	*util = (double) io_nsecs / (double) interval_ns;

	return 1;
}

static int _service_time(const struct dm_stats *dms, double *svctm,
			 uint64_t region_id, uint64_t area_id)
{
	double tput, util;

	if (!_throughput(dms, &tput, region_id, area_id))
		return 0;

	if (!_utilization(dms, &util, region_id, area_id))
		return 0;

	util *= 100;

	/* avoid NAN with zero counter values */
	if ( (uint64_t) tput == 0 || (uint64_t) util == 0) {
		*svctm = 0.0;
		return 1;
	}

	*svctm = ((double) NSEC_PER_SEC * dm_percent_to_float(util))
		  / (100.0 * tput);

	return 1;
}

/*
 * Table in enum order:
 *      DM_STATS_RD_MERGES_PER_SEC,
 *      DM_STATS_WR_MERGES_PER_SEC,
 *      DM_STATS_READS_PER_SEC,
 *      DM_STATS_WRITES_PER_SEC,
 *      DM_STATS_READ_SECTORS_PER_SEC,
 *      DM_STATS_WRITE_SECTORS_PER_SEC,
 *      DM_STATS_AVERAGE_REQUEST_SIZE,
 *      DM_STATS_AVERAGE_QUEUE_SIZE,
 *      DM_STATS_AVERAGE_WAIT_TIME,
 *      DM_STATS_AVERAGE_RD_WAIT_TIME,
 *      DM_STATS_AVERAGE_WR_WAIT_TIME
 *      DM_STATS_SERVICE_TIME,
 *      DM_STATS_THROUGHPUT,
 *      DM_STATS_UTILIZATION
 *
*/

typedef int (*_metric_fn_t)(const struct dm_stats *, double *,
			    uint64_t, uint64_t);

_metric_fn_t _metrics[DM_STATS_NR_METRICS] = {
	_rd_merges_per_sec,
	_wr_merges_per_sec,
	_reads_per_sec,
	_writes_per_sec,
	_read_sectors_per_sec,
	_write_sectors_per_sec,
	_average_request_size,
	_average_queue_size,
	_average_wait_time,
	_average_rd_wait_time,
	_average_wr_wait_time,
	_service_time,
	_throughput,
	_utilization
};

int dm_stats_get_metric(const struct dm_stats *dms, int metric,
			uint64_t region_id, uint64_t area_id, double *value)
{
	if (!dms->interval_ns)
		return_0;

	/*
	 * Decode DM_STATS_{REGION,AREA}_CURRENT here; counters will then
	 * be returned for the actual current region and area.
	 *
	 * DM_STATS_WALK_GROUP is passed through to the counter methods -
	 * aggregates for the group are returned and used to calculate
	 * the metric for the group totals.
	 */
	region_id = (region_id == DM_STATS_REGION_CURRENT)
		     ? dms->cur_region : region_id ;
	area_id = (area_id == DM_STATS_REGION_CURRENT)
		   ? dms->cur_area : area_id ;

	if (metric < 0 || metric >= DM_STATS_NR_METRICS) {
		log_error("Attempt to read invalid metric: %d", metric);
		return 0;
	}

	return _metrics[metric](dms, value, region_id, area_id);
}

/**
 * Methods for accessing stats metrics. All methods share the
 * following naming scheme and prototype:
 *
 * uint64_t dm_stats_get_metric(struct dm_stats *,
 * 				int, int,
 * 				uint64_t, uint64_t,
 * 				double *v)
 *
 * Where the two integer arguments are the region_id and area_id
 * respectively.
 *
 * name is the name of the metric (lower case)
 * metric is the part of the enum name following DM_STATS_ (upper case)
 */
#define MK_STATS_GET_METRIC_FN(name, metric, meta)			\
int dm_stats_get_ ## name(const struct dm_stats *dms, double *meta,	\
			  uint64_t region_id, uint64_t area_id)		\
{									\
	return dm_stats_get_metric(dms, DM_STATS_ ## metric, 		\
				   region_id, area_id, meta);		\
}

MK_STATS_GET_METRIC_FN(rd_merges_per_sec, RD_MERGES_PER_SEC, rrqm)
MK_STATS_GET_METRIC_FN(wr_merges_per_sec, WR_MERGES_PER_SEC, wrqm)
MK_STATS_GET_METRIC_FN(reads_per_sec, READS_PER_SEC, rd_s)
MK_STATS_GET_METRIC_FN(writes_per_sec, WRITES_PER_SEC, wr_s)
MK_STATS_GET_METRIC_FN(read_sectors_per_sec, READ_SECTORS_PER_SEC, rsec_s)
MK_STATS_GET_METRIC_FN(write_sectors_per_sec, WRITE_SECTORS_PER_SEC, wsec_s)
MK_STATS_GET_METRIC_FN(average_request_size, AVERAGE_REQUEST_SIZE, arqsz)
MK_STATS_GET_METRIC_FN(average_queue_size, AVERAGE_QUEUE_SIZE, qusz)
MK_STATS_GET_METRIC_FN(average_wait_time, AVERAGE_WAIT_TIME, await)
MK_STATS_GET_METRIC_FN(average_rd_wait_time, AVERAGE_RD_WAIT_TIME, await)
MK_STATS_GET_METRIC_FN(average_wr_wait_time, AVERAGE_WR_WAIT_TIME, await)
MK_STATS_GET_METRIC_FN(service_time, SERVICE_TIME, svctm)
MK_STATS_GET_METRIC_FN(throughput, THROUGHPUT, tput)

/*
 * Utilization is an exception since it used the dm_percent_t type in the
 * original named function based interface: preserve this behaviour for
 * backwards compatibility with existing users.
 *
 * The same metric may be accessed as a double via the enum based metric
 * interface.
 */
int dm_stats_get_utilization(const struct dm_stats *dms, dm_percent_t *util,
			     uint64_t region_id, uint64_t area_id)
{
	double _util;

	if (!dm_stats_get_metric(dms, DM_STATS_UTILIZATION,
				 region_id, area_id, &_util))
		return_0;
	/* scale up utilization value in the range [0.00..1.00] */
	*util = dm_make_percent(DM_PERCENT_1 * _util, DM_PERCENT_1);
	return 1;
}

void dm_stats_set_sampling_interval_ms(struct dm_stats *dms, uint64_t interval_ms)
{
	/* All times use nsecs internally. */
	dms->interval_ns = interval_ms * NSEC_PER_MSEC;
}

void dm_stats_set_sampling_interval_ns(struct dm_stats *dms, uint64_t interval_ns)
{
	dms->interval_ns = interval_ns;
}

uint64_t dm_stats_get_sampling_interval_ms(const struct dm_stats *dms)
{
	/* All times use nsecs internally. */
	return (dms->interval_ns / NSEC_PER_MSEC);
}

uint64_t dm_stats_get_sampling_interval_ns(const struct dm_stats *dms)
{
	/* All times use nsecs internally. */
	return (dms->interval_ns);
}

int dm_stats_set_program_id(struct dm_stats *dms, int allow_empty,
			    const char *program_id)
{
	if (!allow_empty && (!program_id || !strlen(program_id))) {
		log_error("Empty program_id not permitted without "
			  "allow_empty=1");
		return 0;
	}

	if (!program_id)
		program_id = "";

	if (dms->program_id)
		dm_free(dms->program_id);

	if (!(dms->program_id = dm_strdup(program_id)))
		return_0;

	return 1;
}

uint64_t dm_stats_get_current_region(const struct dm_stats *dms)
{
	return dms->cur_region;
}

uint64_t dm_stats_get_current_area(const struct dm_stats *dms)
{
	return dms->cur_area & ~DM_STATS_WALK_ALL;
}

int dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
			      uint64_t region_id)
{
	if (!dms || !dms->regions)
		return_0;

	/* start is unchanged when aggregating areas */
	if (region_id & DM_STATS_WALK_REGION)
		region_id &= ~DM_STATS_WALK_REGION;

	/* use start of first region as group start */
	if (region_id & DM_STATS_WALK_GROUP) {
		if (region_id == DM_STATS_WALK_GROUP)
			region_id = dms->cur_group;
		else
			region_id &= ~DM_STATS_WALK_GROUP;
	}

	*start = dms->regions[region_id].start;
	return 1;
}

int dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
			    uint64_t region_id)
{
	uint64_t i;
	if (!dms || !dms->regions)
		return_0;

	*len = 0;

	/* length is unchanged when aggregating areas */
	if (region_id & DM_STATS_WALK_REGION)
		region_id &= ~DM_STATS_WALK_REGION;

	if (region_id & DM_STATS_WALK_GROUP) {
		/* decode region / group ID */
		if (region_id == DM_STATS_WALK_GROUP)
			region_id = dms->cur_group;
		else
			region_id &= ~DM_STATS_WALK_GROUP;

		/* use sum of region sizes as group size */
		if (_stats_region_is_grouped(dms, region_id))
			_foreach_group_region(dms, dms->cur_group, i)
				*len += dms->regions[i].len;
		else {
			log_error("Group ID " FMTu64 " does not exist",
				  region_id);
			return 0;
		}
	} else
		*len = dms->regions[region_id].len;

	return 1;
}

int dm_stats_get_region_area_len(const struct dm_stats *dms, uint64_t *len,
				 uint64_t region_id)
{
	if (!dms || !dms->regions)
		return_0;

	/* groups are not subdivided - area size equals group size */
	if (region_id & (DM_STATS_WALK_GROUP | DM_STATS_WALK_REGION))
		/* get_region_len will decode region_id */
		return dm_stats_get_region_len(dms, len, region_id);

	*len = dms->regions[region_id].step;
	return 1;
}

int dm_stats_get_current_region_start(const struct dm_stats *dms,
				      uint64_t *start)
{
	return dm_stats_get_region_start(dms, start, dms->cur_region);
}

int dm_stats_get_current_region_len(const struct dm_stats *dms,
				    uint64_t *len)
{
	return dm_stats_get_region_len(dms, len, dms->cur_region);
}

int dm_stats_get_current_region_area_len(const struct dm_stats *dms,
					 uint64_t *step)
{
	return dm_stats_get_region_area_len(dms, step, dms->cur_region);
}

int dm_stats_get_area_start(const struct dm_stats *dms, uint64_t *start,
			    uint64_t region_id, uint64_t area_id)
{
	struct dm_stats_region *region;
	if (!dms || !dms->regions)
		return_0;

	/* group or region area start equals region start */
	if (region_id & (DM_STATS_WALK_GROUP | DM_STATS_WALK_REGION))
		return dm_stats_get_region_start(dms, start, region_id);

	region = &dms->regions[region_id];
	*start = region->start + region->step * area_id;
	return 1;
}

int dm_stats_get_area_offset(const struct dm_stats *dms, uint64_t *offset,
			     uint64_t region_id, uint64_t area_id)
{
	if (!dms || !dms->regions)
		return_0;

	/* no areas for groups or aggregate regions */
	if (region_id & (DM_STATS_WALK_GROUP | DM_STATS_WALK_REGION))
		*offset = 0;
	else
		*offset = dms->regions[region_id].step * area_id;

	return 1;
}

int dm_stats_get_current_area_start(const struct dm_stats *dms,
				    uint64_t *start)
{
	return dm_stats_get_area_start(dms, start,
				       dms->cur_region, dms->cur_area);
}

int dm_stats_get_current_area_offset(const struct dm_stats *dms,
					  uint64_t *offset)
{
	return dm_stats_get_area_offset(dms, offset,
				       dms->cur_region, dms->cur_area);
}

int dm_stats_get_current_area_len(const struct dm_stats *dms,
				  uint64_t *len)
{
	return dm_stats_get_region_area_len(dms, len, dms->cur_region);
}

const char *dm_stats_get_region_program_id(const struct dm_stats *dms,
					   uint64_t region_id)
{
	const char *program_id = NULL;

	if (region_id & DM_STATS_WALK_GROUP)
		return dms->program_id;

	if (region_id & DM_STATS_WALK_REGION)
		region_id &= ~DM_STATS_WALK_REGION;

	program_id = dms->regions[region_id].program_id;
	return (program_id) ? program_id : "";
}

const char *dm_stats_get_region_aux_data(const struct dm_stats *dms,
					 uint64_t region_id)
{
	const char *aux_data = NULL;

	if (region_id & DM_STATS_WALK_GROUP)
		return "";

	if (region_id & DM_STATS_WALK_REGION)
		region_id &= ~DM_STATS_WALK_REGION;

	aux_data = dms->regions[region_id].aux_data;
	return (aux_data) ? aux_data : "" ;
}

int dm_stats_set_alias(struct dm_stats *dms, uint64_t group_id, const char *alias)
{
	struct dm_stats_group *group = NULL;
	const char *old_alias = NULL;

	if (!dms->regions || !dms->groups || !alias)
		return_0;

	if (!_stats_region_is_grouped(dms, group_id)) {
		log_error("Cannot set alias for ungrouped region ID "
			  FMTu64, group_id);
		return 0;
	}

	if (group_id & DM_STATS_WALK_GROUP) {
		if (group_id == DM_STATS_WALK_GROUP)
			group_id = dms->cur_group;
		else
			group_id &= ~DM_STATS_WALK_GROUP;
	}

	if (group_id != dms->regions[group_id].group_id) {
		/* dm_stats_set_alias() must be called on the group ID. */
		log_error("Cannot set alias for group member " FMTu64 ".",
			  group_id);
		return 0;
	}

	group = &dms->groups[group_id];
	old_alias = group->alias;

	group->alias = dm_strdup(alias);
	if (!group->alias) {
		log_error("Could not allocate memory for alias.");
		goto bad;
	}

	if (!_stats_set_aux(dms, group_id, dms->regions[group_id].aux_data)) {
		log_error("Could not set new aux_data");
		goto bad;
	}

	dm_free((char *) old_alias);

	return 1;

bad:
	dm_free((char *) group->alias);
	group->alias = old_alias;
	return 0;
}

const char *dm_stats_get_alias(const struct dm_stats *dms, uint64_t id)
{
	const struct dm_stats_region *region;

	id = (id == DM_STATS_REGION_CURRENT) ? dms->cur_region : id;

	if (id & DM_STATS_WALK_GROUP) {
		if (id == DM_STATS_WALK_GROUP)
			id = dms->cur_group;
		else
			id &= ~DM_STATS_WALK_GROUP;
	}

	region = &dms->regions[id];
	if (!_stats_region_is_grouped(dms, id)
	    || !dms->groups[region->group_id].alias)
		return dms->name;

	return dms->groups[region->group_id].alias;
}

const char *dm_stats_get_current_region_program_id(const struct dm_stats *dms)
{
	return dm_stats_get_region_program_id(dms, dms->cur_region);
}

const char *dm_stats_get_current_region_aux_data(const struct dm_stats *dms)
{
	return dm_stats_get_region_aux_data(dms, dms->cur_region);
}

int dm_stats_get_region_precise_timestamps(const struct dm_stats *dms,
					   uint64_t region_id)
{
	struct dm_stats_region *region;

	if (region_id == DM_STATS_REGION_CURRENT)
		region_id = dms->cur_region;

	if (region_id == DM_STATS_WALK_GROUP)
		region_id = dms->cur_group;
	else if (region_id & DM_STATS_WALK_GROUP)
		region_id &= ~DM_STATS_WALK_GROUP;

	region = &dms->regions[region_id];
	return region->timescale == 1;
}

int dm_stats_get_current_region_precise_timestamps(const struct dm_stats *dms)
{
	return dm_stats_get_region_precise_timestamps(dms,
						      DM_STATS_REGION_CURRENT);
}

/*
 * Histogram access methods.
 */

static void _sum_histogram_bins(const struct dm_stats *dms,
				struct dm_histogram *dmh_aggr,
				uint64_t region_id, uint64_t area_id)
{
	struct dm_stats_region *region;
	struct dm_histogram_bin *bins;
	struct dm_histogram *dmh_cur;
	uint64_t bin;

	region = &dms->regions[region_id];
	dmh_cur = region->counters[area_id].histogram;
	bins = dmh_aggr->bins;

	for (bin = 0; bin < dmh_aggr->nr_bins; bin++)
		bins[bin].count += dmh_cur->bins[bin].count;
}

/*
 * Create an aggregate histogram for a sub-divided region or a group.
 */
static struct dm_histogram *_aggregate_histogram(const struct dm_stats *dms,
						 uint64_t region_id,
						 uint64_t area_id)
{
	struct dm_histogram *dmh_aggr, *dmh_cur, **dmh_cachep;
	int bin, nr_bins, group = 1;
	uint64_t group_id;
	size_t hist_size;

	if (area_id == DM_STATS_WALK_REGION) {
		/* region aggregation */
		group = 0;
		if (!_stats_region_present(&dms->regions[region_id]))
			return_NULL;

		if (!dms->regions[region_id].bounds)
			return_NULL;

		if (!dms->regions[region_id].counters)
			return dms->regions[region_id].bounds;

		if (dms->regions[region_id].histogram)
			return dms->regions[region_id].histogram;

		dmh_cur = dms->regions[region_id].counters[0].histogram;
		dmh_cachep = &dms->regions[region_id].histogram;
		nr_bins = dms->regions[region_id].bounds->nr_bins;
	} else {
		/* group aggregation */
		group_id = region_id;
		area_id = DM_STATS_WALK_GROUP;
		if (!_stats_group_id_present(dms, group_id))
			return_NULL;

		if (!dms->regions[group_id].bounds)
			return_NULL;

		if (!dms->regions[group_id].counters)
			return dms->regions[group_id].bounds;

		if (dms->groups[group_id].histogram)
			return dms->groups[group_id].histogram;

		dmh_cur = dms->regions[group_id].counters[0].histogram;
		dmh_cachep = &dms->groups[group_id].histogram;
		nr_bins = dms->regions[group_id].bounds->nr_bins;
	}

	hist_size = sizeof(*dmh_aggr)
		     + nr_bins * sizeof(struct dm_histogram_bin);

	if (!(dmh_aggr = dm_pool_zalloc(dms->hist_mem, hist_size))) {
		log_error("Could not allocate group histogram");
		return 0;
	}

	dmh_aggr->nr_bins = dmh_cur->nr_bins;
	dmh_aggr->dms = dms;

	if (!group)
		_foreach_region_area(dms, region_id, area_id) {
			_sum_histogram_bins(dms, dmh_aggr, region_id, area_id);
		}
	else {
		_foreach_group_area(dms, group_id, region_id, area_id) {
			_sum_histogram_bins(dms, dmh_aggr, region_id, area_id);
		}
	}

	for (bin = 0; bin < nr_bins; bin++) {
		dmh_aggr->sum += dmh_aggr->bins[bin].count;
		dmh_aggr->bins[bin].upper = dmh_cur->bins[bin].upper;
	}

	/* cache aggregate histogram for subsequent access */
	*dmh_cachep = dmh_aggr;

	return dmh_aggr;
}

struct dm_histogram *dm_stats_get_histogram(const struct dm_stats *dms,
					    uint64_t region_id,
					    uint64_t area_id)
{
	int aggr = 0;

	if (region_id == DM_STATS_REGION_CURRENT) {
		region_id = dms->cur_region;
		if (region_id & DM_STATS_WALK_GROUP) {
			region_id = dms->cur_group;
			aggr = 1;
		}
	} else if (region_id & DM_STATS_WALK_GROUP) {
		region_id &= ~DM_STATS_WALK_GROUP;
		aggr = 1;
	}

	area_id = (area_id == DM_STATS_AREA_CURRENT)
		   ? dms->cur_area : area_id ;

	if (area_id == DM_STATS_WALK_REGION)
		aggr = 1;

	if (aggr)
		return _aggregate_histogram(dms, region_id, area_id);

	if (region_id & DM_STATS_WALK_REGION)
		region_id &= ~DM_STATS_WALK_REGION;

	if (!dms->regions[region_id].counters)
		return dms->regions[region_id].bounds;

	return dms->regions[region_id].counters[area_id].histogram;
}

int dm_histogram_get_nr_bins(const struct dm_histogram *dmh)
{
	return dmh->nr_bins;
}

uint64_t dm_histogram_get_bin_lower(const struct dm_histogram *dmh, int bin)
{
	return (!bin) ? 0 : dmh->bins[bin - 1].upper;
}

uint64_t dm_histogram_get_bin_upper(const struct dm_histogram *dmh, int bin)
{
	return dmh->bins[bin].upper;
}

uint64_t dm_histogram_get_bin_width(const struct dm_histogram *dmh, int bin)
{
	uint64_t upper, lower;
	upper = dm_histogram_get_bin_upper(dmh, bin);
	lower = dm_histogram_get_bin_lower(dmh, bin);
	return (upper - lower);
}

uint64_t dm_histogram_get_bin_count(const struct dm_histogram *dmh, int bin)
{
	return dmh->bins[bin].count;
}

uint64_t dm_histogram_get_sum(const struct dm_histogram *dmh)
{
	return dmh->sum;
}

dm_percent_t dm_histogram_get_bin_percent(const struct dm_histogram *dmh,
					  int bin)
{
	uint64_t value = dm_histogram_get_bin_count(dmh, bin);
	uint64_t width = dm_histogram_get_bin_width(dmh, bin);
	uint64_t total = dm_histogram_get_sum(dmh);

	double val = (double) value;

	if (!total || !value || !width)
		return DM_PERCENT_0;

	return dm_make_percent((uint64_t) val, total);
}

/*
 * Histogram string helper functions: used to construct histogram and
 * bin boundary strings from numeric data.
 */

/*
 * Allocate an unbound histogram object with nr_bins bins. Only used
 * for histograms used to hold bounds values as arguments for calls to
 * dm_stats_create_region().
 */
static struct dm_histogram *_alloc_dm_histogram(int nr_bins)
{
	/* Allocate space for dm_histogram + nr_entries. */
	size_t size = sizeof(struct dm_histogram) +
		(unsigned) nr_bins * sizeof(struct dm_histogram_bin);
	return dm_zalloc(size);
}

/*
 * Parse a histogram bounds string supplied by the user. The string
 * consists of a list of numbers, "n1,n2,n3,..." with optional 'ns',
 * 'us', 'ms', or 's' unit suffixes.
 *
 * The scale parameter indicates the timescale used for this region: one
 * for nanoscale resolution and NSEC_PER_MSEC for miliseconds.
 *
 * On return bounds contains a pointer to an array of uint64_t
 * histogram bounds values expressed in units of nanoseconds.
 */
struct dm_histogram *dm_histogram_bounds_from_string(const char *bounds_str)
{
	static const char _valid_chars[] = "0123456789,muns";
	uint64_t this_val = 0, mult = 1;
	const char *c, *v, *val_start;
	struct dm_histogram_bin *cur;
	struct dm_histogram *dmh;
	int nr_entries = 1;
	char *endptr;

	c = bounds_str;

	/* Count number of bounds entries. */
	while(*c)
		if (*(c++) == ',')
			nr_entries++;

	c = bounds_str;

	if (!(dmh = _alloc_dm_histogram(nr_entries)))
		return_0;

	dmh->nr_bins = nr_entries;

	cur = dmh->bins;

	do {
		for (v = _valid_chars; *v; v++)
			if (*c == *v)
				break;

		if (!*v) {
			stack;
			goto badchar;
		}

		if (*c == ',') {
			log_error("Empty histogram bin not allowed: %s",
				  bounds_str);
			goto bad;
		} else {
			val_start = c;
			endptr = NULL;

			this_val = strtoull(val_start, &endptr, 10);
			if (!endptr) {
				log_error("Could not parse histogram bound.");
				goto bad;
			}
			c = endptr; /* Advance to units, comma, or end. */

			if (*c == 's') {
				mult = NSEC_PER_SEC;
				c++; /* Advance over 's'. */
			} else if (*(c + 1) == 's') {
				if (*c == 'm')
					mult = NSEC_PER_MSEC;
				else if (*c == 'u')
					mult = NSEC_PER_USEC;
				else if (*c == 'n')
					mult = 1;
				else {
					stack;
					goto badchar;
				}
				c += 2; /* Advance over 'ms', 'us', or 'ns'. */
			} else if (*c == ',')
				c++;
			else if (*c) { /* Expected ',' or NULL. */
				stack;
				goto badchar;
			}

			if (*c == ',')
				c++;
			this_val *= mult;
			(cur++)->upper = this_val;
		}
	} while (*c);

	/* Bounds histograms have no owner. */
	dmh->dms = NULL;
	dmh->region = NULL;

	return dmh;

badchar:
	log_error("Invalid character in histogram: %c", *c);
bad:
	dm_free(dmh);
	return NULL;
}

struct dm_histogram *dm_histogram_bounds_from_uint64(const uint64_t *bounds)
{
	const uint64_t *entry = bounds;
	struct dm_histogram_bin *cur;
	struct dm_histogram *dmh;
	int nr_entries = 1;

	if (!bounds || !bounds[0]) {
		log_error("Could not parse empty histogram bounds array");
		return 0;
	}

	/* Count number of bounds entries. */
	while(*entry)
		if (*(++entry))
			nr_entries++;

	entry = bounds;

	if (!(dmh = _alloc_dm_histogram(nr_entries)))
		return_0;

	dmh->nr_bins = nr_entries;

	cur = dmh->bins;

	while (*entry)
		(cur++)->upper = *(entry++);

	/* Bounds histograms have no owner. */
	dmh->dms = NULL;
	dmh->region = NULL;

	return dmh;
}

void dm_histogram_bounds_destroy(struct dm_histogram *bounds)
{
	if (!bounds)
		return;

	/* Bounds histograms are not bound to any handle or region. */
	if (bounds->dms || bounds->region) {
		log_error("Freeing invalid histogram bounds pointer %p.",
			  (void *) bounds);
		stack;
	}
	/* dm_free() expects a (void *). */
	dm_free((void *) bounds);
}

/*
 * Scale a bounds value down from nanoseconds to the largest possible
 * whole unit suffix.
 */
static void _scale_bound_value_to_suffix(uint64_t *bound, const char **suffix)
{
	*suffix = "ns";
	if (!(*bound % NSEC_PER_SEC)) {
		*bound /= NSEC_PER_SEC;
		*suffix = "s";
	} else if (!(*bound % NSEC_PER_MSEC)) {
		*bound /= NSEC_PER_MSEC;
		*suffix = "ms";
	} else if (!(*bound % NSEC_PER_USEC)) {
		*bound /= NSEC_PER_USEC;
		*suffix = "us";
	}
}

#define DM_HISTOGRAM_BOUNDS_MASK 0x30
#define BOUNDS_LEN 64

static int _make_bounds_string(char *buf, size_t size, uint64_t lower,
			       uint64_t upper, int flags, int width)
{
	char bound_buf[BOUNDS_LEN];
	const char *l_suff = NULL;
	const char *u_suff = NULL;
	const char *sep = "";
	int bounds = flags & DM_HISTOGRAM_BOUNDS_MASK;

	if (!bounds)
		return_0;

	*buf = '\0';

	if (flags & DM_HISTOGRAM_SUFFIX) {
		_scale_bound_value_to_suffix(&lower, &l_suff);
		_scale_bound_value_to_suffix(&upper, &u_suff);
	} else
		l_suff = u_suff = "";

	if (flags & DM_HISTOGRAM_VALUES)
		sep = ":";

	if (bounds > DM_HISTOGRAM_BOUNDS_LOWER) {
		/* Handle infinite uppermost bound. */
		if (upper == UINT64_MAX) {
			if (dm_snprintf(bound_buf, sizeof(bound_buf),
					 ">" FMTu64 "%s", lower, l_suff) < 0)
				goto_out;
			/* Only display an 'upper' string for final bin. */
			bounds = DM_HISTOGRAM_BOUNDS_UPPER;
		} else {
			if (dm_snprintf(bound_buf, sizeof(bound_buf),
					 FMTu64 "%s", upper, u_suff) < 0)
				goto_out;
		}
	} else if (bounds == DM_HISTOGRAM_BOUNDS_LOWER) {
		if ((dm_snprintf(bound_buf, sizeof(bound_buf), FMTu64 "%s",
				 lower, l_suff)) < 0)
			goto_out;
	}

	switch (bounds) {
	case DM_HISTOGRAM_BOUNDS_LOWER:
	case DM_HISTOGRAM_BOUNDS_UPPER:
		return dm_snprintf(buf, size, "%*s%s", width, bound_buf, sep);
	case DM_HISTOGRAM_BOUNDS_RANGE:
		return dm_snprintf(buf, size,  FMTu64 "%s-%s%s",
				   lower, l_suff, bound_buf, sep);
	}
out:
	return 0;
}

#define BOUND_WIDTH_NOSUFFIX 10 /* 999999999 nsecs */
#define BOUND_WIDTH 6 /* bounds string up to 9999xs */
#define COUNT_WIDTH 6 /* count string: up to 9999 */
#define PERCENT_WIDTH 6 /* percent string : 0.00-100.00% */
#define DM_HISTOGRAM_VALUES_MASK 0x06

const char *dm_histogram_to_string(const struct dm_histogram *dmh, int bin,
				   int width, int flags)
{
	char buf[BOUNDS_LEN], bounds_buf[BOUNDS_LEN];
	int minwidth, bounds, values, start, last;
	uint64_t lower, upper, val_u64; /* bounds of the current bin. */
	/* Use the histogram pool for string building. */
	struct dm_pool *mem = dmh->dms->hist_mem;
	const char *sep = "";
	int bounds_width;
	ssize_t len = 0;
	float val_flt;

	bounds = flags & DM_HISTOGRAM_BOUNDS_MASK;
	values = flags & DM_HISTOGRAM_VALUES;

	if (bin < 0) {
		start = 0;
		last = dmh->nr_bins - 1;
	} else
		start = last = bin;

	minwidth = width;

	if (width < 0 || !values)
		width = minwidth = 0; /* no padding */
	else if (flags & DM_HISTOGRAM_PERCENT)
		width = minwidth = (width) ? : PERCENT_WIDTH;
	else if (flags & DM_HISTOGRAM_VALUES)
		width = minwidth = (width) ? : COUNT_WIDTH;

	if (values && !width)
		sep = ":";

	/* Set bounds string to the empty string. */
	bounds_buf[0] = '\0';

	if (!dm_pool_begin_object(mem, 64))
		return_0;

	for (bin = start; bin <= last; bin++) {
		if (bounds) {
			/* Default bounds width depends on time suffixes. */
			bounds_width = (!(flags & DM_HISTOGRAM_SUFFIX))
					? BOUND_WIDTH_NOSUFFIX
					: BOUND_WIDTH ;

			bounds_width = (!width) ? width : bounds_width;

			lower = dm_histogram_get_bin_lower(dmh, bin);
			upper = dm_histogram_get_bin_upper(dmh, bin);

			len = sizeof(bounds_buf);
			len = _make_bounds_string(bounds_buf, len,
						  lower, upper, flags,
						  bounds_width);
			/*
			 * Comma separates "bounds: value" pairs unless
			 * --noheadings is used.
			 */
			sep = (width || !values) ? "," : ":";

			/* Adjust width by real bounds length if set. */
			width -= (width) ? (len - (bounds_width + 1)) : 0;

			/* -ve width indicates specified width was overrun. */
			width = (width > 0) ? width : 0;
		}

		if (bin == last)
			sep = "";

		if (flags & DM_HISTOGRAM_PERCENT) {
			dm_percent_t pr;
			pr = dm_histogram_get_bin_percent(dmh, bin);
			val_flt = dm_percent_to_float(pr);
			len = dm_snprintf(buf, sizeof(buf), "%s%*.2f%%%s",
					  bounds_buf, width, val_flt, sep);
		} else if (values) {
			val_u64 = dmh->bins[bin].count;
			len = dm_snprintf(buf, sizeof(buf), "%s%*"PRIu64"%s",
					  bounds_buf, width, val_u64, sep);
		} else if (bounds)
			len = dm_snprintf(buf, sizeof(buf), "%s%s", bounds_buf,
					  sep);
		else {
			*buf = '\0';
			len = 0;
		}

		if (len < 0)
			goto_bad;

		width = minwidth; /* re-set histogram column width. */
		if (!dm_pool_grow_object(mem, buf, (size_t) len))
			goto_bad;
	}

	if (!dm_pool_grow_object(mem, "\0", 1))
		goto_bad;

	return (const char *) dm_pool_end_object(mem);

bad:
	dm_pool_abandon_object(mem);
	return NULL;
}

/*
 * A lightweight representation of an extent (region, area, file
 * system block or extent etc.). A table of extents can be used
 * to sort and to efficiently find holes or overlaps among a set
 * of tuples of the form (id, start, len).
 */
struct _extent {
	struct dm_list list;
	uint64_t id;
	uint64_t start;
	uint64_t len;
};

/* last address in an extent */
#define _extent_end(a) ((a)->start + (a)->len - 1)

/* a and b must be sorted by increasing start sector */
#define _extents_overlap(a, b) (_extent_end(a) > (b)->start)

/*
 * Comparison function to sort extents in ascending start order.
 */
static int _extent_start_compare(const void *p1, const void *p2)
{
	struct _extent *r1, *r2;
	r1 = (struct _extent *) p1;
	r2 = (struct _extent *) p2;

	if (r1->start < r2->start)
		return -1;
	else if (r1->start == r2->start)
		return 0;
	return 1;
}

static int _stats_create_group(struct dm_stats *dms, dm_bitset_t regions,
			       const char *alias, uint64_t *group_id)
{
	struct dm_stats_group *group;
	*group_id = dm_bit_get_first(regions);

	/* group has no regions? */
	if (*group_id == DM_STATS_GROUP_NOT_PRESENT)
		return_0;

	group = &dms->groups[*group_id];

	if (group->regions) {
		log_error(INTERNAL_ERROR "Unexpected group state while"
			  "creating group ID bitmap" FMTu64, *group_id);
		return 0;
	}

	group->group_id = *group_id;
	group->regions = regions;

	if (alias)
		group->alias = dm_strdup(alias);
	else
		group->alias = NULL;

	/* force an update of the group tag stored in aux_data */
	if (!_stats_set_aux(dms, *group_id, dms->regions[*group_id].aux_data))
		return 0;

	return 1;
}

static int _stats_group_check_overlap(const struct dm_stats *dms,
				      dm_bitset_t regions, int count)
{
	struct dm_list ext_list = DM_LIST_HEAD_INIT(ext_list);
	struct _extent *ext, *tmp, *next, *map = NULL;
	size_t map_size = (dms->max_region + 1) * sizeof(*map);
	int i = 0, id, overlap, merged;

	map = dm_pool_alloc(dms->mem, map_size);
	if (!map) {
		log_error("Could not allocate memory for region map");
		return 0;
	}

	/* build a table of extents in order of region_id */
	for (id = dm_bit_get_first(regions); id >= 0;
	     id = dm_bit_get_next(regions, id)) {
		dm_list_init(&map[i].list);
		map[i].id = id;
		map[i].start = dms->regions[id].start;
		map[i].len = dms->regions[id].len;
		i++;
	}

	/* sort by extent.start */
	qsort(map, count, sizeof(*map), _extent_start_compare);

	for (i = 0; i < count; i++)
		dm_list_add(&ext_list, &map[i].list);

	overlap = 0;
merge:
	merged = 0;
	dm_list_iterate_items_safe(ext, tmp, &ext_list) {
		next = dm_list_item(dm_list_next(&ext_list, &ext->list),
				    struct _extent);
		if (!next)
			continue;

		if (_extents_overlap(ext, next)) {
			log_warn("Warning: region IDs " FMTu64 " and "
				 FMTu64 " overlap. Some events will be "
				 "counted twice.", ext->id, next->id);
			/* merge larger extent into smaller */
			if (_extent_end(ext) > _extent_end(next)) {
				next->id = ext->id;
				next->len = ext->len;
			}
			if (ext->start < next->start)
				next->start = ext->start;
			dm_list_del(&ext->list);
			overlap = merged = 1;
		}
	}
	/* continue until no merge candidates remain */
	if (merged)
		goto merge;

	dm_pool_free(dms->mem, map);
	return overlap;
}

static void _stats_copy_histogram_bounds(struct dm_histogram *to,
					 struct dm_histogram *from)
{
	uint64_t i;

	to->nr_bins = from->nr_bins;

	for (i = 0; i < to->nr_bins; i++)
		to->bins[i].upper = from->bins[i].upper;
}

/*
 * Compare histogram bounds h1 and h2, and return 1 if they match (i.e.
 * have the same number of bins and identical bin boundary values), or 0
 * otherwise.
 */
static int _stats_check_histogram_bounds(struct dm_histogram *h1,
					 struct dm_histogram *h2)
{
	uint64_t i;

	if (!h1 || !h2)
		return 0;

	if (h1->nr_bins != h2->nr_bins)
		return 0;

	for (i = 0; i < h1->nr_bins; i++)
		if (h1->bins[i].upper != h2->bins[i].upper)
			return 0;
	return 1;
}

/*
 * Create a new group in stats handle dms from the group description
 * passed in group.
 */
int dm_stats_create_group(struct dm_stats *dms, const char *members,
			  const char *alias, uint64_t *group_id)
{
	struct dm_histogram *check = NULL, *bounds;
	int i, count = 0, precise = 0;
	dm_bitset_t regions;

	if (!dms->regions || !dms->groups) {
		log_error("Could not create group: no regions found.");
		return 0;
	};

	if (!(regions = dm_bitset_parse_list(members, NULL))) {
		log_error("Could not parse list: '%s'", members);
		return 0;
	}

	if (!(check = dm_pool_zalloc(dms->hist_mem, sizeof(*check)))) {
		log_error("Could not allocate memory for bounds check");
		goto bad;
	}

	/* too many bits? */
	if ((*regions - 1) > dms->max_region) {
		log_error("Invalid region ID: %d", *regions - 1);
		goto bad;
	}

	/*
	 * Check that each region_id in the bitmap meets the group
	 * constraints: present, not already grouped, and if any
	 * histogram is present that they all have the same bounds.
	 */
	for (i = dm_bit_get_first(regions); i >= 0;
	     i = dm_bit_get_next(regions, i)) {
		if (!dm_stats_region_present(dms, i)) {
			log_error("Region ID %d does not exist", i);
			goto bad;
		}
		if (_stats_region_is_grouped(dms, i)) {
			log_error("Region ID %d already a member of group ID "
				  FMTu64, i, dms->regions[i].group_id);
			goto bad;
		}
		if (dms->regions[i].timescale == 1)
			precise++;

		/* check for matching histogram bounds */
		bounds = dms->regions[i].bounds;
		if (bounds && !check->nr_bins)
			_stats_copy_histogram_bounds(check, bounds);
		else if (bounds) {
			if (!_stats_check_histogram_bounds(check, bounds)) {
				log_error("All region histogram bounds "
					  "must match exactly");
				goto bad;
			}
		}
		count++;
	}

	if (precise && (precise != count))
		log_warn("Grouping regions with different clock resolution: "
			 "precision may be lost");

	if (!_stats_group_check_overlap(dms, regions, count))
		log_info("Creating group with overlapping regions");

	if (!_stats_create_group(dms, regions, alias, group_id))
		goto bad;

	dm_pool_free(dms->hist_mem, check);
	return 1;

bad:
	dm_pool_free(dms->hist_mem, check);
	dm_bitset_destroy(regions);
	return 0;
}

/*
 * Remove the specified group_id.
 */
int dm_stats_delete_group(struct dm_stats *dms, uint64_t group_id,
			  int remove_regions)
{
	struct dm_stats_region *leader;
	dm_bitset_t regions;
	uint64_t i;

	if (group_id > dms->max_region) {
		log_error("Invalid group ID: " FMTu64, group_id);
		return 0;
	}

	if (!_stats_group_id_present(dms, group_id)) {
		log_error("Group ID " FMTu64 " does not exist", group_id);
		return 0;
	}

	regions = dms->groups[group_id].regions;
	leader = &dms->regions[group_id];

	/* delete all but the group leader */
	for (i = (*regions - 1); i > leader->region_id; i--) {
		if (dm_bit(regions, i)) {
			dm_bit_clear(regions, i);
			if (remove_regions && !dm_stats_delete_region(dms, i))
				log_warn("Failed to delete region "
					 FMTu64 " on %s.", i, dms->name);
		}
	}

	/* clear group and mark as not present */
	_stats_clear_group_regions(dms, group_id);
	_stats_group_destroy(&dms->groups[group_id]);

	/* delete leader or clear aux_data */
	if (remove_regions)
		return dm_stats_delete_region(dms, group_id);
	else if (!_stats_set_aux(dms, group_id, leader->aux_data))
		return 0;

	return 1;
}

uint64_t dm_stats_get_group_id(const struct dm_stats *dms, uint64_t region_id)
{
	region_id = (region_id == DM_STATS_REGION_CURRENT)
		     ? dms->cur_region : region_id;

	if (region_id & DM_STATS_WALK_GROUP) {
		if (region_id == DM_STATS_WALK_GROUP)
			return dms->cur_group;
		else
			return region_id & ~DM_STATS_WALK_GROUP;
	}

	if (region_id & DM_STATS_WALK_REGION)
		region_id &= ~DM_STATS_WALK_REGION;

	return dms->regions[region_id].group_id;
}

int dm_stats_get_group_descriptor(const struct dm_stats *dms,
				  uint64_t group_id, char **buf)
{
	dm_bitset_t regions = dms->groups[group_id].regions;
	size_t buflen;

	buflen = _stats_group_tag_len(dms, regions);

	*buf = dm_pool_alloc(dms->mem, buflen);
	if (!*buf) {
		log_error("Could not allocate memory for regions string");
		return 0;
	}

	if (!_stats_group_tag_fill(dms, regions, *buf, buflen))
		return 0;

	return 1;
}

#ifdef HAVE_LINUX_FIEMAP_H
/*
 * Group a table of region_ids corresponding to the extents of a file.
 */
static int _stats_group_file_regions(struct dm_stats *dms, uint64_t *region_ids,
				     uint64_t count, const char *alias)
{
	dm_bitset_t regions = dm_bitset_create(NULL, dms->nr_regions);
	uint64_t i, group_id = DM_STATS_GROUP_NOT_PRESENT;
	char *members = NULL;
	int buflen;

	if (!regions) {
		log_error("Cannot map file: failed to allocate group bitmap.");
		return 0;
	}

	for (i = 0; i < count; i++)
		dm_bit_set(regions, region_ids[i]);

	buflen = _stats_group_tag_len(dms, regions);
	members = dm_malloc(buflen);

	if (!members) {
		log_error("Cannot map file: failed to allocate group "
			  "descriptor.");
		dm_bitset_destroy(regions);
		return 0;
	}

	if (!_stats_group_tag_fill(dms, regions, members, buflen))
		goto bad;

	/*
	 * overlaps should not be possible: overlapping file extents
	 * returned by FIEMAP imply a kernel bug or a corrupt fs.
	 */
	if (!_stats_group_check_overlap(dms, regions, count))
		log_info("Creating group with overlapping regions.");

	if (!_stats_create_group(dms, regions, alias, &group_id))
		goto bad;

	dm_free(members);
	return 1;
bad:
	dm_bitset_destroy(regions);
	dm_free(members);
	return 0;
}

static int _stats_add_extent(struct dm_pool *mem, struct fiemap_extent *fm_ext,
			     uint64_t id)
{
	struct _extent extent;

	/* final address of list is unknown */
	memset(&extent.list, 0, sizeof(extent.list));

	/* convert bytes to dm (512b) sectors */
	extent.start = fm_ext->fe_physical >> SECTOR_SHIFT;
	extent.len = fm_ext->fe_length >> SECTOR_SHIFT;

	extent.id = id;

	if (!dm_pool_grow_object(mem, &extent,
				 sizeof(extent))) {
		log_error("Cannot map file: failed to grow extent map.");
		return 0;
	}
	return 1;

}

/* test for the boundary of an extent */
#define ext_boundary(ext, exp, exp_dense)	\
(((ext).fe_logical != 0) &&			\
((ext).fe_physical != (exp)) &&			\
((ext).fe_physical != (exp_dense)))

/*
 * Read the extents of an open file descriptor into a table of struct _extent.
 *
 * Based on e2fsprogs/misc/filefrag.c::filefrag_fiemap().
 *
 * Copyright 2003 by Theodore Ts'o.
 *
 */
static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
						   uint64_t *count)
{
	uint64_t buf[STATS_FIE_BUF_LEN];
	struct fiemap *fiemap = (struct fiemap *)buf;
	struct fiemap_extent *fm_ext = &fiemap->fm_extents[0];
	struct fiemap_extent fm_last = {0};
	struct _extent *extents;
	unsigned long long expected = 0;
	unsigned long long expected_dense = 0;
	unsigned long flags = 0;
	unsigned int i, num = 0;
	int tot_extents = 0, n = 0;
	int last = 0;
	int rc;

	memset(buf, 0, sizeof(buf));

	/* space available per ioctl */
	*count = (sizeof(buf) - sizeof(*fiemap))
		  / sizeof(struct fiemap_extent);

	/* grow temporary extent table in the pool */
	if (!dm_pool_begin_object(mem, sizeof(*extents)))
		return NULL;

	flags |= FIEMAP_FLAG_SYNC;

	do {
		/* start of ioctl loop - zero size and set count to bufsize */
		fiemap->fm_length = ~0ULL;
		fiemap->fm_flags = flags;
		fiemap->fm_extent_count = *count;

		/* get count-sized chunk of extents */
		rc = ioctl(fd, FS_IOC_FIEMAP, (unsigned long) fiemap);
		if (rc < 0) {
			rc = -errno;
			if (rc == -EBADR)
				log_err_once("FIEMAP failed with unknown "
					     "flags %x.", fiemap->fm_flags);
			goto bad;
		}

		/* If 0 extents are returned, then more ioctls are not needed */
		if (fiemap->fm_mapped_extents == 0)
			break;

		for (i = 0; i < fiemap->fm_mapped_extents; i++) {
			expected_dense = fm_last.fe_physical +
					 fm_last.fe_length;
			expected = fm_last.fe_physical +
				   fm_ext[i].fe_logical - fm_last.fe_logical;
			if (ext_boundary(fm_ext[i], expected, expected_dense)) {
				tot_extents++;
				if (!_stats_add_extent(mem, fm_ext + i,
						       tot_extents - 1))
					goto_bad;
			} else {
				expected = 0;
				if (!tot_extents)
					tot_extents = 1;
				if (fm_ext[i].fe_logical == 0)
					if (!_stats_add_extent(mem, fm_ext + i,
							       tot_extents - 1))
						goto_bad;
			}
			num += tot_extents;
			if (fm_ext[i].fe_flags & FIEMAP_EXTENT_LAST)
				last = 1;
			fm_last = fm_ext[i];
			n++;
		}

		fiemap->fm_start = (fm_ext[i - 1].fe_logical +
				    fm_ext[i - 1].fe_length);
	} while (last == 0);

	if (!tot_extents) {
		log_error("Cannot map file: no allocated extents.");
		goto bad;
	}

	/* return total number of extents */
	*count = tot_extents;
	return dm_pool_end_object(mem);
bad:
	dm_pool_abandon_object(mem);
	return NULL;
}

/*
 * Create a set of regions representing the extents of a file and
 * return a table of uint64_t region_id values. The number of regions
 * created is returned in the memory pointed to by count (which must be
 * non-NULL).
 */
static uint64_t *_stats_create_file_regions(struct dm_stats *dms, int fd,
					    struct dm_histogram *bounds,
					    int precise, uint64_t *count)
{
	struct _extent *extents = NULL;
	uint64_t *regions = NULL, i;
	char *hist_arg = NULL;
	struct statfs fsbuf;
	struct stat buf;

#ifdef BTRFS_SUPER_MAGIC
	if (fstatfs(fd, &fsbuf)) {
		log_error("fstatfs failed for fd %d", fd);
		return 0;
	}

	if (fsbuf.f_type == BTRFS_SUPER_MAGIC) {
		log_error("Cannot map file: btrfs does not provide "
			  "physical FIEMAP extent data.");
		return 0;
	}
#endif

	if (fstat(fd, &buf)) {
		log_error("fstat failed for fd %d", fd);
		return 0;
	}

	if (!(buf.st_mode & S_IFREG)) {
		log_error("Not a regular file");
		return 0;
	}

	if (!dm_is_dm_major(major(buf.st_dev))) {
		log_error("Cannot map file: not a device-mapper device.");
		return 0;
	}

	if (!(extents = _stats_get_extents_for_file(dms->mem, fd, count)))
		return_0;

        if (bounds) {
                /* _build_histogram_arg enables precise if vals < 1ms. */
                if (!(hist_arg = _build_histogram_arg(bounds, &precise)))
                        goto_out;
        }

	/* make space for end-of-table marker */
	if (!(regions = dm_malloc((1 + *count) * sizeof(*regions)))) {
		log_error("Could not allocate memory for region IDs.");
		goto out;
	}

	for (i = 0; i < *count; i++) {
		if (!_stats_create_region(dms, regions + i, extents[i].start,
					  extents[i].len, -1, precise, hist_arg,
					  dms->program_id, "")) {
			log_error("Failed to create region " FMTu64 " of "
				  FMTu64 " at " FMTu64 ".", i, *count,
				  extents[i].start);
			goto out_remove;
		}
	}
	regions[*count] = DM_STATS_REGION_NOT_PRESENT;

	if (bounds)
		dm_free(hist_arg);
	dm_pool_free(dms->mem, extents);
	return regions;

out_remove:
	/* clean up regions after create failure */
	for (--i; i != DM_STATS_REGION_NOT_PRESENT; i--) {
		if (!dm_stats_delete_region(dms, i))
			log_error("Could not delete region " FMTu64 ".", i);
	}

out:
	dm_pool_free(dms->mem, extents);
	dm_free(hist_arg);
	dm_free(regions);
	return NULL;
}


uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
					  int group, int precise,
					  struct dm_histogram *bounds,
					  const char *alias)
{
	uint64_t *regions, count = 0;

	if (alias && !group) {
		log_error("Cannot set alias without grouping regions.");
		return NULL;
	}

	regions = _stats_create_file_regions(dms, fd, bounds, precise, &count);
	if (!regions)
		return_0;

	if (!group)
		return regions;

	/* refresh handle */
	if (!dm_stats_list(dms, NULL))
		goto_out;

	if (!_stats_group_file_regions(dms, regions, count, alias))
		goto_out;

	return regions;
out:
	dm_free(regions);
	return NULL;
}

#else /* HAVE_LINUX_FIEMAP */
uint64_t *dm_stats_create_regions_from_fd(struct dm_stats *dms, int fd,
					  int group, int precise,
					  struct dm_histogram *bounds,
					  const char *alias)
{
	log_error("File mapping requires FIEMAP ioctl support.");
	return 0;
}
#endif /* HAVE_LINUX_FIEMAP */

/*
 * Backward compatible dm_stats_create_region() implementations.
 *
 * Keep these at the end of the file to avoid adding clutter around the
 * current dm_stats_create_region() version.
 */

#if defined(__GNUC__)
int dm_stats_create_region_v1_02_106(struct dm_stats *dms, uint64_t *region_id,
				     uint64_t start, uint64_t len, int64_t step,
				     int precise, const char *program_id,
				     const char *aux_data);
int dm_stats_create_region_v1_02_106(struct dm_stats *dms, uint64_t *region_id,
				     uint64_t start, uint64_t len, int64_t step,
				     int precise, const char *program_id,
				     const char *aux_data)
{
	/* 1.02.106 lacks histogram argument. */
	return _stats_create_region(dms, region_id, start, len, step, precise,
				    NULL, program_id, aux_data);
}
DM_EXPORT_SYMBOL(dm_stats_create_region, 1_02_106);

int dm_stats_create_region_v1_02_104(struct dm_stats *dms, uint64_t *region_id,
				     uint64_t start, uint64_t len, int64_t step,
				     const char *program_id, const char *aux_data);
int dm_stats_create_region_v1_02_104(struct dm_stats *dms, uint64_t *region_id,
				     uint64_t start, uint64_t len, int64_t step,
				     const char *program_id, const char *aux_data)
{
	/* 1.02.104 lacks histogram and precise arguments. */
	return _stats_create_region(dms, region_id, start, len, step, 0, NULL,
				    program_id, aux_data);
}
DM_EXPORT_SYMBOL(dm_stats_create_region, 1_02_104);
#endif
