Whamcloud - gitweb
83b1255c708d3d09085eebd1a493ff2fb4e06db9
[fs/lustre-release.git] / lustre / llite / llite_gs.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2004, 2005 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #define DEBUG_SUBSYSTEM S_LLITE
23
24 #include <linux/fs.h>
25 #include <linux/types.h>
26 #include <linux/version.h>
27 #include <asm/uaccess.h>
28 #include <linux/file.h>
29 #include <linux/kmod.h>
30 #include <linux/posix_acl.h>
31 #include <linux/xattr_acl.h>
32
33 #include <linux/lustre_acl.h>
34 #include <linux/lustre_lite.h>
35 #include <linux/lustre_gs.h>
36 #include "llite_internal.h"
37
38 int ll_gs_intent_init(struct lookup_intent *it)
39 {
40         struct lustre_intent_data *lustre_data;
41         
42         LASSERT(it->d.fs_data != NULL); 
43         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
44         /*set lustre key size when there is gss server 
45          *or other configuration*/ 
46         lustre_data->it_key = NULL;
47         lustre_data->it_key_size = 0;
48         RETURN(0);
49 }
50
51 static int ll_get_acl_key(struct inode *inode, struct posix_acl **acl,
52                           struct lustre_key **lkey) 
53 {
54         struct lookup_intent it = { .it_op = IT_GETATTR };
55         struct dentry de = { .d_inode = inode };
56         struct ll_sb_info *sbi;
57         struct lustre_id id;
58         struct ptlrpc_request *req = NULL;
59         struct ll_inode_info *lli = ll_i2info(inode);
60         int rc = 0;
61         ENTRY;
62
63         if (lli->lli_posix_acl && lli->lli_key_info) {
64                 /*If they are in the local cache, just fetch them*/
65                 spin_lock(&lli->lli_lock);
66                 *acl = posix_acl_dup(lli->lli_posix_acl);
67                 *lkey =  lustre_key_get(lli->lli_key_info);
68                 spin_unlock(&lli->lli_lock);
69                 RETURN(rc);
70         }
71         sbi = ll_i2sbi(inode);
72         ll_inode2id(&id, inode);
73
74         if (ll_intent_alloc(&it))
75                 RETURN(-EACCES);
76
77         rc = md_intent_lock(sbi->ll_md_exp, &id, NULL, 0, NULL, 0, &id,
78                             &it, 0, &req, ll_mdc_blocking_ast);
79         if (rc < 0) {
80                 ll_intent_free(&it);
81                 GOTO(out, rc);
82         }
83
84         rc = revalidate_it_finish(req, 1, &it, &de);
85         if (rc) {
86                 ll_intent_release(&it);
87                 GOTO(out, rc);
88         }
89
90         ll_lookup_finish_locks(&it, &de);
91         ll_intent_free(&it);
92
93         spin_lock(&lli->lli_lock);
94         *acl = posix_acl_dup(lli->lli_posix_acl);
95         *lkey =  lustre_key_get(lli->lli_key_info);
96         spin_unlock(&lli->lli_lock);
97 out:
98         if (req)
99                 ptlrpc_req_finished(req);        
100         RETURN(rc);
101 }
102
103 static int ll_init_key_perm(struct key_perm *kperm, struct posix_acl *acl, 
104                             __u32 uid, __u32 gid, int mode) 
105 {
106         if (acl) {
107                 kperm->kp_acl_count = acl->a_count;
108                 memcpy(kperm->kp_acls, acl->a_entries, 
109                        acl->a_count * sizeof(struct posix_acl_entry));
110         }
111         kperm->kp_mode = mode;
112         kperm->kp_uid = uid;
113         kperm->kp_gid = gid;
114         RETURN(0);
115 }
116
117 static int ll_init_key_context(struct key_context *pkc, __u32 uid, 
118                                 __u32 gid, struct crypto_key *ck, 
119                                 struct posix_acl *acl,  int mode, 
120                                 int command, int valid)
121 {
122         struct key_perm *kperm;
123         ENTRY;
124
125         pkc->kc_command = command;
126         pkc->kc_valid = valid;
127
128         if (ck)
129                 memcpy(&pkc->kc_ck, ck, sizeof(*ck));
130
131         kperm = &pkc->kc_perm;      
132  
133         ll_init_key_perm(kperm, acl, uid, gid, mode);  
134         RETURN(0);
135 }
136 static int ll_get_default_acl(struct inode *inode, struct posix_acl **acl, 
137                               mode_t mode) 
138 {
139         int rc = 0, buf_size, ea_size;
140         char *buf = NULL;
141         ENTRY;
142
143         if (!S_ISDIR(inode->i_mode))
144                 RETURN(0);
145  
146         buf_size = xattr_acl_size(LL_ACL_MAX_ENTRIES);
147         OBD_ALLOC(buf, buf_size);
148         if (!buf)
149                 RETURN(-ENOMEM);
150
151         ea_size = ll_getxattr_internal(inode, XATTR_NAME_ACL_DEFAULT, 
152                                        buf, buf_size, OBD_MD_FLXATTR);
153         if (ea_size <= 0) {
154                 if (ea_size < 0 && ea_size != -ENODATA)
155                         CERROR("get default acl of ino %lu error rc %d \n",
156                                 inode->i_ino, ea_size);
157                 GOTO(out, rc = 0);       
158         }
159         *acl = posix_acl_from_xattr(buf, ea_size);
160         if (IS_ERR(*acl)) {
161                 rc = PTR_ERR(*acl);
162                 CERROR("convert xattr to acl failed: %d\n", rc);
163                 GOTO(out, rc);
164         } else if (*acl) {
165                 rc = posix_acl_valid(*acl);
166                 if (rc) {
167                         CERROR("acl valid error: %d\n", rc);
168                         posix_acl_release(*acl);
169                         GOTO(out, rc);
170                 }
171         }
172         
173         rc = posix_acl_create_masq(*acl, &mode); 
174 out:
175         if (buf) 
176                 OBD_FREE(buf, buf_size);
177         RETURN(rc);
178 }
179
180 int ll_gks_create_key(struct inode *dir, mode_t mode, void **key, 
181                       int* key_size)
182 {
183         struct obd_export *gs_exp = ll_i2gsexp(dir);
184         struct key_context *kcontext = NULL;
185         struct key_parms   kparms;
186         struct posix_acl *default_acl = NULL;       
187         int    rc = 0;  
188         ENTRY;
189  
190         OBD_ALLOC(kcontext, sizeof(struct key_context));
191         if (!kcontext)
192                 GOTO(out, rc = -ENOMEM);
193
194         rc = ll_get_default_acl(dir, &default_acl, mode);
195         if (rc)
196                 GOTO(out, rc);       
197  
198         ll_init_key_context(kcontext, current->fsuid, current->fsgid, 
199                             NULL, default_acl, mode, GKS_GET_KEY, 0);
200        
201         kparms.context = kcontext;
202         kparms.context_size = sizeof(struct key_context);
203         kparms.perm = NULL;
204        
205         *key_size = sizeof(struct crypto_key);
206         OBD_ALLOC(*key, *key_size);
207         if (!*key)
208                 GOTO(out, rc = -ENOMEM);
209  
210         /*GET an encrypt key from GS server*/
211         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
212                           key_size, *key);
213         if (rc) {
214                 CERROR("get key error rc %d \n", rc);
215                 GOTO(out, rc);
216         }
217         CDEBUG(D_INFO, "Get enkey %s MAC %s from exp %p \n", 
218                (char*)((struct crypto_key *)(*key))->ck_key, 
219                (char*)((struct crypto_key *)(*key))->ck_mac, 
220                gs_exp);
221 out:
222         if (kcontext)
223                 OBD_FREE(kcontext, sizeof(struct key_context));
224         if (default_acl)
225                 posix_acl_release(default_acl);
226         RETURN(rc);
227
228 }
229  
230 int ll_gks_init_it(struct inode *parent, struct lookup_intent *it)
231 {
232         struct obd_export *gs_exp = ll_i2gsexp(parent);
233         struct lustre_intent_data *lustre_data;
234         mode_t mode = (it->it_create_mode | S_IFREG) & (~current->fs->umask);
235         void *key = NULL;
236         int key_size = 0, rc = 0;
237         ENTRY;
238  
239         if (!gs_exp || !it)
240                 RETURN(rc);
241
242         ll_gs_intent_init(it);
243         if (!(it->it_op & IT_CREAT))
244                 RETURN(rc);
245
246         LASSERT(it->d.fs_data != NULL); 
247         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
248           
249         if (lustre_data->it_key) {
250                 LASSERT(lustre_data->it_key_size == 
251                          sizeof(struct crypto_key));
252                 OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
253         }
254
255         rc = ll_gks_create_key(parent, mode, &key, &key_size); 
256         if (rc)
257                 GOTO(out, rc);
258
259         lustre_data->it_key = key; 
260         lustre_data->it_key_size = key_size; 
261 out:
262         if (rc) {
263                 if (key && key_size)
264                         OBD_FREE(key, key_size);
265         }
266         RETURN(rc); 
267 }
268
269 int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
270 {
271         struct obd_export *gs_exp = ll_i2gsexp(inode);
272         struct ll_inode_info *lli = ll_i2info(inode);
273         struct key_context *kcontext = NULL;
274         struct key_perm *kperm = NULL;
275         struct key_parms kparms;
276         struct lustre_key *lkey =  NULL;
277         struct crypto_key *ckey = NULL;
278         struct posix_acl *acl = NULL;
279         __u32 flags = 0; 
280         int rc = 0, ck_size = 0, kcontext_size = 0, acl_count;
281         
282         ENTRY;
283  
284         if (!gs_exp)
285                 RETURN(rc);
286        
287         rc = ll_get_acl_key(inode, &acl, &lkey);
288         if (rc)
289                 GOTO(out, rc);       
290         if (!lkey || IS_DECRYPTED(lkey->lk_flags))
291                 GOTO(out, rc = 0);
292        
293         acl_count = acl ? acl->a_count : 0;  
294         kcontext_size = crypto_kcontext_size(acl_count); 
295         OBD_ALLOC(kcontext, kcontext_size);
296         if (!kcontext)
297                 GOTO(out, rc = -ENOMEM);
298         
299         flags = mds_pack_open_flags(it->it_flags); 
300
301         spin_lock(&lli->lli_lock); 
302         ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
303                             acl, inode->i_mode, GKS_DECRYPT_KEY, flags);
304        
305         spin_unlock(&lli->lli_lock); 
306         
307         OBD_ALLOC(kperm, sizeof(struct key_perm));
308         ll_init_key_perm(kperm, NULL, current->uid, current->gid, 0);
309     
310         kparms.context = kcontext;
311         kparms.context_size = kcontext_size;
312         kparms.perm = kperm;       
313         kparms.perm_size = sizeof(struct key_perm); 
314
315         ck_size = sizeof(*ckey);
316         OBD_ALLOC(ckey, ck_size);
317         if (!ckey)
318                 GOTO(out, rc = -ENOMEM);
319  
320         /*GET an encrypt key from GS server*/
321         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
322                           &ck_size, ckey);
323         if (rc) {
324                 CERROR("decrypt key error rc %d \n", rc);
325                 GOTO(out, rc);
326         }
327         CDEBUG(D_INFO, "decrypt key %s MAC %s from exp %p \n", 
328                ckey->ck_mac, ckey->ck_mac, gs_exp);        
329       
330         /*copy the decrypt key from kcontext to the lustre key*/
331         
332         spin_lock(&lli->lli_lock); 
333         memcpy(&lkey->lk_ck, ckey, sizeof(*ckey));
334         SET_DECRYPTED(lkey->lk_flags);
335         spin_unlock(&lli->lli_lock); 
336 out:
337         if (acl)
338                 posix_acl_release(acl);
339         if (lkey)
340                 lustre_key_release(lkey); 
341         if (kperm)
342                 OBD_FREE(kperm, sizeof(struct key_perm));
343         if (kcontext)
344                 OBD_FREE(kcontext, kcontext_size);
345         if (ckey)
346                 OBD_FREE(ckey, ck_size);
347         RETURN(rc); 
348 }
349 static void get_real_parameters(struct inode *inode, struct iattr *iattr,
350                                 struct posix_acl *new_acl, mode_t *mode,   
351                                 __u32 *uid, __u32 *gid)
352
353         LASSERT(iattr);
354
355         if (iattr->ia_valid & ATTR_MODE) {
356                 *mode = iattr->ia_mode;
357         } else {
358                 *mode = inode->i_mode;
359                 if (new_acl) {
360                         posix_acl_equiv_mode(new_acl, mode);
361                         CDEBUG(D_INFO, "get new mode %d \n", *mode);
362                 } 
363         }
364
365         if (iattr->ia_valid & ATTR_UID)
366                 *uid = iattr->ia_uid;
367         else 
368                 *uid = inode->i_uid;
369
370         if (iattr->ia_valid & ATTR_GID)
371                 *gid = iattr->ia_gid;
372         else
373                 *gid = inode->i_gid;
374 }
375
376 int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value, 
377                    int size, void **key, int *key_size)
378 {
379         struct ll_inode_info *lli = ll_i2info(inode);
380         struct obd_export *gs_exp = ll_i2gsexp(inode);
381         struct key_context *kcontext = NULL;
382         struct key_perm *kperm = NULL;
383         struct key_parms kparms;
384         struct lustre_key *lkey =  NULL;
385         struct posix_acl *acl = NULL, *new_acl = NULL; 
386         int rc = 0,  kperm_size = 0, kcontext_size = 0; 
387         mode_t mac_mode;
388         __u32 uid, gid;
389         int acl_count = 0;
390         
391         ENTRY;
392  
393         if (!gs_exp)
394                 RETURN(rc);
395        
396         rc = ll_get_acl_key(inode, &acl, &lkey);
397         if (rc)
398                 GOTO(out, rc);       
399         if (!lkey)
400                 RETURN(rc);
401         
402         acl_count = acl ? acl->a_count : 0;  
403         kcontext_size = crypto_kcontext_size(acl_count); 
404         OBD_ALLOC(kcontext, kcontext_size);
405         if (!kcontext)
406                 GOTO(out, rc = -ENOMEM);
407         spin_lock(&lli->lli_lock);
408         ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
409                             acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid);
410         spin_unlock(&lli->lli_lock);
411         if (value) {
412                 new_acl = posix_acl_from_xattr(value, size); 
413                 if (IS_ERR(new_acl)) {
414                         rc = PTR_ERR(new_acl);
415                         CERROR("convert from xattr to acl error: %d",rc);
416                         new_acl = NULL;
417                         GOTO(out, rc);
418                 } else if (new_acl) {
419                         rc = posix_acl_valid(new_acl);
420                         if (rc) {
421                                 CERROR("acl valid error: %d", rc);
422                                 GOTO(out, rc);
423                         }
424                 }
425         } 
426         acl_count = new_acl ? new_acl->a_count : 0;  
427         kperm_size = crypto_kperm_size(acl_count);
428         OBD_ALLOC(kperm, kperm_size);
429         get_real_parameters(inode, iattr, new_acl, &mac_mode, &uid, &gid);
430         ll_init_key_perm(kperm, new_acl, uid, gid, mac_mode);
431         kparms.context = kcontext;
432         kparms.context_size = kcontext_size;
433         kparms.perm = kperm;       
434         kparms.perm_size = kperm_size; 
435
436         *key_size = sizeof(struct crypto_key);
437         OBD_ALLOC(*key, *key_size);
438         if (!*key)
439                 GOTO(out, rc = -ENOMEM);
440         /*GET an encrypt key from GS server*/
441         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
442                           key_size, *key);
443         if (rc) {
444                 CERROR("decrypt key error rc %d \n", rc);
445                 GOTO(out, rc);
446         }
447                         printk("come here 5\n"); 
448         /*copy the decrypt key from kcontext to the lustre key*/
449         spin_lock(&lli->lli_lock);
450         memcpy(&lkey->lk_ck, *key, *key_size);
451         iattr->ia_valid |= ATTR_MAC;
452         spin_unlock(&lli->lli_lock);
453 out:
454         if (acl)
455                 posix_acl_release(acl);
456         if (new_acl)
457                 posix_acl_release(new_acl);
458         if (lkey)
459                 lustre_key_release(lkey); 
460         if (kperm)
461                 OBD_FREE(kperm, kperm_size);
462         if (kcontext)
463                 OBD_FREE(kcontext, kcontext_size);
464         RETURN(rc); 
465 }
466
467 /*key function for calculate the key for countermode method*/
468 static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
469                        int flags)
470 {
471         struct inode *inode = page->mapping->host;
472         struct ll_inode_info *lli = ll_i2info(inode);
473         struct lustre_key *lkey = ll_i2info(inode)->lli_key_info;
474         unsigned char *ptr;
475         char *key_ptr;
476         int index = page->index;
477         __u64 data_key = 0; 
478         int i;
479         ENTRY;
480
481         if (!lkey)
482                 RETURN(0);
483         if (!IS_DECRYPTED(lkey->lk_flags))
484                 RETURN(-EFAULT);
485         if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags))
486                 RETURN(-EFAULT);
487         if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags))
488                 RETURN(-EFAULT);
489         
490         /*FIXME: tmp calculate method, should calculate 
491           the key according to KEY_TYPE*/
492         
493         spin_lock(&lli->lli_lock);
494         key_ptr = &lkey->lk_ck.ck_key[0];
495         for (i=0; i < KEY_SIZE; i++) 
496                 data_key += *key_ptr++; 
497         spin_unlock(&lli->lli_lock);
498         data_key += index;
499
500         CDEBUG(D_INFO, "data_key is "LPU64" \n", data_key);
501         /*encrypt the data*/
502         ptr = (char *)kmap(page);
503         key_ptr = ptr;
504         ptr += offset; 
505         CDEBUG(D_INFO, "ptr is %s \n", ptr);
506         for (i = 0; i < count; i++) 
507                 *ptr++ ^= (__u8)data_key; 
508         CDEBUG(D_INFO, "encrypted ptr is %s \n", key_ptr);
509         kunmap(page);
510         
511         RETURN(0); 
512
513
514 int ll_gs_init_inode_key(struct inode *inode, void  *mkey)
515 {
516         struct ll_inode_info *lli = ll_i2info(inode);
517         struct crypto_key *key = (struct crypto_key*)mkey;
518         struct lustre_key *lkey = NULL;
519         ENTRY;        
520
521         if (!key)
522                 RETURN(0);
523         
524         if (lli->lli_key_info == NULL) {
525                 OBD_ALLOC(lkey, sizeof(struct lustre_key));
526                 if (!lkey)
527                         RETURN(-ENOMEM); 
528                 memcpy(&lkey->lk_ck, key, sizeof(*key));
529                 atomic_set(&lkey->lk_refcount, 1);
530                 SET_UNDECRYPTED(lkey->lk_flags); 
531                 ENABLE_ENCRYPT(lkey->lk_flags);  
532                 ENABLE_DECRYPT(lkey->lk_flags); 
533                 spin_lock(&lli->lli_lock);
534                 lli->lli_key_info = lkey; 
535                 spin_unlock(&lli->lli_lock);
536         } else {
537                 lkey = lustre_key_get(lli->lli_key_info);
538                 if (!IS_DECRYPTED(lkey->lk_flags)) {
539                         if (memcmp(&lkey->lk_ck, key, sizeof(*key))) {
540                                 CWARN("already have key_info %p in ino %ld \n",
541                                       lli->lli_key_info, inode->i_ino);
542                         }
543                 } else {
544                         spin_lock(&lli->lli_lock);
545                         SET_UNDECRYPTED(lkey->lk_flags); 
546                         memcpy(&lkey->lk_ck, key, sizeof(*key));
547                         spin_unlock(&lli->lli_lock);
548                 }
549                 lustre_key_release(lkey);
550         }
551         CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", 
552                lli->lli_key_info->lk_ck.ck_mac, 
553                lli->lli_key_info->lk_ck.ck_key, 
554                inode->i_ino);
555         RETURN(0);
556 }
557
558 static int ll_gs_destroy_key(struct inode *inode)
559 {
560         struct ll_inode_info *lli = ll_i2info(inode);
561        
562         spin_lock(&lli->lli_lock);
563         if (lli->lli_key_info) {
564                 LASSERTF(atomic_read(&lli->lli_key_info->lk_refcount) == 1, 
565                          "lk_refcount %d != 1 when destory\n", 
566                          atomic_read(&lli->lli_key_info->lk_refcount));
567                 lustre_key_release(lli->lli_key_info);
568                 lli->lli_key_info = NULL;
569         }
570         spin_unlock(&lli->lli_lock);
571         RETURN(0);
572 }
573
574 struct crypto_helper_ops ll_cgs_ops = { 
575        .init_it_key     = ll_gks_init_it,
576        .create_key      = ll_gks_create_key,
577        .init_inode_key  = ll_gs_init_inode_key, 
578        .get_mac         = ll_gks_get_mac,
579        .decrypt_key     = ll_gks_decrypt_key, 
580        .destroy_key     = ll_gs_destroy_key,
581 };
582
583 int ll_mks_create_key(struct inode *inode, struct lookup_intent *it)
584 {
585         struct lustre_intent_data *lustre_data;
586         struct crypto_key         *crypto_key;
587         int    rc = 0;       
588         ENTRY;
589        
590         LASSERT(it->d.fs_data != NULL); 
591         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
592        
593         if (lustre_data->it_key) {
594                 OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
595         }
596         OBD_ALLOC(crypto_key, sizeof(struct crypto_key));
597        
598         crypto_key->ck_type = MKS_TYPE;
599         lustre_data->it_key = crypto_key; 
600         lustre_data->it_key_size = sizeof(struct crypto_key); 
601         RETURN(rc);
602 }
603
604 int ll_mks_init_it(struct inode *parent, struct lookup_intent *it)
605 {
606         int rc = 0;
607         ENTRY;
608  
609         if (!it)
610                 RETURN(0);
611
612         ll_gs_intent_init(it);
613         if (it->it_op & IT_CREAT) {
614                 ll_mks_create_key(parent, it);
615         }
616         RETURN(rc); 
617 }
618
619 int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it)
620 {
621         struct ll_inode_info *lli = ll_i2info(inode);
622         struct lustre_key *lkey =  NULL;
623         struct posix_acl *acl = NULL;
624         int rc = 0;
625         
626         ENTRY;
627  
628         rc = ll_get_acl_key(inode, &acl, &lkey);
629         if (rc || !lkey)
630                 GOTO(out, rc);      
631         spin_lock(&lli->lli_lock); 
632         SET_DECRYPTED(lkey->lk_flags); 
633         spin_unlock(&lli->lli_lock); 
634 out:
635         if (acl)
636                 posix_acl_release(acl);
637         if (lkey)
638                 lustre_key_release(lkey); 
639         RETURN(rc);
640 }
641
642 struct crypto_helper_ops ll_cmd_ops = { 
643        .init_it_key     = ll_mks_init_it,
644        .init_inode_key  = ll_gs_init_inode_key, 
645        .decrypt_key     = ll_mks_decrypt_key,
646        .destroy_key     = ll_gs_destroy_key,
647 };
648
649
650 static int ll_register_cops(struct ll_crypto_info *llci, char *type,
651                             struct crypto_helper_ops *cops)
652 {
653         struct list_head *list = &llci->ll_cops_list;
654         struct crypto_ops_item *opi = NULL, *tmp;
655         char   *opi_name = NULL;        
656         int rc = 0;
657         ENTRY;
658         
659         list_for_each_entry(tmp, list, clist) {
660                 if (!strcmp(type, tmp->ctype)) {
661                         CWARN("%s is already registered\n", type);
662                         rc = -EEXIST;
663                         GOTO(exit, rc); 
664                 }
665         }
666         
667         OBD_ALLOC(opi, sizeof(*opi));
668        
669         OBD_ALLOC(opi_name, strlen(type) + 1); 
670        
671         LASSERT(opi && opi_name);
672
673         memcpy(opi_name, type, strlen(type));
674
675         opi->ctype = opi_name;
676         opi->cops = cops;
677   
678         list_add_tail(&opi->clist, list);
679 exit:
680         RETURN(rc);
681 }
682
683 static int ll_init_sb_crypto(struct super_block *sb)
684 {
685         struct ll_crypto_info *llci = NULL;
686         int rc = 0;
687         ENTRY;
688
689         OBD_ALLOC(llci, sizeof(*llci));
690         
691         if (!llci)
692                 RETURN(-ENOMEM);
693
694         INIT_LIST_HEAD(&llci->ll_cops_list);
695         
696         ll_register_cops(llci, "gks", &ll_cgs_ops);
697         ll_register_cops(llci, "mks", &ll_cmd_ops);
698
699         ll_s2sbi(sb)->ll_crypto_info = llci;
700
701         RETURN(rc);
702 }         
703
704 static int ll_unregister_cops(struct ll_crypto_info *llci)
705 {
706         struct list_head *list = &llci->ll_cops_list;
707         struct crypto_ops_item *tmp, *item;
708
709         list_for_each_entry_safe(item, tmp, list, clist) {       
710                 list_del_init(&item->clist);       
711                 OBD_FREE(item->ctype, strlen(item->ctype) + 1);
712                 OBD_FREE(item, sizeof(*item));
713         }
714         RETURN(0);
715 }
716
717 int lustre_destroy_crypto(struct super_block *sb)
718 {
719         struct ll_crypto_info *llci = ll_s2crpi(sb);
720         ENTRY;       
721
722         if (!llci)
723                 RETURN(0);
724
725         if (llci->ll_gt_exp)
726                 obd_disconnect(llci->ll_gt_exp, 0);
727  
728         ll_unregister_cops(llci);
729         OBD_FREE(llci, sizeof(*llci)); 
730         RETURN(0);
731 }
732
733 int lustre_init_crypto(struct super_block *sb, char *gkc, 
734                        struct obd_connect_data *data,
735                        int async)
736 {
737         struct obd_device *obd = NULL;
738         struct ll_sb_info *sbi = ll_s2sbi(sb);
739         struct lustre_handle gt_conn;
740         int rc = 0;
741         ENTRY;
742
743         rc = ll_init_sb_crypto(sb);
744         if (rc)
745                 RETURN(rc);
746
747         if (!gkc || !strcmp(gkc, "null")) {
748                 CDEBUG(D_INFO, "No gks Server\n"); 
749                 RETURN(rc);
750         }
751         
752         obd = class_name2obd(gkc);
753         if (!obd) {
754                 CERROR("GSC %s: not setup or attached\n", gkc);
755                 GOTO(out, rc = -EINVAL);
756         }
757         
758         obd_set_info(obd->obd_self_export, strlen("async"), "async",
759                      sizeof(async), &async);
760         
761         rc = obd_connect(&gt_conn, obd, &sbi->ll_sb_uuid, data,
762                           OBD_OPT_REAL_CLIENT);
763         if (rc) {
764                 CERROR("cannot connect to %s: rc = %d\n", gkc, rc);
765                 GOTO(out, rc);
766         }
767         ll_s2crpi(sb)->ll_gt_exp = class_conn2export(&gt_conn);
768 out:
769         if (rc)
770                 lustre_destroy_crypto(sb); 
771         RETURN(rc);
772 }
773 struct crypto_helper_ops *
774 ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type)
775 {
776         struct list_head *list = &llc_info->ll_cops_list;
777         struct crypto_ops_item *tmp;
778         ENTRY;
779
780         list_for_each_entry(tmp, list, clist) {
781                 if (!strcmp(type, tmp->ctype)) {
782                         EXIT;
783                         return (tmp->cops);            
784                 }
785         }
786         CERROR("can not find crypto api %s \n", type);
787         RETURN(NULL);
788 }
789
790 int ll_set_sb_gksinfo(struct super_block *sb, char *type)
791 {
792         struct ll_crypto_info *llci = ll_s2crpi(sb);
793         struct obd_export *md_exp = ll_s2mdexp(sb);
794         struct obd_export *dt_exp = ll_s2dtexp(sb);
795         struct crypto_helper_ops *ops;
796         int rc = 0;
797         ENTRY;
798         
799         /*try to find the helper ops according to the type*/
800         ops = ll_gks_find_ops(llci, type);
801         if (!ops) {
802                 CERROR("can not find the crypto ops by type %s \n", type);
803                 RETURN(-EINVAL);
804         }
805         llci->ll_cops = ops;
806         /*set crypto type */
807         rc = obd_set_info(md_exp, strlen("crypto_type"), "crypto_type",
808                           strlen(type), type);
809
810         /*set crypt call back func*/
811
812         rc = obd_set_info(dt_exp, strlen("crypto_cb"), "crypto_cb",
813                           sizeof(crypt_cb_t), &ll_crypt_cb);
814   
815         RETURN(rc);
816 }
817