static int reencrypt_replace_device(struct crypt_device *cd, const char *target, const char *source, uint32_t flags)
{
	int r, exists = 1;
	struct crypt_dm_active_device dmd_source, dmd_target = {};
	uint32_t dmflags = DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH;

	log_dbg(cd, "Replacing table in device %s with table from device %s.", target, source);

	/* check only whether target device exists */
	r = dm_status_device(cd, target);
	if (r < 0) {
		if (r == -ENODEV)
			exists = 0;
		else
			return r;
	}

	r = dm_query_device(cd, source, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER |
			    DM_ACTIVE_CRYPT_KEYSIZE | DM_ACTIVE_CRYPT_KEY, &dmd_source);

	if (r < 0)
		return r;

	if (exists && ((r = dm_query_device(cd, target, 0, &dmd_target)) < 0))
		goto out;

	dmd_source.flags |= flags;
	dmd_source.uuid = crypt_get_uuid(cd);

	if (exists) {
		if (dmd_target.size != dmd_source.size) {
			log_err(cd, _("Source and target device sizes don't match. Source %" PRIu64 ", target: %" PRIu64 "."),
				dmd_source.size, dmd_target.size);
			r = -EINVAL;
			goto out;
		}
		r = dm_reload_device(cd, target, &dmd_source, 0, 0);
		if (!r) {
			log_dbg(cd, "Resuming device %s", target);
			r = dm_resume_device(cd, target, dmflags | act2dmflags(dmd_source.flags));
		}
	} else
		r = dm_create_device(cd, target, CRYPT_SUBDEV, &dmd_source);
out:
	dm_targets_free(cd, &dmd_source);
	dm_targets_free(cd, &dmd_target);

	return r;
}
static int reencrypt_replace_device(struct crypt_device *cd, const char *target, const char *source, uint32_t flags)
{
	int r, exists = 1;
	struct crypt_dm_active_device dmd_source, dmd_target = {};
	uint32_t dmflags = DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH;

	log_dbg(cd, "Replacing table in device %s with table from device %s.", target, source);

	 
	r = dm_status_device(cd, target);
	if (r < 0) {
		if (r == -ENODEV)
			exists = 0;
		else
			return r;
	}

	r = dm_query_device(cd, source, DM_ACTIVE_DEVICE | DM_ACTIVE_CRYPT_CIPHER |
			    DM_ACTIVE_CRYPT_KEYSIZE | DM_ACTIVE_CRYPT_KEY, &dmd_source);

	if (r < 0)
		return r;

	if (exists && ((r = dm_query_device(cd, target, 0, &dmd_target)) < 0))
		goto out;

	dmd_source.flags |= flags;
	dmd_source.uuid = crypt_get_uuid(cd);

	if (exists) {
		if (dmd_target.size != dmd_source.size) {
			log_err(cd, _("Source and target device sizes don't match. Source %" PRIu64 ", target: %" PRIu64 "."),
				dmd_source.size, dmd_target.size);
			r = -EINVAL;
			goto out;
		}
		r = dm_reload_device(cd, target, &dmd_source, 0, 0);
		if (!r) {
			log_dbg(cd, "Resuming device %s", target);
			r = dm_resume_device(cd, target, dmflags | act2dmflags(dmd_source.flags));
		}
	} else
		r = dm_create_device(cd, target, CRYPT_SUBDEV, &dmd_source);
out:
	dm_targets_free(cd, &dmd_source);
	dm_targets_free(cd, &dmd_target);

	return r;
}