Whamcloud - gitweb
Branch: HEAD
[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_flags & O_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_dk, ckey->ck_key, KEY_SIZE);
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 crypto_key *ckey = NULL;
386         struct posix_acl *acl = NULL, *new_acl = NULL; 
387         int rc = 0,  kperm_size = 0, kcontext_size = 0; 
388         mode_t mac_mode;
389         __u32 uid, gid;
390         int acl_count = 0;
391         
392         ENTRY;
393  
394         if (!gs_exp)
395                 RETURN(rc);
396        
397         rc = ll_get_acl_key(inode, &acl, &lkey);
398         if (rc)
399                 GOTO(out, rc);       
400         if (!lkey)
401                 RETURN(rc);
402         
403         acl_count = acl ? acl->a_count : 0;  
404         kcontext_size = crypto_kcontext_size(acl_count); 
405         OBD_ALLOC(kcontext, kcontext_size);
406         if (!kcontext)
407                 GOTO(out, rc = -ENOMEM);
408         spin_lock(&lli->lli_lock);
409         ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
410                             acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid);
411         spin_unlock(&lli->lli_lock);
412         if (value) {
413                 new_acl = posix_acl_from_xattr(value, size); 
414                 if (IS_ERR(new_acl)) {
415                         rc = PTR_ERR(new_acl);
416                         CERROR("convert from xattr to acl error: %d",rc);
417                         new_acl = NULL;
418                         GOTO(out, rc);
419                 } else if (new_acl) {
420                         rc = posix_acl_valid(new_acl);
421                         if (rc) {
422                                 CERROR("acl valid error: %d", rc);
423                                 GOTO(out, rc);
424                         }
425                 }
426         } else {
427                 new_acl = acl;
428         }
429         acl_count = new_acl ? new_acl->a_count : 0;  
430         kperm_size = crypto_kperm_size(acl_count);
431         OBD_ALLOC(kperm, kperm_size);
432         get_real_parameters(inode, iattr, new_acl, &mac_mode, &uid, &gid);
433         ll_init_key_perm(kperm, new_acl, uid, gid, mac_mode);
434         kparms.context = kcontext;
435         kparms.context_size = kcontext_size;
436         kparms.perm = kperm;       
437         kparms.perm_size = kperm_size; 
438
439         *key_size = sizeof(struct crypto_key);
440         OBD_ALLOC(ckey, sizeof(struct crypto_key));
441         if (!ckey)
442                 GOTO(out, rc = -ENOMEM);
443         /*GET an encrypt key from GS server*/
444         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
445                           key_size, ckey);
446         if (rc) {
447                 CERROR("decrypt key error rc %d \n", rc);
448                 GOTO(out, rc);
449         }
450         *key = ckey;
451         iattr->ia_valid |= ATTR_MAC;
452 out:
453         if (acl)
454                 posix_acl_release(acl);
455         if (new_acl)
456                 posix_acl_release(new_acl);
457         if (lkey)
458                 lustre_key_release(lkey); 
459         if (kperm)
460                 OBD_FREE(kperm, kperm_size);
461         if (kcontext)
462                 OBD_FREE(kcontext, kcontext_size);
463         RETURN(rc); 
464 }
465
466 static int ll_crypt_permission_check(struct lustre_key *lkey,
467                                      int flags)
468 {
469         if (!IS_DECRYPTED(lkey->lk_flags)) 
470                 RETURN(-EFAULT);
471         if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags)) 
472                 RETURN(-EFAULT);
473         if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags)) 
474                 RETURN(-EFAULT);
475         RETURN(0);
476 }
477 /*key function for calculate the key for countermode method*/
478 static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
479                        int flags)
480 {
481         struct inode *inode = page->mapping->host;
482         struct ll_inode_info *lli = ll_i2info(inode);
483         struct lustre_key *lkey = ll_i2info(inode)->lli_key_info;
484         unsigned char *ptr;
485         char *key_ptr;
486         int index = page->index;
487         __u64 data_key = 0; 
488         int i, rc = 0;
489         ENTRY;
490
491         if (!lkey)
492                 RETURN(0);
493         spin_lock(&lli->lli_lock);
494         rc = ll_crypt_permission_check(lkey, flags);
495         if (rc) {
496                 spin_unlock(&lli->lli_lock);
497                 RETURN(rc);
498         }
499         
500         key_ptr = &lkey->lk_dk[0];
501         for (i=0; i < KEY_SIZE; i++) 
502                 data_key += *key_ptr++; 
503         spin_unlock(&lli->lli_lock);
504         data_key += index;
505
506         CDEBUG(D_INFO, "data_key is "LPU64" \n", data_key);
507         /*encrypt the data*/
508         ptr = (char *)kmap(page);
509         key_ptr = ptr;
510         ptr += offset; 
511         CDEBUG(D_INFO, "ptr is %s \n", ptr);
512         for (i = 0; i < count; i++) 
513                 *ptr++ ^= (__u8)data_key; 
514         CDEBUG(D_INFO, "encrypted ptr is %s \n", key_ptr);
515         kunmap(page);
516         
517         RETURN(rc); 
518
519
520 int ll_gs_init_inode_key(struct inode *inode, void  *mkey)
521 {
522         struct ll_inode_info *lli = ll_i2info(inode);
523         struct crypto_key *key = (struct crypto_key*)mkey;
524         struct lustre_key *lkey = NULL;
525         ENTRY;        
526
527         if (!key)
528                 RETURN(0);
529         
530         if (lli->lli_key_info == NULL) {
531                 OBD_ALLOC(lkey, sizeof(struct lustre_key));
532                 if (!lkey)
533                         RETURN(-ENOMEM); 
534                 memcpy(&lkey->lk_ck, key, sizeof(*key));
535                 atomic_set(&lkey->lk_refcount, 1);
536                 SET_UNDECRYPTED(lkey->lk_flags); 
537                 ENABLE_ENCRYPT(lkey->lk_flags);  
538                 ENABLE_DECRYPT(lkey->lk_flags); 
539                 spin_lock(&lli->lli_lock);
540                 lli->lli_key_info = lkey; 
541                 spin_unlock(&lli->lli_lock);
542                 CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", 
543                        lli->lli_key_info->lk_ck.ck_key, 
544                        lli->lli_key_info->lk_ck.ck_mac, 
545                        inode->i_ino);
546         } else {
547                 lkey = lustre_key_get(lli->lli_key_info);
548                 LASSERTF(!memcmp(lkey->lk_ck.ck_key, key->ck_key, KEY_SIZE), 
549                          "old key %s != new key %s\n", lkey->lk_ck.ck_key, 
550                          key->ck_key);
551                 spin_lock(&lli->lli_lock);
552                 if (memcmp(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE)){
553                         CDEBUG(D_INFO, "reset mac %s to %s ino %ld \n",
554                                lkey->lk_ck.ck_mac, key->ck_mac, inode->i_ino);
555                         memcpy(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE);
556                         SET_UNDECRYPTED(lkey->lk_flags); 
557                 }
558                 spin_unlock(&lli->lli_lock);
559                 lustre_key_release(lkey);
560         }
561         RETURN(0);
562 }
563
564 static int ll_gs_destroy_key(struct inode *inode)
565 {
566         struct ll_inode_info *lli = ll_i2info(inode);
567        
568         spin_lock(&lli->lli_lock);
569         if (lli->lli_key_info) {
570                 LASSERTF(atomic_read(&lli->lli_key_info->lk_refcount) == 1, 
571                          "lk_refcount %d != 1 when destory\n", 
572                          atomic_read(&lli->lli_key_info->lk_refcount));
573                 lustre_key_release(lli->lli_key_info);
574                 lli->lli_key_info = NULL;
575         }
576         spin_unlock(&lli->lli_lock);
577         RETURN(0);
578 }
579
580 struct crypto_helper_ops ll_cgs_ops = { 
581        .init_it_key     = ll_gks_init_it,
582        .create_key      = ll_gks_create_key,
583        .init_inode_key  = ll_gs_init_inode_key, 
584        .get_mac         = ll_gks_get_mac,
585        .decrypt_key     = ll_gks_decrypt_key, 
586        .destroy_key     = ll_gs_destroy_key,
587 };
588
589 int ll_mks_create_key(struct inode *inode, struct lookup_intent *it)
590 {
591         struct lustre_intent_data *lustre_data;
592         struct crypto_key         *crypto_key;
593         int    rc = 0;       
594         ENTRY;
595        
596         LASSERT(it->d.fs_data != NULL); 
597         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
598        
599         if (lustre_data->it_key) {
600                 OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
601         }
602         OBD_ALLOC(crypto_key, sizeof(struct crypto_key));
603        
604         crypto_key->ck_type = MKS_TYPE;
605         lustre_data->it_key = crypto_key; 
606         lustre_data->it_key_size = sizeof(struct crypto_key); 
607         RETURN(rc);
608 }
609
610 int ll_mks_init_it(struct inode *parent, struct lookup_intent *it)
611 {
612         int rc = 0;
613         ENTRY;
614  
615         if (!it)
616                 RETURN(0);
617
618         ll_gs_intent_init(it);
619         if (it->it_op & IT_CREAT) {
620                 ll_mks_create_key(parent, it);
621         }
622         RETURN(rc); 
623 }
624
625 int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it)
626 {
627         struct ll_inode_info *lli = ll_i2info(inode);
628         struct lustre_key *lkey =  NULL;
629         struct posix_acl *acl = NULL;
630         int rc = 0;
631         
632         ENTRY;
633  
634         rc = ll_get_acl_key(inode, &acl, &lkey);
635         if (rc || !lkey)
636                 GOTO(out, rc);      
637         spin_lock(&lli->lli_lock); 
638         SET_DECRYPTED(lkey->lk_flags); 
639         spin_unlock(&lli->lli_lock); 
640 out:
641         if (acl)
642                 posix_acl_release(acl);
643         if (lkey)
644                 lustre_key_release(lkey); 
645         RETURN(rc);
646 }
647
648 struct crypto_helper_ops ll_cmd_ops = { 
649        .init_it_key     = ll_mks_init_it,
650        .init_inode_key  = ll_gs_init_inode_key, 
651        .decrypt_key     = ll_mks_decrypt_key,
652        .destroy_key     = ll_gs_destroy_key,
653 };
654
655
656 static int ll_register_cops(struct ll_crypto_info *llci, char *type,
657                             struct crypto_helper_ops *cops)
658 {
659         struct list_head *list = &llci->ll_cops_list;
660         struct crypto_ops_item *opi = NULL, *tmp;
661         char   *opi_name = NULL;        
662         int rc = 0;
663         ENTRY;
664         
665         list_for_each_entry(tmp, list, clist) {
666                 if (!strcmp(type, tmp->ctype)) {
667                         CWARN("%s is already registered\n", type);
668                         rc = -EEXIST;
669                         GOTO(exit, rc); 
670                 }
671         }
672         
673         OBD_ALLOC(opi, sizeof(*opi));
674        
675         OBD_ALLOC(opi_name, strlen(type) + 1); 
676        
677         LASSERT(opi && opi_name);
678
679         memcpy(opi_name, type, strlen(type));
680
681         opi->ctype = opi_name;
682         opi->cops = cops;
683   
684         list_add_tail(&opi->clist, list);
685 exit:
686         RETURN(rc);
687 }
688
689 static int ll_init_sb_crypto(struct super_block *sb)
690 {
691         struct ll_crypto_info *llci = NULL;
692         int rc = 0;
693         ENTRY;
694
695         OBD_ALLOC(llci, sizeof(*llci));
696         
697         if (!llci)
698                 RETURN(-ENOMEM);
699
700         INIT_LIST_HEAD(&llci->ll_cops_list);
701         
702         ll_register_cops(llci, "gks", &ll_cgs_ops);
703         ll_register_cops(llci, "mks", &ll_cmd_ops);
704
705         ll_s2sbi(sb)->ll_crypto_info = llci;
706
707         RETURN(rc);
708 }         
709
710 static int ll_unregister_cops(struct ll_crypto_info *llci)
711 {
712         struct list_head *list = &llci->ll_cops_list;
713         struct crypto_ops_item *tmp, *item;
714
715         list_for_each_entry_safe(item, tmp, list, clist) {       
716                 list_del_init(&item->clist);       
717                 OBD_FREE(item->ctype, strlen(item->ctype) + 1);
718                 OBD_FREE(item, sizeof(*item));
719         }
720         RETURN(0);
721 }
722
723 int lustre_destroy_crypto(struct super_block *sb)
724 {
725         struct ll_crypto_info *llci = ll_s2crpi(sb);
726         ENTRY;       
727
728         if (!llci)
729                 RETURN(0);
730
731         if (llci->ll_gt_exp)
732                 obd_disconnect(llci->ll_gt_exp, 0);
733  
734         ll_unregister_cops(llci);
735         OBD_FREE(llci, sizeof(*llci)); 
736         RETURN(0);
737 }
738
739 int lustre_init_crypto(struct super_block *sb, char *gkc, 
740                        struct obd_connect_data *data,
741                        int async)
742 {
743         struct obd_device *obd = NULL;
744         struct ll_sb_info *sbi = ll_s2sbi(sb);
745         struct lustre_handle gt_conn;
746         int rc = 0;
747         ENTRY;
748
749         rc = ll_init_sb_crypto(sb);
750         if (rc)
751                 RETURN(rc);
752
753         if (!gkc || !strcmp(gkc, "null")) {
754                 CDEBUG(D_INFO, "No gks Server\n"); 
755                 RETURN(rc);
756         }
757         
758         obd = class_name2obd(gkc);
759         if (!obd) {
760                 CERROR("GSC %s: not setup or attached\n", gkc);
761                 GOTO(out, rc = -EINVAL);
762         }
763         
764         obd_set_info(obd->obd_self_export, strlen("async"), "async",
765                      sizeof(async), &async);
766         
767         rc = obd_connect(&gt_conn, obd, &sbi->ll_sb_uuid, data,
768                           OBD_OPT_REAL_CLIENT);
769         if (rc) {
770                 CERROR("cannot connect to %s: rc = %d\n", gkc, rc);
771                 GOTO(out, rc);
772         }
773         ll_s2crpi(sb)->ll_gt_exp = class_conn2export(&gt_conn);
774 out:
775         if (rc)
776                 lustre_destroy_crypto(sb); 
777         RETURN(rc);
778 }
779 struct crypto_helper_ops *
780 ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type)
781 {
782         struct list_head *list = &llc_info->ll_cops_list;
783         struct crypto_ops_item *tmp;
784         ENTRY;
785
786         list_for_each_entry(tmp, list, clist) {
787                 if (!strcmp(type, tmp->ctype)) {
788                         EXIT;
789                         return (tmp->cops);            
790                 }
791         }
792         CERROR("can not find crypto api %s \n", type);
793         RETURN(NULL);
794 }
795
796 int ll_set_sb_gksinfo(struct super_block *sb, char *type)
797 {
798         struct ll_crypto_info *llci = ll_s2crpi(sb);
799         struct obd_export *md_exp = ll_s2mdexp(sb);
800         struct obd_export *dt_exp = ll_s2dtexp(sb);
801         struct crypto_helper_ops *ops;
802         int rc = 0;
803         ENTRY;
804         
805         /*try to find the helper ops according to the type*/
806         ops = ll_gks_find_ops(llci, type);
807         if (!ops) {
808                 CERROR("can not find the crypto ops by type %s \n", type);
809                 RETURN(-EINVAL);
810         }
811         llci->ll_cops = ops;
812         /*set crypto type */
813         rc = obd_set_info(md_exp, strlen("crypto_type"), "crypto_type",
814                           strlen(type), type);
815
816         /*set crypt call back func*/
817
818         rc = obd_set_info(dt_exp, strlen("crypto_cb"), "crypto_cb",
819                           sizeof(crypt_cb_t), &ll_crypt_cb);
820   
821         RETURN(rc);
822 }
823