kcore: add _text to KCORE_TEXT
[safe/jmp/linux-2.6] / fs / afs / security.c
index cbdd7f7..bb4ed14 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/ctype.h>
+#include <linux/sched.h>
 #include <keys/rxrpc-type.h>
 #include "internal.h"
 
@@ -92,9 +93,9 @@ static struct afs_vnode *afs_get_auth_inode(struct afs_vnode *vnode,
                ASSERT(auth_inode != NULL);
        } else {
                auth_inode = afs_iget(vnode->vfs_inode.i_sb, key,
-                                     &vnode->status.parent);
+                                     &vnode->status.parent, NULL, NULL);
                if (IS_ERR(auth_inode))
-                       return ERR_PTR(PTR_ERR(auth_inode));
+                       return ERR_CAST(auth_inode);
        }
 
        auth_vnode = AFS_FS_I(auth_inode);
@@ -109,7 +110,7 @@ void afs_clear_permits(struct afs_vnode *vnode)
 {
        struct afs_permits *permits;
 
-       _enter("{%x}", vnode->fid.vnode);
+       _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
 
        mutex_lock(&vnode->permits_lock);
        permits = vnode->permits;
@@ -132,7 +133,8 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, long acl_order)
        struct afs_vnode *auth_vnode;
        int count, loop;
 
-       _enter("{%x},%x,%lx", vnode->fid.vnode, key_serial(key), acl_order);
+       _enter("{%x:%u},%x,%lx",
+              vnode->fid.vid, vnode->fid.vnode, key_serial(key), acl_order);
 
        auth_vnode = afs_get_auth_inode(vnode, key);
        if (IS_ERR(auth_vnode)) {
@@ -187,8 +189,9 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, long acl_order)
        if (!permits)
                goto out_unlock;
 
-       memcpy(permits->permits, xpermits->permits,
-              count * sizeof(struct afs_permit));
+       if (xpermits)
+               memcpy(permits->permits, xpermits->permits,
+                       count * sizeof(struct afs_permit));
 
        _debug("key %x access %x",
               key_serial(key), vnode->status.caller_access);
@@ -220,7 +223,8 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key,
        bool valid;
        int loop, ret;
 
-       _enter("");
+       _enter("{%x:%u},%x",
+              vnode->fid.vid, vnode->fid.vnode, key_serial(key));
 
        auth_vnode = afs_get_auth_inode(vnode, key);
        if (IS_ERR(auth_vnode)) {
@@ -268,9 +272,9 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key,
                        _leave(" = %d", ret);
                        return ret;
                }
+               *_access = vnode->status.caller_access;
        }
 
-       *_access = vnode->status.caller_access;
        iput(&auth_vnode->vfs_inode);
        _leave(" = 0 [access %x]", *_access);
        return 0;
@@ -281,14 +285,15 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key,
  * - AFS ACLs are attached to directories only, and a file is controlled by its
  *   parent directory's ACL
  */
-int afs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int afs_permission(struct inode *inode, int mask)
 {
        struct afs_vnode *vnode = AFS_FS_I(inode);
-       afs_access_t access;
+       afs_access_t uninitialized_var(access);
        struct key *key;
        int ret;
 
-       _enter("{%x:%x},%x,", vnode->fid.vid, vnode->fid.vnode, mask);
+       _enter("{{%x:%u},%lx},%x,",
+              vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask);
 
        key = afs_request_key(vnode->volume->cell);
        if (IS_ERR(key)) {
@@ -296,13 +301,19 @@ int afs_permission(struct inode *inode, int mask, struct nameidata *nd)
                return PTR_ERR(key);
        }
 
+       /* if the promise has expired, we need to check the server again */
+       if (!vnode->cb_promised) {
+               _debug("not promised");
+               ret = afs_vnode_fetch_status(vnode, NULL, key);
+               if (ret < 0)
+                       goto error;
+               _debug("new promise [fl=%lx]", vnode->flags);
+       }
+
        /* check the permits to see if we've got one yet */
        ret = afs_check_permit(vnode, key, &access);
-       if (ret < 0) {
-               key_put(key);
-               _leave(" = %d [check]", ret);
-               return ret;
-       }
+       if (ret < 0)
+               goto error;
 
        /* interpret the access mask */
        _debug("REQ %x ACC %x on %s",
@@ -336,10 +347,14 @@ int afs_permission(struct inode *inode, int mask, struct nameidata *nd)
        }
 
        key_put(key);
-       return generic_permission(inode, mask, NULL);
+       ret = generic_permission(inode, mask, NULL);
+       _leave(" = %d", ret);
+       return ret;
 
 permission_denied:
+       ret = -EACCES;
+error:
        key_put(key);
-       _leave(" = -EACCES");
-       return -EACCES;
+       _leave(" = %d", ret);
+       return ret;
 }