Beispiel #1
0
/**
 * Melt a frozen device.
 *
 * @wdev walb dev.
 * @ctl ioctl data.
 * RETURN:
 *   0 in success, or -EFAULT.
 */
static int ioctl_wdev_melt(struct walb_dev *wdev, struct walb_ctl *ctl)
{
	ASSERT(ctl->command == WALB_IOCTL_MELT);
	LOGn("WALB_IOCTL_MELT\n");

	cancel_melt_work(wdev);
	if (melt_if_frozen(wdev, true)) {
		return 0;
	}
	return -EFAULT;
}
Beispiel #2
0
/**
 * Freeze a walb device.
 * Currently write IOs will be frozen but read IOs will not.
 *
 * @wdev walb dev.
 * @ctl ioctl data.
 * RETURN:
 *   0 in success, or -EFAULT.
 */
static int ioctl_wdev_freeze(struct walb_dev *wdev, struct walb_ctl *ctl)
{
	u32 timeout_sec;

	ASSERT(ctl->command == WALB_IOCTL_FREEZE);
	LOGn("WALB_IOCTL_FREEZE\n");

	/* Clip timeout value. */
	timeout_sec = ctl->val_u32;
	if (timeout_sec > 86400) {
		timeout_sec = 86400;
		LOGn("Freeze timeout has been cut to %"PRIu32" seconds.\n",
			timeout_sec);
	}

	cancel_melt_work(wdev);
	if (freeze_if_melted(wdev, timeout_sec)) {
		return 0;
	}
	return -EFAULT;
}
Beispiel #3
0
/**
 * Melt a device if frozen.
 *
 * RETURN:
 *   true in success, or false (due to race condition).
 */
bool melt_if_frozen(
	struct walb_dev *wdev, bool restarts_checkpointing)
{
	unsigned int minor;

	ASSERT(wdev);
	minor = MINOR(wdev->devt);

	cancel_melt_work(wdev);

	/* Melt the device if required. */
	mutex_lock(&wdev->freeze_lock);
	switch (wdev->freeze_state) {
	case FRZ_MELTED:
		/* Do nothing. */
		LOGn("Already melted minor %u\n", minor);
		break;
	case FRZ_FREEZED:
		/* Melt. */
		LOGn("Melt walb device minor %u.\n", minor);
		if (restarts_checkpointing) {
			start_checkpointing(&wdev->cpd);
		}
		iocore_melt(wdev);
		wdev->freeze_state = FRZ_MELTED;
		break;
	case FRZ_FREEZED_WITH_TIMEOUT:
		/* Race condition. */
		LOGe("Race condition occurred.\n");
		mutex_unlock(&wdev->freeze_lock);
		return false;
	default:
		BUG();
	}
	ASSERT(wdev->freeze_state == FRZ_MELTED);
	mutex_unlock(&wdev->freeze_lock);
	return true;
}