summaryrefslogtreecommitdiffstats
path: root/fs/afs/security.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2007-04-27 00:59:35 +0200
committerDavid S. Miller <davem@davemloft.net>2007-04-27 00:59:35 +0200
commit260a980317dac80182dd76140cf67c6e81d6d3dd (patch)
tree84f3e919fd33be56aad4fc57f5cb844df1a6b952 /fs/afs/security.c
parent[AFS]: Implement the CB.InitCallBackState3 operation. (diff)
downloadlinux-260a980317dac80182dd76140cf67c6e81d6d3dd.tar.xz
linux-260a980317dac80182dd76140cf67c6e81d6d3dd.zip
[AFS]: Add "directory write" support.
Add support for the create, link, symlink, unlink, mkdir, rmdir and rename VFS operations to the in-kernel AFS filesystem. Also: (1) Fix dentry and inode revalidation. d_revalidate should only look at state of the dentry. Revalidation of the contents of an inode pointed to by a dentry is now separate. (2) Fix afs_lookup() to hash negative dentries as well as positive ones. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/afs/security.c')
-rw-r--r--fs/afs/security.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/fs/afs/security.c b/fs/afs/security.c
index cbdd7f7162fa..f9f424d80458 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -92,7 +92,7 @@ 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));
}
@@ -288,7 +288,8 @@ int afs_permission(struct inode *inode, int mask, struct nameidata *nd)
struct key *key;
int ret;
- _enter("{%x:%x},%x,", vnode->fid.vid, vnode->fid.vnode, mask);
+ _enter("{{%x:%x},%lx},%x,",
+ vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask);
key = afs_request_key(vnode->volume->cell);
if (IS_ERR(key)) {
@@ -296,13 +297,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 +343,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;
}