diff options
author | David Howells <dhowells@redhat.com> | 2007-04-26 18:59:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-04-26 18:59:35 -0400 |
commit | 260a980317dac80182dd76140cf67c6e81d6d3dd (patch) | |
tree | 84f3e919fd33be56aad4fc57f5cb844df1a6b952 /fs/afs/security.c | |
parent | c35eccb1f614954b10cba3f74b7c301993b2f42e (diff) |
[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, | |||
92 | ASSERT(auth_inode != NULL); | 92 | ASSERT(auth_inode != NULL); |
93 | } else { | 93 | } else { |
94 | auth_inode = afs_iget(vnode->vfs_inode.i_sb, key, | 94 | auth_inode = afs_iget(vnode->vfs_inode.i_sb, key, |
95 | &vnode->status.parent); | 95 | &vnode->status.parent, NULL, NULL); |
96 | if (IS_ERR(auth_inode)) | 96 | if (IS_ERR(auth_inode)) |
97 | return ERR_PTR(PTR_ERR(auth_inode)); | 97 | return ERR_PTR(PTR_ERR(auth_inode)); |
98 | } | 98 | } |
@@ -288,7 +288,8 @@ int afs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
288 | struct key *key; | 288 | struct key *key; |
289 | int ret; | 289 | int ret; |
290 | 290 | ||
291 | _enter("{%x:%x},%x,", vnode->fid.vid, vnode->fid.vnode, mask); | 291 | _enter("{{%x:%x},%lx},%x,", |
292 | vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask); | ||
292 | 293 | ||
293 | key = afs_request_key(vnode->volume->cell); | 294 | key = afs_request_key(vnode->volume->cell); |
294 | if (IS_ERR(key)) { | 295 | if (IS_ERR(key)) { |
@@ -296,13 +297,19 @@ int afs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
296 | return PTR_ERR(key); | 297 | return PTR_ERR(key); |
297 | } | 298 | } |
298 | 299 | ||
300 | /* if the promise has expired, we need to check the server again */ | ||
301 | if (!vnode->cb_promised) { | ||
302 | _debug("not promised"); | ||
303 | ret = afs_vnode_fetch_status(vnode, NULL, key); | ||
304 | if (ret < 0) | ||
305 | goto error; | ||
306 | _debug("new promise [fl=%lx]", vnode->flags); | ||
307 | } | ||
308 | |||
299 | /* check the permits to see if we've got one yet */ | 309 | /* check the permits to see if we've got one yet */ |
300 | ret = afs_check_permit(vnode, key, &access); | 310 | ret = afs_check_permit(vnode, key, &access); |
301 | if (ret < 0) { | 311 | if (ret < 0) |
302 | key_put(key); | 312 | goto error; |
303 | _leave(" = %d [check]", ret); | ||
304 | return ret; | ||
305 | } | ||
306 | 313 | ||
307 | /* interpret the access mask */ | 314 | /* interpret the access mask */ |
308 | _debug("REQ %x ACC %x on %s", | 315 | _debug("REQ %x ACC %x on %s", |
@@ -336,10 +343,14 @@ int afs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
336 | } | 343 | } |
337 | 344 | ||
338 | key_put(key); | 345 | key_put(key); |
339 | return generic_permission(inode, mask, NULL); | 346 | ret = generic_permission(inode, mask, NULL); |
347 | _leave(" = %d", ret); | ||
348 | return ret; | ||
340 | 349 | ||
341 | permission_denied: | 350 | permission_denied: |
351 | ret = -EACCES; | ||
352 | error: | ||
342 | key_put(key); | 353 | key_put(key); |
343 | _leave(" = -EACCES"); | 354 | _leave(" = %d", ret); |
344 | return -EACCES; | 355 | return ret; |
345 | } | 356 | } |