Whamcloud - gitweb
- many fixes about using ENTRY, RETURN, GOTO and EXIT.
[fs/lustre-release.git] / lustre / llite / llite_gs.c
index 9f75957..7fe1804 100644 (file)
@@ -94,15 +94,17 @@ static int ll_get_acl_key(struct inode *inode, struct posix_acl **acl,
         *acl = posix_acl_dup(lli->lli_posix_acl);
         *lkey =  lustre_key_get(lli->lli_key_info);
         spin_unlock(&lli->lli_lock);
+        EXIT;
 out:
         if (req)
                 ptlrpc_req_finished(req);        
-        RETURN(rc);
+        return rc;
 }
 
 static int ll_init_key_perm(struct key_perm *kperm, struct posix_acl *acl, 
                             __u32 uid, __u32 gid, int mode) 
 {
+        ENTRY;
         if (acl) {
                 kperm->kp_acl_count = acl->a_count;
                 memcpy(kperm->kp_acls, acl->a_entries, 
@@ -170,11 +172,12 @@ static int ll_get_default_acl(struct inode *inode, struct posix_acl **acl,
                 }
         }
         
-        rc = posix_acl_create_masq(*acl, &mode); 
+        rc = posix_acl_create_masq(*acl, &mode);
+        EXIT;
 out:
         if (buf) 
                 OBD_FREE(buf, buf_size);
-        RETURN(rc);
+        return rc;
 }
 
 int ll_gks_create_key(struct inode *dir, mode_t mode, void **key, 
@@ -182,9 +185,9 @@ int ll_gks_create_key(struct inode *dir, mode_t mode, void **key,
 {
         struct obd_export *gs_exp = ll_i2gsexp(dir);
         struct key_context *kcontext = NULL;
-        struct key_parms   kparms;
         struct posix_acl *default_acl = NULL;       
-        int    rc = 0;  
+        struct key_parms kparms;
+        int rc = 0;  
         ENTRY;
  
         OBD_ALLOC(kcontext, sizeof(struct key_context));
@@ -207,7 +210,7 @@ int ll_gks_create_key(struct inode *dir, mode_t mode, void **key,
         if (!*key)
                 GOTO(out, rc = -ENOMEM);
  
-        /*GET an encrypt key from GS server*/
+        /* GET an encrypt key from GS server */
         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
                           key_size, *key);
         if (rc) {
@@ -218,12 +221,13 @@ int ll_gks_create_key(struct inode *dir, mode_t mode, void **key,
                (char*)((struct crypto_key *)(*key))->ck_key, 
                (char*)((struct crypto_key *)(*key))->ck_mac, 
                gs_exp);
+        EXIT;
 out:
         if (kcontext)
                 OBD_FREE(kcontext, sizeof(struct key_context));
         if (default_acl)
                 posix_acl_release(default_acl);
-        RETURN(rc);
+        return rc;
 
 }
  
@@ -240,7 +244,7 @@ int ll_gks_init_it(struct inode *parent, struct lookup_intent *it)
                 RETURN(rc);
 
         ll_gs_intent_init(it);
-        if (!(it->it_op & IT_CREAT))
+        if (!(it->it_flags & O_CREAT)) 
                 RETURN(rc);
 
         LASSERT(it->d.fs_data != NULL); 
@@ -257,13 +261,14 @@ int ll_gks_init_it(struct inode *parent, struct lookup_intent *it)
                 GOTO(out, rc);
 
         lustre_data->it_key = key; 
-        lustre_data->it_key_size = key_size; 
+        lustre_data->it_key_size = key_size;
+        EXIT;
 out:
         if (rc) {
                 if (key && key_size)
                         OBD_FREE(key, key_size);
         }
-        RETURN(rc)
+        return rc
 }
 
 int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
@@ -305,6 +310,9 @@ int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
         spin_unlock(&lli->lli_lock); 
         
         OBD_ALLOC(kperm, sizeof(struct key_perm));
+        if (!kperm)
+                GOTO(out, rc = -ENOMEM);
+            
         ll_init_key_perm(kperm, NULL, current->uid, current->gid, 0);
     
         kparms.context = kcontext;
@@ -330,9 +338,10 @@ int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
         /*copy the decrypt key from kcontext to the lustre key*/
         
         spin_lock(&lli->lli_lock); 
-        memcpy(&lkey->lk_ck, ckey, sizeof(*ckey));
+        memcpy(&lkey->lk_dk, ckey->ck_key, KEY_SIZE);
         SET_DECRYPTED(lkey->lk_flags);
-        spin_unlock(&lli->lli_lock); 
+        spin_unlock(&lli->lli_lock);
+        EXIT;
 out:
         if (acl)
                 posix_acl_release(acl);
@@ -344,7 +353,34 @@ out:
                 OBD_FREE(kcontext, kcontext_size);
         if (ckey)
                 OBD_FREE(ckey, ck_size);
-        RETURN(rc); 
+        return rc; 
+}
+
+static void get_real_parameters(struct inode *inode, struct iattr *iattr,
+                                struct posix_acl *new_acl, mode_t *mode,   
+                                __u32 *uid, __u32 *gid)
+{ 
+        LASSERT(iattr);
+
+        if (iattr->ia_valid & ATTR_MODE) {
+                *mode = iattr->ia_mode;
+        } else {
+                *mode = inode->i_mode;
+                if (new_acl) {
+                        posix_acl_equiv_mode(new_acl, mode);
+                        CDEBUG(D_INFO, "get new mode %d \n", *mode);
+                } 
+        }
+
+        if (iattr->ia_valid & ATTR_UID)
+                *uid = iattr->ia_uid;
+        else 
+                *uid = inode->i_uid;
+
+        if (iattr->ia_valid & ATTR_GID)
+                *gid = iattr->ia_gid;
+        else
+                *gid = inode->i_gid;
 }
 
 int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value, 
@@ -356,9 +392,11 @@ int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value,
         struct key_perm *kperm = NULL;
         struct key_parms kparms;
         struct lustre_key *lkey =  NULL;
+        struct crypto_key *ckey = NULL;
         struct posix_acl *acl = NULL, *new_acl = NULL; 
         int rc = 0,  kperm_size = 0, kcontext_size = 0; 
         mode_t mac_mode;
+        __u32 uid, gid;
         int acl_count = 0;
         
         ENTRY;
@@ -382,7 +420,7 @@ int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value,
                             acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid);
         spin_unlock(&lli->lli_lock);
         if (value) {
-                new_acl = posix_acl_from_xattr(value, size);
+                new_acl = posix_acl_from_xattr(value, size); 
                 if (IS_ERR(new_acl)) {
                         rc = PTR_ERR(new_acl);
                         CERROR("convert from xattr to acl error: %d",rc);
@@ -395,38 +433,36 @@ int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value,
                                 GOTO(out, rc);
                         }
                 }
-        } 
-        acl_count = acl ? acl->a_count : 0;  
+        } else {
+                new_acl = acl;
+        }
+        acl_count = new_acl ? new_acl->a_count : 0;  
         kperm_size = crypto_kperm_size(acl_count);
         OBD_ALLOC(kperm, kperm_size);
