Whamcloud - gitweb
- per-inode wait queue to wait for I/O completion
[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         EXIT;
98 out:
99         if (req)
100                 ptlrpc_req_finished(req);        
101         return rc;
102 }
103
104 static int ll_init_key_perm(struct key_perm *kperm, struct posix_acl *acl, 
105                             __u32 uid, __u32 gid, int mode) 
106 {
107         ENTRY;
108         if (acl) {
109                 kperm->kp_acl_count = acl->a_count;
110                 memcpy(kperm->kp_acls, acl->a_entries, 
111                        acl->a_count * sizeof(struct posix_acl_entry));
112         }
113         kperm->kp_mode = mode;
114         kperm->kp_uid = uid;
115         kperm->kp_gid = gid;
116         RETURN(0);
117 }
118
119 static int ll_init_key_context(struct key_context *pkc, __u32 uid, 
120                                 __u32 gid, struct crypto_key *ck, 
121                                 struct posix_acl *acl,  int mode, 
122                                 int command, int valid)
123 {
124         struct key_perm *kperm;
125         ENTRY;
126
127         pkc->kc_command = command;
128         pkc->kc_valid = valid;
129
130         if (ck)
131                 memcpy(&pkc->kc_ck, ck, sizeof(*ck));
132
133         kperm = &pkc->kc_perm;      
134  
135         ll_init_key_perm(kperm, acl, uid, gid, mode);  
136         RETURN(0);
137 }
138 static int ll_get_default_acl(struct inode *inode, struct posix_acl **acl, 
139                               mode_t mode) 
140 {
141         int rc = 0, buf_size, ea_size;
142         char *buf = NULL;
143         ENTRY;
144
145         if (!S_ISDIR(inode->i_mode))
146                 RETURN(0);
147  
148         buf_size = xattr_acl_size(LL_ACL_MAX_ENTRIES);
149         OBD_ALLOC(buf, buf_size);
150         if (!buf)
151                 RETURN(-ENOMEM);
152
153         ea_size = ll_getxattr_internal(inode, XATTR_NAME_ACL_DEFAULT, 
154                                        buf, buf_size, OBD_MD_FLXATTR);
155         if (ea_size <= 0) {
156                 if (ea_size < 0 && ea_size != -ENODATA)
157                         CERROR("get default acl of ino %lu error rc %d \n",
158                                 inode->i_ino, ea_size);
159                 GOTO(out, rc = 0);       
160         }
161         *acl = posix_acl_from_xattr(buf, ea_size);
162         if (IS_ERR(*acl)) {
163                 rc = PTR_ERR(*acl);
164                 CERROR("convert xattr to acl failed: %d\n", rc);
165                 GOTO(out, rc);
166         } else if (*acl) {
167                 rc = posix_acl_valid(*acl);
168                 if (rc) {
169                         CERROR("acl valid error: %d\n", rc);
170                         posix_acl_release(*acl);
171                         GOTO(out, rc);
172                 }
173         }
174         
175         rc = posix_acl_create_masq(*acl, &mode);
176         EXIT;
177 out:
178         if (buf) 
179                 OBD_FREE(buf, buf_size);
180         return rc;
181 }
182
183 int ll_gks_create_key(struct inode *dir, mode_t mode, void **key, 
184                       int* key_size)
185 {
186         struct obd_export *gs_exp = ll_i2gsexp(dir);
187         struct key_context *kcontext = NULL;
188         struct posix_acl *default_acl = NULL;       
189         struct key_parms kparms;
190         int rc = 0;  
191         ENTRY;
192  
193         OBD_ALLOC(kcontext, sizeof(struct key_context));
194         if (!kcontext)
195                 GOTO(out, rc = -ENOMEM);
196
197         rc = ll_get_default_acl(dir, &default_acl, mode);
198         if (rc)
199                 GOTO(out, rc);       
200  
201         ll_init_key_context(kcontext, current->fsuid, current->fsgid, 
202                             NULL, default_acl, mode, GKS_GET_KEY, 0);
203        
204         kparms.context = kcontext;
205         kparms.context_size = sizeof(struct key_context);
206         kparms.perm = NULL;
207        
208         *key_size = sizeof(struct crypto_key);
209         OBD_ALLOC(*key, *key_size);
210         if (!*key)
211                 GOTO(out, rc = -ENOMEM);
212  
213         /* GET an encrypt key from GS server */
214         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
215                           key_size, *key);
216         if (rc) {
217                 CERROR("get key error rc %d \n", rc);
218                 GOTO(out, rc);
219         }
220         CDEBUG(D_INFO, "Get enkey %s MAC %s from exp %p \n", 
221                (char*)((struct crypto_key *)(*key))->ck_key, 
222                (char*)((struct crypto_key *)(*key))->ck_mac, 
223                gs_exp);
224         EXIT;
225 out:
226         if (kcontext)
227                 OBD_FREE(kcontext, sizeof(struct key_context));
228         if (default_acl)
229                 posix_acl_release(default_acl);
230         return rc;
231
232 }
233  
234 int ll_gks_init_it(struct inode *parent, struct lookup_intent *it)
235 {
236         struct obd_export *gs_exp = ll_i2gsexp(parent);
237         struct lustre_intent_data *lustre_data;
238         mode_t mode = (it->it_create_mode | S_IFREG) & (~current->fs->umask);
239         void *key = NULL;
240         int key_size = 0, rc = 0;
241         ENTRY;
242  
243         if (!gs_exp || !it)
244                 RETURN(rc);
245
246         ll_gs_intent_init(it);
247         if (!(it->it_flags & O_CREAT)) 
248                 RETURN(rc);
249
250         LASSERT(it->d.fs_data != NULL); 
251         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
252           
253         if (lustre_data->it_key) {
254                 LASSERT(lustre_data->it_key_size == 
255                          sizeof(struct crypto_key));
256                 OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
257         }
258
259         rc = ll_gks_create_key(parent, mode, &key, &key_size); 
260         if (rc)
261                 GOTO(out, rc);
262
263         lustre_data->it_key = key; 
264         lustre_data->it_key_size = key_size;
265         EXIT;
266 out:
267         if (rc) {
268                 if (key && key_size)
269                         OBD_FREE(key, key_size);
270         }
271         return rc; 
272 }
273
274 int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
275 {
276         struct obd_export *gs_exp = ll_i2gsexp(inode);
277         struct ll_inode_info *lli = ll_i2info(inode);
278         struct key_context *kcontext = NULL;
279         struct key_perm *kperm = NULL;
280         struct key_parms kparms;
281         struct lustre_key *lkey =  NULL;
282         struct crypto_key *ckey = NULL;
283         struct posix_acl *acl = NULL;
284         __u32 flags = 0; 
285         int rc = 0, ck_size = 0, kcontext_size = 0, acl_count;
286         
287         ENTRY;
288  
289         if (!gs_exp)
290                 RETURN(rc);
291        
292         rc = ll_get_acl_key(inode, &acl, &lkey);
293         if (rc)
294                 GOTO(out, rc);       
295         if (!lkey || IS_DECRYPTED(lkey->lk_flags))
296                 GOTO(out, rc = 0);
297        
298         acl_count = acl ? acl->a_count : 0;  
299         kcontext_size = crypto_kcontext_size(acl_count); 
300         OBD_ALLOC(kcontext, kcontext_size);
301         if (!kcontext)
302                 GOTO(out, rc = -ENOMEM);
303         
304         flags = mds_pack_open_flags(it->it_flags); 
305
306         spin_lock(&lli->lli_lock); 
307         ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
308                             acl, inode->i_mode, GKS_DECRYPT_KEY, flags);
309        
310         spin_unlock(&lli->lli_lock); 
311         
312         OBD_ALLOC(kperm, sizeof(struct key_perm));
313         if (!kperm)
314                 GOTO(out, rc = -ENOMEM);
315             
316         ll_init_key_perm(kperm, NULL, current->uid, current->gid, 0);
317     
318         kparms.context = kcontext;
319         kparms.context_size = kcontext_size;
320         kparms.perm = kperm;       
321         kparms.perm_size = sizeof(struct key_perm); 
322
323         ck_size = sizeof(*ckey);
324         OBD_ALLOC(ckey, ck_size);
325         if (!ckey)
326                 GOTO(out, rc = -ENOMEM);
327  
328         /*GET an encrypt key from GS server*/
329         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
330                           &ck_size, ckey);
331         if (rc) {
332                 CERROR("decrypt key error rc %d \n", rc);
333                 GOTO(out, rc);
334         }
335         CDEBUG(D_INFO, "decrypt key %s MAC %s from exp %p \n", 
336                ckey->ck_mac, ckey->ck_mac, gs_exp);        
337       
338         /*copy the decrypt key from kcontext to the lustre key*/
339         
340         spin_lock(&lli->lli_lock); 
341         memcpy(&lkey->lk_dk, ckey->ck_key, KEY_SIZE);
342         SET_DECRYPTED(lkey->lk_flags);
343         spin_unlock(&lli->lli_lock);
344         EXIT;
345 out:
346         if (acl)
347                 posix_acl_release(acl);
348         if (lkey)
349                 lustre_key_release(lkey); 
350         if (kperm)
351                 OBD_FREE(kperm, sizeof(struct key_perm));
352         if (kcontext)
353                 OBD_FREE(kcontext, kcontext_size);
354         if (ckey)
355                 OBD_FREE(ckey, ck_size);
356         return rc; 
357 }
358
359 static void get_real_parameters(struct inode *inode, struct iattr *iattr,
360                                 struct posix_acl *new_acl, mode_t *mode,   
361                                 __u32 *uid, __u32 *gid)
362
363         LASSERT(iattr);
364
365         if (iattr->ia_valid & ATTR_MODE) {
366                 *mode = iattr->ia_mode;
367         } else {
368                 *mode = inode->i_mode;
369                 if (new_acl) {
370                         posix_acl_equiv_mode(new_acl, mode);
371                         CDEBUG(D_INFO, "get new mode %d \n", *mode);
372                 } 
373         }
374
375         if (iattr->ia_valid & ATTR_UID)
376                 *uid = iattr->ia_uid;
377         else 
378                 *uid = inode->i_uid;
379
380         if (iattr->ia_valid & ATTR_GID)
381                 *gid = iattr->ia_gid;
382         else
383                 *gid = inode->i_gid;
384 }
385
386 int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value, 
387                    int size, void **key, int *key_size)
388 {
389         struct ll_inode_info *lli = ll_i2info(inode);
390         struct obd_export *gs_exp = ll_i2gsexp(inode);
391         struct key_context *kcontext = NULL;
392         struct key_perm *kperm = NULL;
393         struct key_parms kparms;
394         struct lustre_key *lkey =  NULL;
395         struct crypto_key *ckey = NULL;
396         struct posix_acl *acl = NULL, *new_acl = NULL; 
397         int rc = 0,  kperm_size = 0, kcontext_size = 0; 
398         mode_t mac_mode;
399         __u32 uid, gid;
400         int acl_count = 0;
401         
402         ENTRY;
403  
404         if (!gs_exp)
405                 RETURN(rc);
406        
407         rc = ll_get_acl_key(inode, &acl, &lkey);
408         if (rc)
409                 GOTO(out, rc);       
410         if (!lkey)
411                 RETURN(rc);
412         
413         acl_count = acl ? acl->a_count : 0;  
414         kcontext_size = crypto_kcontext_size(acl_count); 
415         OBD_ALLOC(kcontext, kcontext_size);
416         if (!kcontext)
417                 GOTO(out, rc = -ENOMEM);
418         spin_lock(&lli->lli_lock);
419         ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
420                             acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid);
421         spin_unlock(&lli->lli_lock);
422         if (value) {
423                 new_acl = posix_acl_from_xattr(value, size); 
424                 if (IS_ERR(new_acl)) {
425                         rc = PTR_ERR(new_acl);
426                         CERROR("convert from xattr to acl error: %d",rc);
427                         new_acl = NULL;
428                         GOTO(out, rc);
429                 } else if (new_acl) {
430                         rc = posix_acl_valid(new_acl);
431                         if (rc) {
432                                 CERROR("acl valid error: %d", rc);
433                                 GOTO(out, rc);
434                         }
435                 }
436         } else {
437                 new_acl = acl;
438         }
439         acl_count = new_acl ? new_acl->a_count : 0;  
440         kperm_size = crypto_kperm_size(acl_count);
441         OBD_ALLOC(kperm, kperm_size);
442         if (!kperm)
443                 GOTO(out, rc = -ENOMEM);
444                 
445         get_real_parameters(inode, iattr, new_acl, &mac_mode, &uid, &gid);
446         ll_init_key_perm(kperm, new_acl, uid, gid, mac_mode);
447         kparms.context = kcontext;
448         kparms.context_size = kcontext_size;
449         kparms.perm = kperm;       
450         kparms.perm_size = kperm_size; 
451
452         *key_size = sizeof(struct crypto_key);
453         OBD_ALLOC(ckey, sizeof(struct crypto_key));
454         if (!ckey)
455                 GOTO(out, rc = -ENOMEM);
456         /*GET an encrypt key from GS server*/
457         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
458                           key_size, ckey);
459         if (rc) {
460                 CERROR("decrypt key error rc %d \n", rc);
461                 GOTO(out, rc);
462         }
463         *key = ckey;
464         iattr->ia_valid |= ATTR_MAC;
465         EXIT;
466 out:
467         if (acl)
468                 posix_acl_release(acl);
469         if (new_acl)
470                 posix_acl_release(new_acl);
471         if (lkey)
472                 lustre_key_release(lkey); 
473         if (kperm)
474                 OBD_FREE(kperm, kperm_size);
475         if (kcontext)
476                 OBD_FREE(kcontext, kcontext_size);
477         return rc; 
478 }
479
480 static int ll_crypt_permission_check(struct lustre_key *lkey,
481                                      int flags)
482 {
483         ENTRY;
484         if (!IS_DECRYPTED(lkey->lk_flags)) 
485                 RETURN(-EFAULT);
486         if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags)) 
487                 RETURN(-EFAULT);
488         if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags)) 
489                 RETURN(-EFAULT);
490         RETURN(0);
491 }
492 /*key function for calculate the key for countermode method*/
493 static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
494                        int flags)
495 {
496         struct inode *inode = page->mapping->host;
497         struct ll_inode_info *lli = ll_i2info(inode);
498         struct lustre_key *lkey = ll_i2info(inode)->lli_key_info;
499         unsigned char *ptr;
500         char *key_ptr;
501         int index = page->index;
502         __u64 data_key = 0; 
503         int i, rc = 0;
504         ENTRY;
505
506         if (!lkey)
507                 RETURN(0);
508         spin_lock(&lli->lli_lock);
509         rc = ll_crypt_permission_check(lkey, flags);
510         if (rc) {
511                 spin_unlock(&lli->lli_lock);
512                 RETURN(rc);
513         }
514         
515         key_ptr = &lkey->lk_dk[0];
516         for (i=0; i < KEY_SIZE; i++) 
517                 data_key += *key_ptr++; 
518         spin_unlock(&lli->lli_lock);
519         data_key += index;
520
521         CDEBUG(D_INFO, "data_key is "LPU64" \n", data_key);
522         /*encrypt the data*/
523         ptr = (char *)kmap(page);
524         key_ptr = ptr;
525         ptr += offset; 
526         CDEBUG(D_INFO, "ptr is %s \n", ptr);
527         for (i = 0; i < count; i++) 
528                 *ptr++ ^= (__u8)data_key; 
529         CDEBUG(D_INFO, "encrypted ptr is %s \n", key_ptr);
530         kunmap(page);
531         
532         RETURN(rc); 
533
534
535 int ll_gs_init_inode_key(struct inode *inode, void  *mkey)
536 {
537         struct ll_inode_info *lli = ll_i2info(inode);
538         struct crypto_key *key = (struct crypto_key*)mkey;
539         struct lustre_key *lkey = NULL;
540         ENTRY;        
541
542         if (!key)
543                 RETURN(0);
544         
545         if (lli->lli_key_info == NULL) {
546                 OBD_ALLOC(lkey, sizeof(struct lustre_key));
547                 if (!lkey)
548                         RETURN(-ENOMEM); 
549                 memcpy(&lkey->lk_ck, key, sizeof(*key));
550                 atomic_set(&lkey->lk_refcount, 1);
551                 SET_UNDECRYPTED(lkey->lk_flags); 
552                 ENABLE_ENCRYPT(lkey->lk_flags);  
553                 ENABLE_DECRYPT(lkey->lk_flags); 
554                 spin_lock(&lli->lli_lock);
555                 lli->lli_key_info = lkey; 
556                 spin_unlock(&lli->lli_lock);
557                 CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", 
558                        lli->lli_key_info->lk_ck.ck_key, 
559                        lli->lli_key_info->lk_ck.ck_mac, 
560                        inode->i_ino);
561         } else {
562                 lkey = lustre_key_get(lli->lli_key_info);
563                 LASSERTF(!memcmp(lkey->lk_ck.ck_key, key->ck_key, KEY_SIZE), 
564                          "old key %s != new key %s\n", lkey->lk_ck.ck_key, 
565                          key->ck_key);
566                 spin_lock(&lli->lli_lock);
567                 if (memcmp(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE)){
568                         CDEBUG(D_INFO, "reset mac %s to %s ino %ld \n",
569                                lkey->lk_ck.ck_mac, key->ck_mac, inode->i_ino);
570                         memcpy(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE);
571                         SET_UNDECRYPTED(lkey->lk_flags); 
572                 }
573                 spin_unlock(&lli->lli_lock);
574                 lustre_key_release(lkey);
575         }
576         RETURN(0);
577 }
578
579 static int ll_gs_destroy_key(struct inode *inode)
580 {
581         struct ll_inode_info *lli = ll_i2info(inode);
582        
583         spin_lock(&lli->lli_lock);
584         if (lli->lli_key_info) {
585                 LASSERTF(atomic_read(&lli->lli_key_info->lk_refcount) == 1, 
586                          "lk_refcount %d != 1 when destory\n", 
587                          atomic_read(&lli->lli_key_info->lk_refcount));
588                 lustre_key_release(lli->lli_key_info);
589                 lli->lli_key_info = NULL;
590         }
591         spin_unlock(&lli->lli_lock);
592         RETURN(0);
593 }
594
595 struct crypto_helper_ops ll_cgs_ops = { 
596        .init_it_key     = ll_gks_init_it,
597        .create_key      = ll_gks_create_key,
598        .init_inode_key  = ll_gs_init_inode_key, 
599        .get_mac         = ll_gks_get_mac,
600        .decrypt_key     = ll_gks_decrypt_key, 
601        .destroy_key     = ll_gs_destroy_key,
602 };
603
604 int ll_mks_create_key(struct inode *inode, struct lookup_intent *it)
605 {
606         struct lustre_intent_data *lustre_data;
607         struct crypto_key         *crypto_key;
608         int    rc = 0;       
609         ENTRY;
610        
611         LASSERT(it->d.fs_data != NULL); 
612         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
613        
614         if (lustre_data->it_key)
615                 OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
616
617         OBD_ALLOC(crypto_key, sizeof(struct crypto_key));
618         if (!crypto_key)
619                 RETURN(-ENOMEM);
620        
621         crypto_key->ck_type = MKS_TYPE;
622         lustre_data->it_key = crypto_key; 
623         lustre_data->it_key_size = sizeof(struct crypto_key); 
624         RETURN(rc);
625 }
626
627 int ll_mks_init_it(struct inode *parent, struct lookup_intent *it)
628 {
629         int rc = 0;
630         ENTRY;
631  
632         if (!it)
633                 RETURN(0);
634
635         ll_gs_intent_init(it);
636         if (it->it_op & IT_CREAT) {
637                 ll_mks_create_key(parent, it);
638         }
639         RETURN(rc); 
640 }
641
642 int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it)
643 {
644         struct ll_inode_info *lli = ll_i2info(inode);
645         struct lustre_key *lkey =  NULL;
646         struct posix_acl *acl = NULL;
647         int rc = 0;
648         ENTRY;
649  
650         rc = ll_get_acl_key(inode, &acl, &lkey);
651         if (rc || !lkey)
652                 GOTO(out, rc);      
653         spin_lock(&lli->lli_lock); 
654         SET_DECRYPTED(lkey->lk_flags); 
655         spin_unlock(&lli->lli_lock);
656         EXIT;
657 out:
658         if (acl)
659                 posix_acl_release(acl);
660         if (lkey)
661                 lustre_key_release(lkey); 
662         return rc;
663 }
664
665 struct crypto_helper_ops ll_cmd_ops = { 
666        .init_it_key     = ll_mks_init_it,
667        .init_inode_key  = ll_gs_init_inode_key, 
668        .decrypt_key     = ll_mks_decrypt_key,
669        .destroy_key     = ll_gs_destroy_key,
670 };
671
672
673 static int ll_register_cops(struct ll_crypto_info *llci, char *type,
674                             struct crypto_helper_ops *cops)
675 {
676         struct list_head *list = &llci->ll_cops_list;
677         struct crypto_ops_item *opi = NULL, *tmp;
678         char   *opi_name = NULL;        
679         int rc = 0;
680         ENTRY;
681         
682         list_for_each_entry(tmp, list, clist) {
683                 if (!strcmp(type, tmp->ctype)) {
684                         CWARN("%s is already registered\n", type);
685                         RETURN(-EEXIST);
686                 }
687         }
688         
689         OBD_ALLOC(opi, sizeof(*opi));
690         if (!opi)
691                 RETURN(-ENOMEM);
692        
693         OBD_ALLOC(opi_name, strlen(type) + 1);
694         if (!opi_name) {
695                 OBD_FREE(opi, sizeof(*opi));
696                 RETURN(-ENOMEM);
697         }
698        
699         memcpy(opi_name, type, strlen(type));
700
701         opi->ctype = opi_name;
702         opi->cops = cops;
703   
704         list_add_tail(&opi->clist, list);
705         RETURN(rc);
706 }
707
708 static int ll_init_sb_crypto(struct super_block *sb)
709 {
710         struct ll_crypto_info *llci = NULL;
711         int rc = 0;
712         ENTRY;
713
714         OBD_ALLOC(llci, sizeof(*llci));
715         if (!llci)
716                 RETURN(-ENOMEM);
717
718         INIT_LIST_HEAD(&llci->ll_cops_list);
719         
720         ll_register_cops(llci, "gks", &ll_cgs_ops);
721         ll_register_cops(llci, "mks", &ll_cmd_ops);
722
723         ll_s2sbi(sb)->ll_crypto_info = llci;
724
725         RETURN(rc);
726 }         
727
728 static int ll_unregister_cops(struct ll_crypto_info *llci)
729 {
730         struct list_head *list = &llci->ll_cops_list;
731         struct crypto_ops_item *tmp, *item;
732         ENTRY;
733
734         list_for_each_entry_safe(item, tmp, list, clist) {       
735                 list_del_init(&item->clist);       
736                 OBD_FREE(item->ctype, strlen(item->ctype) + 1);
737                 OBD_FREE(item, sizeof(*item));
738         }
739         RETURN(0);
740 }
741
742 int lustre_destroy_crypto(struct super_block *sb)
743 {
744         struct ll_crypto_info *llci = ll_s2crpi(sb);
745         ENTRY;       
746
747         if (!llci)
748                 RETURN(0);
749
750         if (llci->ll_gt_exp)
751                 obd_disconnect(llci->ll_gt_exp, 0);
752  
753         ll_unregister_cops(llci);
754         OBD_FREE(llci, sizeof(*llci)); 
755         RETURN(0);
756 }
757
758 int lustre_init_crypto(struct super_block *sb, char *gkc, 
759                        struct obd_connect_data *data,
760                        int async)
761 {
762         struct obd_device *obd = NULL;
763         struct ll_sb_info *sbi = ll_s2sbi(sb);
764         struct lustre_handle gt_conn;
765         int rc = 0;
766         ENTRY;
767
768         rc = ll_init_sb_crypto(sb);
769         if (rc)
770                 RETURN(rc);
771
772         if (!gkc || !strcmp(gkc, "null")) {
773                 CDEBUG(D_INFO, "No gks Server\n"); 
774                 RETURN(rc);
775         }
776         
777         obd = class_name2obd(gkc);
778         if (!obd) {
779                 CERROR("GSC %s: not setup or attached\n", gkc);
780                 GOTO(out, rc = -EINVAL);
781         }
782         
783         obd_set_info(obd->obd_self_export, strlen("async"), "async",
784                      sizeof(async), &async);
785         
786         rc = obd_connect(&gt_conn, obd, &sbi->ll_sb_uuid, data,
787                           OBD_OPT_REAL_CLIENT);
788         if (rc) {
789                 CERROR("cannot connect to %s: rc = %d\n", gkc, rc);
790                 GOTO(out, rc);
791         }
792         ll_s2crpi(sb)->ll_gt_exp = class_conn2export(&gt_conn);
793         EXIT;
794 out:
795         if (rc)
796                 lustre_destroy_crypto(sb); 
797         return rc;
798 }
799 struct crypto_helper_ops *
800 ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type)
801 {
802         struct list_head *list = &llc_info->ll_cops_list;
803         struct crypto_ops_item *tmp;
804         ENTRY;
805
806         list_for_each_entry(tmp, list, clist) {
807                 if (!strcmp(type, tmp->ctype)) {
808                         EXIT;
809                         return (tmp->cops);            
810                 }
811         }
812         CERROR("can not find crypto api %s \n", type);
813         RETURN(NULL);
814 }
815
816 int ll_set_sb_gksinfo(struct super_block *sb, char *type)
817 {
818         struct ll_crypto_info *llci = ll_s2crpi(sb);
819         struct obd_export *md_exp = ll_s2mdexp(sb);
820         struct obd_export *dt_exp = ll_s2dtexp(sb);
821         struct crypto_helper_ops *ops;
822         int rc = 0;
823         ENTRY;
824         
825         /*try to find the helper ops according to the type*/
826         ops = ll_gks_find_ops(llci, type);
827         if (!ops) {
828                 CERROR("can not find the crypto ops by type %s \n", type);
829                 RETURN(-EINVAL);
830         }
831         llci->ll_cops = ops;
832         /*set crypto type */
833         rc = obd_set_info(md_exp, strlen("crypto_type"), "crypto_type",
834                           strlen(type), type);
835
836         /*set crypt call back func*/
837
838         rc = obd_set_info(dt_exp, strlen("crypto_cb"), "crypto_cb",
839                           sizeof(crypt_cb_t), &ll_crypt_cb);
840   
841         RETURN(rc);
842 }
843