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