-        if (iattr->ia_valid & ATTR_MODE)
-                mac_mode = iattr->ia_mode;
-        else
-                mac_mode = inode->i_mode; 
-        ll_init_key_perm(kperm, new_acl, iattr->ia_uid, iattr->ia_gid, 
-                         mac_mode);
+        if (!kperm)
+                GOTO(out, rc = -ENOMEM);
+                
+        get_real_parameters(inode, iattr, new_acl, &mac_mode, &uid, &gid);
+        ll_init_key_perm(kperm, new_acl, uid, gid, mac_mode);
         kparms.context = kcontext;
         kparms.context_size = kcontext_size;
         kparms.perm = kperm;       
         kparms.perm_size = kperm_size; 
 
         *key_size = sizeof(struct crypto_key);
-        OBD_ALLOC(*key, *key_size);
-        if (!*key)
+        OBD_ALLOC(ckey, sizeof(struct crypto_key));
+        if (!ckey)
                 GOTO(out, rc = -ENOMEM);
         /*GET an encrypt key from GS server*/
         rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
-                          key_size, *key);
+                          key_size, ckey);
         if (rc) {
                 CERROR("decrypt key error rc %d \n", rc);
                 GOTO(out, rc);
         }
-        /*copy the decrypt key from kcontext to the lustre key*/
-        spin_lock(&lli->lli_lock);
-        memcpy(&lkey->lk_ck, *key, *key_size);
+        *key = ckey;
         iattr->ia_valid |= ATTR_MAC;
