]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - security/integrity/ima/ima_iint.c
IMA: explicit IMA i_flag to remove global lock on inode_delete
[net-next-2.6.git] / security / integrity / ima / ima_iint.c
index 969a1c1cb333ebf156767a9aed8f2cae3413fef4..c442e47b67853099e776c4e5b95dd3fa321183ae 100644 (file)
@@ -59,6 +59,9 @@ struct ima_iint_cache *ima_iint_find(struct inode *inode)
 {
        struct ima_iint_cache *iint;
 
+       if (!IS_IMA(inode))
+               return NULL;
+
        spin_lock(&ima_iint_lock);
        iint = __ima_iint_find(inode);
        spin_unlock(&ima_iint_lock);
@@ -91,6 +94,7 @@ int ima_inode_alloc(struct inode *inode)
        new_iint->inode = inode;
        new_node = &new_iint->rb_node;
 
+       mutex_lock(&inode->i_mutex); /* i_flags */
        spin_lock(&ima_iint_lock);
 
        p = &ima_iint_tree.rb_node;
@@ -107,14 +111,17 @@ int ima_inode_alloc(struct inode *inode)
                        goto out_err;
        }
 
+       inode->i_flags |= S_IMA;
        rb_link_node(new_node, parent, p);
        rb_insert_color(new_node, &ima_iint_tree);
 
        spin_unlock(&ima_iint_lock);
+       mutex_unlock(&inode->i_mutex); /* i_flags */
 
        return 0;
 out_err:
        spin_unlock(&ima_iint_lock);
+       mutex_unlock(&inode->i_mutex); /* i_flags */
        iint_free(new_iint);
 
        return rc;
@@ -135,15 +142,14 @@ void ima_inode_free(struct inode *inode)
 
        inode->i_readcount = 0;
 
+       if (!IS_IMA(inode))
+               return;
+
        spin_lock(&ima_iint_lock);
        iint = __ima_iint_find(inode);
-       if (iint)
-               rb_erase(&iint->rb_node, &ima_iint_tree);
+       rb_erase(&iint->rb_node, &ima_iint_tree);
        spin_unlock(&ima_iint_lock);
 
-       if (!iint)
-               return;
-
        iint_free(iint);
 }