int crypt_compare_dm_devices(struct crypt_device *cd,
			       const struct crypt_dm_active_device *src,
			       const struct crypt_dm_active_device *tgt)
{
	int r;
	const struct dm_target *s, *t;

	if (!src || !tgt)
		return -EINVAL;

	r = _compare_device_types(cd, src, tgt);
	if (r)
		return r;

	s = &src->segment;
	t = &tgt->segment;

	while (s || t) {
		if (!s || !t) {
			log_dbg(cd, "segments count mismatch.");
			return -EINVAL;
		}
		if (s->type != t->type) {
			log_dbg(cd, "segment type mismatch.");
			r = -EINVAL;
			break;
		}

		switch (s->type) {
		case DM_CRYPT:
			r = _compare_crypt_devices(cd, s, t);
			break;
		case DM_INTEGRITY:
			r = _compare_integrity_devices(cd, s, t);
			break;
		case DM_LINEAR:
			r = (s->u.linear.offset == t->u.linear.offset) ? 0 : -EINVAL;
			break;
		default:
			r = -ENOTSUP;
		}

		if (r)
			break;

		s = s->next;
		t = t->next;
	}

	return r;
}
int crypt_compare_dm_devices(struct crypt_device *cd,
			       const struct crypt_dm_active_device *src,
			       const struct crypt_dm_active_device *tgt)
{
	int r;
	const struct dm_target *s, *t;

	if (!src || !tgt)
		return -EINVAL;

	r = _compare_device_types(cd, src, tgt);
	if (r)
		return r;

	s = &src->segment;
	t = &tgt->segment;

	while (s || t) {
		if (!s || !t) {
			log_dbg(cd, "segments count mismatch.");
			return -EINVAL;
		}
		if (s->type != t->type) {
			log_dbg(cd, "segment type mismatch.");
			r = -EINVAL;
			break;
		}

		switch (s->type) {
		case DM_CRYPT:
			r = _compare_crypt_devices(cd, s, t);
			break;
		case DM_INTEGRITY:
			r = _compare_integrity_devices(cd, s, t);
			break;
		case DM_LINEAR:
			r = (s->u.linear.offset == t->u.linear.offset) ? 0 : -EINVAL;
			break;
		default:
			r = -ENOTSUP;
		}

		if (r)
			break;

		s = s->next;
		t = t->next;
	}

	return r;
}