-        spin_unlock(&lli->lli_lock);
+        EXIT;
 out:
         if (acl)
                 posix_acl_release(acl);
@@ -438,9 +474,21 @@ out:
                 OBD_FREE(kperm, kperm_size);
         if (kcontext)
                 OBD_FREE(kcontext, kcontext_size);
-        RETURN(rc)
+        return rc
 }
 
+static int ll_crypt_permission_check(struct lustre_key *lkey,
+                                     int flags)
+{
+        ENTRY;
+        if (!IS_DECRYPTED(lkey->lk_flags)) 
+                RETURN(-EFAULT);
+        if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags)) 
+                RETURN(-EFAULT);
+        if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags)) 
+                RETURN(-EFAULT);
+        RETURN(0);
+}
 /*key function for calculate the key for countermode method*/
 static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
                        int flags)
@@ -452,23 +500,19 @@ static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
         char *key_ptr;
         int index = page->index;
         __u64 data_key = 0; 
-        int i;
+        int i, rc = 0;
         ENTRY;
 
         if (!lkey)
                 RETURN(0);
-        if (!IS_DECRYPTED(lkey->lk_flags))
-                RETURN(-EFAULT);
-        if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags))
-                RETURN(-EFAULT);
-        if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags))
-                RETURN(-EFAULT);
-        
-        /*FIXME: tmp calculate method, should calculate 
-          the key according to KEY_TYPE*/
-        
         spin_lock(&lli->lli_lock);
-        key_ptr = &lkey->lk_ck.ck_key[0];
+        rc = ll_crypt_permission_check(lkey, flags);
+        if (rc) {
+                spin_unlock(&lli->lli_lock);
+                RETURN(rc);
+        }
+        
+        key_ptr = &lkey->lk_dk[0];
         for (i=0; i < KEY_SIZE; i++) 
                 data_key += *key_ptr++; 
         spin_unlock(&lli->lli_lock);
@@ -485,7 +529,7 @@ static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
         CDEBUG(D_INFO, "encrypted ptr is %s \n", key_ptr);
         kunmap(page);
         
-        RETURN(0); 
+        RETURN(rc); 
 } 
 
 int ll_gs_init_inode_key(struct inode *inode, void  *mkey)
@@ -510,25 +554,25 @@ int ll_gs_init_inode_key(struct inode *inode, void  *mkey)
                 spin_lock(&lli->lli_lock);
                 lli->lli_key_info = lkey; 
                 spin_unlock(&lli->lli_lock);
+                CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", 
+                       lli->lli_key_info->lk_ck.ck_key, 
+                       lli->lli_key_info->lk_ck.ck_mac, 
+                       inode->i_ino);
         } else {
                 lkey = lustre_key_get(lli->lli_key_info);
-                if (!IS_DECRYPTED(lkey->lk_flags)) {
-                        if (memcmp(&lkey->lk_ck, key, sizeof(*key))) {
-                                CWARN("already have key_info %p in ino %ld \n",
-                                      lli->lli_key_info, inode->i_ino);
-                        }
-                } else {
-                        spin_lock(&lli->lli_lock);
+                LASSERTF(!memcmp(lkey->lk_ck.ck_key, key->ck_key, KEY_SIZE), 
+                         "old key %s != new key %s\n", lkey->lk_ck.ck_key, 
+                         key->ck_key);
+                spin_lock(&lli->lli_lock);
+                if (memcmp(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE)){
+                        CDEBUG(D_INFO, "reset mac %s to %s ino %ld \n",
+                               lkey->lk_ck.ck_mac, key->ck_mac, inode->i_ino);
+                        memcpy(lkey->lk_ck.ck_mac, key->ck_mac, MAC_SIZE);
                         SET_UNDECRYPTED(lkey->lk_flags); 
-                        memcpy(&lkey->lk_ck, key, sizeof(*key));
-                        spin_unlock(&lli->lli_lock);
                 }
+                spin_unlock(&lli->lli_lock);
                 lustre_key_release(lkey);
         }
-        CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", 
-               lli->lli_key_info->lk_ck.ck_mac, 
-               lli->lli_key_info->lk_ck.ck_key, 
-               inode->i_ino);
         RETURN(0);
 }
 
