diff options
author | David Howells <dhowells@redhat.com> | 2007-04-27 00:59:35 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-04-27 00:59:35 +0200 |
commit | 260a980317dac80182dd76140cf67c6e81d6d3dd (patch) | |
tree | 84f3e919fd33be56aad4fc57f5cb844df1a6b952 /fs/afs/security.c | |
parent | [AFS]: Implement the CB.InitCallBackState3 operation. (diff) | |
download | linux-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.c | 31 |
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; } |