/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see http://www.gnu.org/licenses
 *
 * Please contact Oracle Corporation, Inc., 500 Oracle Parkway, Redwood Shores,
 * CA 94065 USA or visit www.oracle.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Oracle Corporation, Inc.
 */

#include "../../include/linux/libcfs/libcfs.h"

unsigned long cfs_fail_loc;
EXPORT_SYMBOL(cfs_fail_loc);

unsigned int cfs_fail_val;
EXPORT_SYMBOL(cfs_fail_val);

DECLARE_WAIT_QUEUE_HEAD(cfs_race_waitq);
EXPORT_SYMBOL(cfs_race_waitq);

int cfs_race_state;
EXPORT_SYMBOL(cfs_race_state);

int __cfs_fail_check_set(__u32 id, __u32 value, int set)
{
	static atomic_t cfs_fail_count = ATOMIC_INIT(0);

	LASSERT(!(id & CFS_FAIL_ONCE));

	if ((cfs_fail_loc & (CFS_FAILED | CFS_FAIL_ONCE)) ==
	    (CFS_FAILED | CFS_FAIL_ONCE)) {
		atomic_set(&cfs_fail_count, 0); /* paranoia */
		return 0;
	}

	/* Fail 1/cfs_fail_val times */
	if (cfs_fail_loc & CFS_FAIL_RAND) {
		if (cfs_fail_val < 2 || cfs_rand() % cfs_fail_val > 0)
			return 0;
	}

	/* Skip the first cfs_fail_val, then fail */
	if (cfs_fail_loc & CFS_FAIL_SKIP) {
		if (atomic_inc_return(&cfs_fail_count) <= cfs_fail_val)
			return 0;
	}

	/* check cfs_fail_val... */
	if (set == CFS_FAIL_LOC_VALUE) {
		if (cfs_fail_val != -1 && cfs_fail_val != value)
			return 0;
	}

	/* Fail cfs_fail_val times, overridden by FAIL_ONCE */
	if (cfs_fail_loc & CFS_FAIL_SOME &&
	    (!(cfs_fail_loc & CFS_FAIL_ONCE) || cfs_fail_val <= 1)) {
		int count = atomic_inc_return(&cfs_fail_count);

		if (count >= cfs_fail_val) {
			set_bit(CFS_FAIL_ONCE_BIT, &cfs_fail_loc);
			atomic_set(&cfs_fail_count, 0);
			/* we are lost race to increase  */
			if (count > cfs_fail_val)
				return 0;
		}
	}

	if ((set == CFS_FAIL_LOC_ORSET || set == CFS_FAIL_LOC_RESET) &&
	    (value & CFS_FAIL_ONCE))
		set_bit(CFS_FAIL_ONCE_BIT, &cfs_fail_loc);
	/* Lost race to set CFS_FAILED_BIT. */
	if (test_and_set_bit(CFS_FAILED_BIT, &cfs_fail_loc)) {
		/* If CFS_FAIL_ONCE is valid, only one process can fail,
		 * otherwise multi-process can fail at the same time. */
		if (cfs_fail_loc & CFS_FAIL_ONCE)
			return 0;
	}

	switch (set) {
	case CFS_FAIL_LOC_NOSET:
	case CFS_FAIL_LOC_VALUE:
		break;
	case CFS_FAIL_LOC_ORSET:
		cfs_fail_loc |= value & ~(CFS_FAILED | CFS_FAIL_ONCE);
		break;
	case CFS_FAIL_LOC_RESET:
		cfs_fail_loc = value;
		break;
	default:
		LASSERTF(0, "called with bad set %u\n", set);
		break;
	}

	return 1;
}
EXPORT_SYMBOL(__cfs_fail_check_set);

int __cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set)
{
	int ret;

	ret = __cfs_fail_check_set(id, value, set);
	if (ret) {
		CERROR("cfs_fail_timeout id %x sleeping for %dms\n",
		       id, ms);
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(cfs_time_seconds(ms) / 1000);
		CERROR("cfs_fail_timeout id %x awake\n", id);
	}
	return ret;
}
EXPORT_SYMBOL(__cfs_fail_timeout_set);