@@ -567,10 +611,12 @@ int ll_mks_create_key(struct inode *inode, struct lookup_intent *it)
         LASSERT(it->d.fs_data != NULL); 
         lustre_data = (struct lustre_intent_data *)it->d.fs_data;
        
-        if (lustre_data->it_key) {
+        if (lustre_data->it_key)
                 OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
-        }
+
         OBD_ALLOC(crypto_key, sizeof(struct crypto_key));
+        if (!crypto_key)
+                RETURN(-ENOMEM);
        
         crypto_key->ck_type = MKS_TYPE;
         lustre_data->it_key = crypto_key; 
@@ -599,7 +645,6 @@ int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it)
         struct lustre_key *lkey =  NULL;
         struct posix_acl *acl = NULL;
         int rc = 0;
-        
         ENTRY;
  
         rc = ll_get_acl_key(inode, &acl, &lkey);
@@ -607,13 +652,14 @@ int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it)
                 GOTO(out, rc);      
         spin_lock(&lli->lli_lock); 
         SET_DECRYPTED(lkey->lk_flags); 
-        spin_unlock(&lli->lli_lock); 
+        spin_unlock(&lli->lli_lock);
+        EXIT;
 out:
         if (acl)
                 posix_acl_release(acl);
         if (lkey)
                 lustre_key_release(lkey); 
-        RETURN(rc);
+        return rc;
 }
 
 struct crypto_helper_ops ll_cmd_ops = { 
@@ -636,24 +682,26 @@ static int ll_register_cops(struct ll_crypto_info *llci, char *type,
         list_for_each_entry(tmp, list, clist) {
                 if (!strcmp(type, tmp->ctype)) {
                         CWARN("%s is already registered\n", type);
-                        rc = -EEXIST;
-                        GOTO(exit, rc); 
+                        RETURN(-EEXIST);
                 }
         }
         
         OBD_ALLOC(opi, sizeof(*opi));
+        if (!opi)
+                RETURN(-ENOMEM);
        
-        OBD_ALLOC(opi_name, strlen(type) + 1); 
+        OBD_ALLOC(opi_name, strlen(type) + 1);
+        if (!opi_name) {
+                OBD_FREE(opi, sizeof(*opi));
+                RETURN(-ENOMEM);
+        }
        
-        LASSERT(opi && opi_name);
-
         memcpy(opi_name, type, strlen(type));
 
         opi->ctype = opi_name;
         opi->cops = cops;
   
         list_add_tail(&opi->clist, list);
-exit:
         RETURN(rc);
 }
 
@@ -664,7 +712,6 @@ static int ll_init_sb_crypto(struct super_block *sb)
         ENTRY;
 
         OBD_ALLOC(llci, sizeof(*llci));
-        
         if (!llci)
                 RETURN(-ENOMEM);
 
@@ -682,6 +729,7 @@ static int ll_unregister_cops(struct ll_crypto_info *llci)
 {
         struct list_head *list = &llci->ll_cops_list;
         struct crypto_ops_item *tmp, *item;
+        ENTRY;
 
         list_for_each_entry_safe(item, tmp, list, clist) {       
                 list_del_init(&item->clist);       
@@ -742,10 +790,11 @@ int lustre_init_crypto(struct super_block *sb, char *gkc,
                 GOTO(out, rc);
         }
         ll_s2crpi(sb)->ll_gt_exp = class_conn2export(&gt_conn);
+        EXIT;
 out:
         if (rc)
                 lustre_destroy_crypto(sb); 
-        RETURN(rc);
+        return rc;
 }
 struct crypto_helper_ops *
 ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type)