1/* 2 * GPL HEADER START 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 only, 8 * as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License version 2 for more details (a copy is included 14 * in the LICENSE file that accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License 17 * version 2 along with this program; If not, see 18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf 19 * 20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 21 * CA 95054 USA or visit www.sun.com if you need additional information or 22 * have any questions. 23 * 24 * GPL HEADER END 25 */ 26/* 27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 28 * Use is subject to license terms. 29 * 30 * Copyright (c) 2012, Intel Corporation. 31 */ 32/* 33 * This file is part of Lustre, http://www.lustre.org/ 34 * Lustre is a trademark of Sun Microsystems, Inc. 35 * 36 * lustre/include/lustre_capa.h 37 * 38 * Author: Lai Siyao <lsy@clusterfs.com> 39 */ 40 41#ifndef __LINUX_CAPA_H_ 42#define __LINUX_CAPA_H_ 43 44/** \defgroup capa capa 45 * 46 * @{ 47 */ 48 49/* 50 * capability 51 */ 52#include <linux/crypto.h> 53#include "lustre/lustre_idl.h" 54 55#define CAPA_TIMEOUT 1800 /* sec, == 30 min */ 56#define CAPA_KEY_TIMEOUT (24 * 60 * 60) /* sec, == 1 days */ 57 58struct capa_hmac_alg { 59 const char *ha_name; 60 int ha_len; 61 int ha_keylen; 62}; 63 64#define DEF_CAPA_HMAC_ALG(name, type, len, keylen) \ 65[CAPA_HMAC_ALG_ ## type] = { \ 66 .ha_name = name, \ 67 .ha_len = len, \ 68 .ha_keylen = keylen, \ 69} 70 71struct client_capa { 72 struct inode *inode; 73 struct list_head lli_list; /* link to lli_oss_capas */ 74}; 75 76struct target_capa { 77 struct hlist_node c_hash; /* link to capa hash */ 78}; 79 80struct obd_capa { 81 struct list_head c_list; /* link to capa_list */ 82 83 struct lustre_capa c_capa; /* capa */ 84 atomic_t c_refc; /* ref count */ 85 unsigned long c_expiry; /* jiffies */ 86 spinlock_t c_lock; /* protect capa content */ 87 int c_site; 88 89 union { 90 struct client_capa cli; 91 struct target_capa tgt; 92 } u; 93}; 94 95enum { 96 CAPA_SITE_CLIENT = 0, 97 CAPA_SITE_SERVER, 98 CAPA_SITE_MAX 99}; 100 101static inline struct lu_fid *capa_fid(struct lustre_capa *capa) 102{ 103 return &capa->lc_fid; 104} 105 106static inline __u64 capa_opc(struct lustre_capa *capa) 107{ 108 return capa->lc_opc; 109} 110 111static inline __u64 capa_uid(struct lustre_capa *capa) 112{ 113 return capa->lc_uid; 114} 115 116static inline __u64 capa_gid(struct lustre_capa *capa) 117{ 118 return capa->lc_gid; 119} 120 121static inline __u32 capa_flags(struct lustre_capa *capa) 122{ 123 return capa->lc_flags & 0xffffff; 124} 125 126static inline __u32 capa_alg(struct lustre_capa *capa) 127{ 128 return (capa->lc_flags >> 24); 129} 130 131static inline __u32 capa_keyid(struct lustre_capa *capa) 132{ 133 return capa->lc_keyid; 134} 135 136static inline __u64 capa_key_seq(struct lustre_capa_key *key) 137{ 138 return key->lk_seq; 139} 140 141static inline __u32 capa_key_keyid(struct lustre_capa_key *key) 142{ 143 return key->lk_keyid; 144} 145 146static inline __u32 capa_timeout(struct lustre_capa *capa) 147{ 148 return capa->lc_timeout; 149} 150 151static inline __u32 capa_expiry(struct lustre_capa *capa) 152{ 153 return capa->lc_expiry; 154} 155 156void _debug_capa(struct lustre_capa *, struct libcfs_debug_msg_data *, 157 const char *fmt, ... ); 158#define DEBUG_CAPA(level, capa, fmt, args...) \ 159do { \ 160 if (((level) & D_CANTMASK) != 0 || \ 161 ((libcfs_debug & (level)) != 0 && \ 162 (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) { \ 163 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, level, NULL); \ 164 _debug_capa((capa), &msgdata, fmt, ##args); \ 165 } \ 166} while (0) 167 168#define DEBUG_CAPA_KEY(level, k, fmt, args...) \ 169do { \ 170CDEBUG(level, fmt " capability key@%p seq %llu keyid %u\n", \ 171 ##args, k, capa_key_seq(k), capa_key_keyid(k)); \ 172} while (0) 173 174typedef int (* renew_capa_cb_t)(struct obd_capa *, struct lustre_capa *); 175 176/* obdclass/capa.c */ 177extern struct list_head capa_list[]; 178extern spinlock_t capa_lock; 179extern int capa_count[]; 180extern struct kmem_cache *capa_cachep; 181 182struct hlist_head *init_capa_hash(void); 183void cleanup_capa_hash(struct hlist_head *hash); 184 185struct obd_capa *capa_add(struct hlist_head *hash, 186 struct lustre_capa *capa); 187struct obd_capa *capa_lookup(struct hlist_head *hash, 188 struct lustre_capa *capa, int alive); 189 190int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key); 191int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen); 192int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen); 193void capa_cpy(void *dst, struct obd_capa *ocapa); 194static inline struct obd_capa *alloc_capa(int site) 195{ 196 struct obd_capa *ocapa; 197 198 if (unlikely(site != CAPA_SITE_CLIENT && site != CAPA_SITE_SERVER)) 199 return ERR_PTR(-EINVAL); 200 201 OBD_SLAB_ALLOC_PTR(ocapa, capa_cachep); 202 if (unlikely(!ocapa)) 203 return ERR_PTR(-ENOMEM); 204 205 INIT_LIST_HEAD(&ocapa->c_list); 206 atomic_set(&ocapa->c_refc, 1); 207 spin_lock_init(&ocapa->c_lock); 208 ocapa->c_site = site; 209 if (ocapa->c_site == CAPA_SITE_CLIENT) 210 INIT_LIST_HEAD(&ocapa->u.cli.lli_list); 211 else 212 INIT_HLIST_NODE(&ocapa->u.tgt.c_hash); 213 214 return ocapa; 215} 216 217static inline struct obd_capa *capa_get(struct obd_capa *ocapa) 218{ 219 if (!ocapa) 220 return NULL; 221 222 atomic_inc(&ocapa->c_refc); 223 return ocapa; 224} 225 226static inline void capa_put(struct obd_capa *ocapa) 227{ 228 if (!ocapa) 229 return; 230 231 if (atomic_read(&ocapa->c_refc) == 0) { 232 DEBUG_CAPA(D_ERROR, &ocapa->c_capa, "refc is 0 for"); 233 LBUG(); 234 } 235 236 if (atomic_dec_and_test(&ocapa->c_refc)) { 237 LASSERT(list_empty(&ocapa->c_list)); 238 if (ocapa->c_site == CAPA_SITE_CLIENT) { 239 LASSERT(list_empty(&ocapa->u.cli.lli_list)); 240 } else { 241 struct hlist_node *hnode; 242 243 hnode = &ocapa->u.tgt.c_hash; 244 LASSERT(!hnode->next && !hnode->pprev); 245 } 246 OBD_SLAB_FREE(ocapa, capa_cachep, sizeof(*ocapa)); 247 } 248} 249 250static inline int open_flags_to_accmode(int flags) 251{ 252 int mode = flags; 253 254 if ((mode + 1) & O_ACCMODE) 255 mode++; 256 if (mode & O_TRUNC) 257 mode |= 2; 258 259 return mode; 260} 261 262static inline __u64 capa_open_opc(int mode) 263{ 264 return mode & FMODE_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_READ; 265} 266 267static inline void set_capa_expiry(struct obd_capa *ocapa) 268{ 269 unsigned long expiry = cfs_time_sub((unsigned long)ocapa->c_capa.lc_expiry, 270 get_seconds()); 271 ocapa->c_expiry = cfs_time_add(cfs_time_current(), 272 cfs_time_seconds(expiry)); 273} 274 275static inline int capa_is_expired_sec(struct lustre_capa *capa) 276{ 277 return (capa->lc_expiry - get_seconds() <= 0); 278} 279 280static inline int capa_is_expired(struct obd_capa *ocapa) 281{ 282 return time_before_eq(ocapa->c_expiry, cfs_time_current()); 283} 284 285static inline int capa_opc_supported(struct lustre_capa *capa, __u64 opc) 286{ 287 return (capa_opc(capa) & opc) == opc; 288} 289 290struct filter_capa_key { 291 struct list_head k_list; 292 struct lustre_capa_key k_key; 293}; 294 295enum { 296 LC_ID_NONE = 0, 297 LC_ID_PLAIN = 1, 298 LC_ID_CONVERT = 2 299}; 300 301#define BYPASS_CAPA (struct lustre_capa *)ERR_PTR(-ENOENT) 302 303/** @} capa */ 304 305#endif /* __LINUX_CAPA_H_ */ 306