/*
 * 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/gpl-2.0.html
 *
 * 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 Sun Microsystems, Inc.
 *
 * lustre/ptlrpc/sec_gc.c
 *
 * Author: Eric Mei <ericm@clusterfs.com>
 */

#define DEBUG_SUBSYSTEM S_SEC

#include <linux/libcfs/libcfs.h>

#include <obd_support.h>
#include <obd_class.h>
#include <lustre_net.h>
#include <lustre_sec.h>

#include "ptlrpc_internal.h"

#define SEC_GC_INTERVAL (30 * 60)

static struct mutex sec_gc_mutex;
static LIST_HEAD(sec_gc_list);
static spinlock_t sec_gc_list_lock;

static LIST_HEAD(sec_gc_ctx_list);
static spinlock_t sec_gc_ctx_list_lock;

static struct ptlrpc_thread sec_gc_thread;
static atomic_t sec_gc_wait_del = ATOMIC_INIT(0);

void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec)
{
	LASSERT(sec->ps_policy->sp_cops->gc_ctx);
	LASSERT(sec->ps_gc_interval > 0);
	LASSERT(list_empty(&sec->ps_gc_list));

	sec->ps_gc_next = ktime_get_real_seconds() + sec->ps_gc_interval;

	spin_lock(&sec_gc_list_lock);
	list_add_tail(&sec->ps_gc_list, &sec_gc_list);
	spin_unlock(&sec_gc_list_lock);

	CDEBUG(D_SEC, "added sec %p(%s)\n", sec, sec->ps_policy->sp_name);
}

void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec)
{
	if (list_empty(&sec->ps_gc_list))
		return;

	might_sleep();

	/* signal before list_del to make iteration in gc thread safe */
	atomic_inc(&sec_gc_wait_del);

	spin_lock(&sec_gc_list_lock);
	list_del_init(&sec->ps_gc_list);
	spin_unlock(&sec_gc_list_lock);

	/* barrier */
	mutex_lock(&sec_gc_mutex);
	mutex_unlock(&sec_gc_mutex);

	atomic_dec(&sec_gc_wait_del);

	CDEBUG(D_SEC, "del sec %p(%s)\n", sec, sec->ps_policy->sp_name);
}

static void sec_process_ctx_list(void)
{
	struct ptlrpc_cli_ctx *ctx;

	spin_lock(&sec_gc_ctx_list_lock);

	while (!list_empty(&sec_gc_ctx_list)) {
		ctx = list_entry(sec_gc_ctx_list.next,
				 struct ptlrpc_cli_ctx, cc_gc_chain);
		list_del_init(&ctx->cc_gc_chain);
		spin_unlock(&sec_gc_ctx_list_lock);

		LASSERT(ctx->cc_sec);
		LASSERT(atomic_read(&ctx->cc_refcount) == 1);
		CDEBUG(D_SEC, "gc pick up ctx %p(%u->%s)\n",
		       ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
		sptlrpc_cli_ctx_put(ctx, 1);

		spin_lock(&sec_gc_ctx_list_lock);
	}

	spin_unlock(&sec_gc_ctx_list_lock);
}

static void sec_do_gc(struct ptlrpc_sec *sec)
{
	LASSERT(sec->ps_policy->sp_cops->gc_ctx);

	if (unlikely(sec->ps_gc_next == 0)) {
		CDEBUG(D_SEC, "sec %p(%s) has 0 gc time\n",
		       sec, sec->ps_policy->sp_name);
		return;
	}

	CDEBUG(D_SEC, "check on sec %p(%s)\n", sec, sec->ps_policy->sp_name);

	if (sec->ps_gc_next > ktime_get_real_seconds())
		return;

	sec->ps_policy->sp_cops->gc_ctx(sec);
	sec->ps_gc_next = ktime_get_real_seconds() + sec->ps_gc_interval;
}

static int sec_gc_main(void *arg)
{
	struct ptlrpc_thread *thread = arg;
	struct l_wait_info lwi;

	unshare_fs_struct();

	/* Record that the thread is running */
	thread_set_flags(thread, SVC_RUNNING);
	wake_up(&thread->t_ctl_waitq);

	while (1) {
		struct ptlrpc_sec *sec;

		thread_clear_flags(thread, SVC_SIGNAL);
		sec_process_ctx_list();
again:
		/* go through sec list do gc.
		 * FIXME here we iterate through the whole list each time which
		 * is not optimal. we perhaps want to use balanced binary tree
		 * to trace each sec as order of expiry time.
		 * another issue here is we wakeup as fixed interval instead of
		 * according to each sec's expiry time
		 */
		mutex_lock(&sec_gc_mutex);
		list_for_each_entry(sec, &sec_gc_list, ps_gc_list) {
			/* if someone is waiting to be deleted, let it
			 * proceed as soon as possible.
			 */
			if (atomic_read(&sec_gc_wait_del)) {
				CDEBUG(D_SEC, "deletion pending, start over\n");
				mutex_unlock(&sec_gc_mutex);
				goto again;
			}

			sec_do_gc(sec);
		}
		mutex_unlock(&sec_gc_mutex);

		/* check ctx list again before sleep */
		sec_process_ctx_list();

		lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * MSEC_PER_SEC),
				  NULL, NULL);
		l_wait_event(thread->t_ctl_waitq,
			     thread_is_stopping(thread) ||
			     thread_is_signal(thread),
			     &lwi);

		if (thread_test_and_clear_flags(thread, SVC_STOPPING))
			break;
	}

	thread_set_flags(thread, SVC_STOPPED);
	wake_up(&thread->t_ctl_waitq);
	return 0;
}

int sptlrpc_gc_init(void)
{
	struct l_wait_info lwi = { 0 };
	struct task_struct *task;

	mutex_init(&sec_gc_mutex);
	spin_lock_init(&sec_gc_list_lock);
	spin_lock_init(&sec_gc_ctx_list_lock);

	/* initialize thread control */
	memset(&sec_gc_thread, 0, sizeof(sec_gc_thread));
	init_waitqueue_head(&sec_gc_thread.t_ctl_waitq);

	task = kthread_run(sec_gc_main, &sec_gc_thread, "sptlrpc_gc");
	if (IS_ERR(task)) {
		CERROR("can't start gc thread: %ld\n", PTR_ERR(task));
		return PTR_ERR(task);
	}

	l_wait_event(sec_gc_thread.t_ctl_waitq,
		     thread_is_running(&sec_gc_thread), &lwi);
	return 0;
}

void sptlrpc_gc_fini(void)
{
	struct l_wait_info lwi = { 0 };

	thread_set_flags(&sec_gc_thread, SVC_STOPPING);
	wake_up(&sec_gc_thread.t_ctl_waitq);

	l_wait_event(sec_gc_thread.t_ctl_waitq,
		     thread_is_stopped(&sec_gc_thread), &lwi);
}
