Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / lustre / lustre / include / lustre_capa.h
diff --git a/kernel/drivers/staging/lustre/lustre/include/lustre_capa.h b/kernel/drivers/staging/lustre/lustre/include/lustre_capa.h
new file mode 100644 (file)
index 0000000..fe19534
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * 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 */
+       unsigned long           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 %llu 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)
+{
+       unsigned long expiry = cfs_time_sub((unsigned long)ocapa->c_capa.lc_expiry,
+                                        get_seconds());
+       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 - get_seconds() <= 0);
+}
+
+static inline int capa_is_expired(struct obd_capa *ocapa)
+{
+       return time_before_eq(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_ */