/*
 * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/include/lustre_capa.h
 *
 * Author: Lai Siyao <lsy@clusterfs.com>
 */

#ifndef __LINUX_CAPA_H_
#define __LINUX_CAPA_H_

/** \defgroup capa capa
 *
 * @{
 */

/*
 * capability
 */
#include <linux/crypto.h>
#include <lustre/lustre_idl.h>

#define CAPA_TIMEOUT 1800		/* sec, == 30 min */
#define CAPA_KEY_TIMEOUT (24 * 60 * 60)  /* sec, == 1 days */

struct capa_hmac_alg {
	const char     *ha_name;
	int	     ha_len;
	int	     ha_keylen;
};

#define DEF_CAPA_HMAC_ALG(name, type, len, keylen)      \
[CAPA_HMAC_ALG_ ## type] = {			    \
	.ha_name	 = name,			\
	.ha_len	  = len,			 \
	.ha_keylen       = keylen,		      \
}

struct client_capa {
	struct inode	     *inode;
	struct list_head		lli_list;     /* link to lli_oss_capas */
};

struct target_capa {
	struct hlist_node	  c_hash;       /* link to capa hash */
};

struct obd_capa {
	struct list_head		c_list;       /* link to capa_list */

	struct lustre_capa	c_capa;       /* capa */
	atomic_t	      c_refc;       /* ref count */
	cfs_time_t		c_expiry;     /* jiffies */
	spinlock_t		c_lock;	/* protect capa content */
	int			c_site;

	union {
		struct client_capa	cli;
		struct target_capa	tgt;
	} u;
};

enum {
	CAPA_SITE_CLIENT = 0,
	CAPA_SITE_SERVER,
	CAPA_SITE_MAX
};

static inline struct lu_fid *capa_fid(struct lustre_capa *capa)
{
	return &capa->lc_fid;
}

static inline __u64 capa_opc(struct lustre_capa *capa)
{
	return capa->lc_opc;
}

static inline __u64 capa_uid(struct lustre_capa *capa)
{
	return capa->lc_uid;
}

static inline __u64 capa_gid(struct lustre_capa *capa)
{
	return capa->lc_gid;
}

static inline __u32 capa_flags(struct lustre_capa *capa)
{
	return capa->lc_flags & 0xffffff;
}

static inline __u32 capa_alg(struct lustre_capa *capa)
{
	return (capa->lc_flags >> 24);
}

static inline __u32 capa_keyid(struct lustre_capa *capa)
{
	return capa->lc_keyid;
}

static inline __u64 capa_key_seq(struct lustre_capa_key *key)
{
	return key->lk_seq;
}

static inline __u32 capa_key_keyid(struct lustre_capa_key *key)
{
	return key->lk_keyid;
}

static inline __u32 capa_timeout(struct lustre_capa *capa)
{
	return capa->lc_timeout;
}

static inline __u32 capa_expiry(struct lustre_capa *capa)
{
	return capa->lc_expiry;
}

void _debug_capa(struct lustre_capa *, struct libcfs_debug_msg_data *,
		 const char *fmt, ... );
#define DEBUG_CAPA(level, capa, fmt, args...)				  \
do {									   \
	if (((level) & D_CANTMASK) != 0 ||				     \
	    ((libcfs_debug & (level)) != 0 &&				  \
	     (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) {	       \
		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, level, NULL);	      \
		_debug_capa((capa), &msgdata, fmt, ##args);		    \
	}								      \
} while (0)

#define DEBUG_CAPA_KEY(level, k, fmt, args...)				 \
do {									   \
CDEBUG(level, fmt " capability key@%p seq "LPU64" keyid %u\n",		 \
       ##args, k, capa_key_seq(k), capa_key_keyid(k));			 \
} while (0)

typedef int (* renew_capa_cb_t)(struct obd_capa *, struct lustre_capa *);

/* obdclass/capa.c */
extern struct list_head capa_list[];
extern spinlock_t capa_lock;
extern int capa_count[];
extern struct kmem_cache *capa_cachep;

struct hlist_head *init_capa_hash(void);
void cleanup_capa_hash(struct hlist_head *hash);

struct obd_capa *capa_add(struct hlist_head *hash,
			  struct lustre_capa *capa);
struct obd_capa *capa_lookup(struct hlist_head *hash,
			     struct lustre_capa *capa, int alive);

int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key);
int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen);
int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen);
void capa_cpy(void *dst, struct obd_capa *ocapa);
static inline struct obd_capa *alloc_capa(int site)
{
	struct obd_capa *ocapa;

	if (unlikely(site != CAPA_SITE_CLIENT && site != CAPA_SITE_SERVER))
		return ERR_PTR(-EINVAL);

	OBD_SLAB_ALLOC_PTR(ocapa, capa_cachep);
	if (unlikely(!ocapa))
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&ocapa->c_list);
	atomic_set(&ocapa->c_refc, 1);
	spin_lock_init(&ocapa->c_lock);
	ocapa->c_site = site;
	if (ocapa->c_site == CAPA_SITE_CLIENT)
		INIT_LIST_HEAD(&ocapa->u.cli.lli_list);
	else
		INIT_HLIST_NODE(&ocapa->u.tgt.c_hash);

	return ocapa;
}

static inline struct obd_capa *capa_get(struct obd_capa *ocapa)
{
	if (!ocapa)
		return NULL;

	atomic_inc(&ocapa->c_refc);
	return ocapa;
}

static inline void capa_put(struct obd_capa *ocapa)
{
	if (!ocapa)
		return;

	if (atomic_read(&ocapa->c_refc) == 0) {
		DEBUG_CAPA(D_ERROR, &ocapa->c_capa, "refc is 0 for");
		LBUG();
	}

	if (atomic_dec_and_test(&ocapa->c_refc)) {
		LASSERT(list_empty(&ocapa->c_list));
		if (ocapa->c_site == CAPA_SITE_CLIENT) {
			LASSERT(list_empty(&ocapa->u.cli.lli_list));
		} else {
			struct hlist_node *hnode;

			hnode = &ocapa->u.tgt.c_hash;
			LASSERT(!hnode->next && !hnode->pprev);
		}
		OBD_SLAB_FREE(ocapa, capa_cachep, sizeof(*ocapa));
	}
}

static inline int open_flags_to_accmode(int flags)
{
	int mode = flags;

	if ((mode + 1) & O_ACCMODE)
		mode++;
	if (mode & O_TRUNC)
		mode |= 2;

	return mode;
}

static inline __u64 capa_open_opc(int mode)
{
	return mode & FMODE_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_READ;
}

static inline void set_capa_expiry(struct obd_capa *ocapa)
{
	cfs_time_t expiry = cfs_time_sub((cfs_time_t)ocapa->c_capa.lc_expiry,
					 cfs_time_current_sec());
	ocapa->c_expiry = cfs_time_add(cfs_time_current(),
				       cfs_time_seconds(expiry));
}

static inline int capa_is_expired_sec(struct lustre_capa *capa)
{
	return (capa->lc_expiry - cfs_time_current_sec() <= 0);
}

static inline int capa_is_expired(struct obd_capa *ocapa)
{
	return cfs_time_beforeq(ocapa->c_expiry, cfs_time_current());
}

static inline int capa_opc_supported(struct lustre_capa *capa, __u64 opc)
{
	return (capa_opc(capa) & opc) == opc;
}

struct filter_capa_key {
	struct list_head	      k_list;
	struct lustre_capa_key  k_key;
};

enum {
	LC_ID_NONE      = 0,
	LC_ID_PLAIN     = 1,
	LC_ID_CONVERT   = 2
};

#define BYPASS_CAPA (struct lustre_capa *)ERR_PTR(-ENOENT)

/** @} capa */

#endif /* __LINUX_CAPA_H_ */
