aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/dir.c')
-rw-r--r--fs/afs/dir.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index d7697f6f3b7f..87368417e4d3 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/fs.h> 16#include <linux/fs.h>
17#include <linux/pagemap.h> 17#include <linux/pagemap.h>
18#include <linux/ctype.h>
18#include "internal.h" 19#include "internal.h"
19 20
20static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, 21static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
@@ -28,11 +29,13 @@ static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
28 29
29const struct file_operations afs_dir_file_operations = { 30const struct file_operations afs_dir_file_operations = {
30 .open = afs_dir_open, 31 .open = afs_dir_open,
32 .release = afs_release,
31 .readdir = afs_dir_readdir, 33 .readdir = afs_dir_readdir,
32}; 34};
33 35
34const struct inode_operations afs_dir_inode_operations = { 36const struct inode_operations afs_dir_inode_operations = {
35 .lookup = afs_dir_lookup, 37 .lookup = afs_dir_lookup,
38 .permission = afs_permission,
36 .getattr = afs_inode_getattr, 39 .getattr = afs_inode_getattr,
37#if 0 /* TODO */ 40#if 0 /* TODO */
38 .create = afs_dir_create, 41 .create = afs_dir_create,
@@ -169,13 +172,17 @@ static inline void afs_dir_put_page(struct page *page)
169/* 172/*
170 * get a page into the pagecache 173 * get a page into the pagecache
171 */ 174 */
172static struct page *afs_dir_get_page(struct inode *dir, unsigned long index) 175static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
176 struct key *key)
173{ 177{
174 struct page *page; 178 struct page *page;
179 struct file file = {
180 .private_data = key,
181 };
175 182
176 _enter("{%lu},%lu", dir->i_ino, index); 183 _enter("{%lu},%lu", dir->i_ino, index);
177 184
178 page = read_mapping_page(dir->i_mapping, index, NULL); 185 page = read_mapping_page(dir->i_mapping, index, &file);
179 if (!IS_ERR(page)) { 186 if (!IS_ERR(page)) {
180 wait_on_page_locked(page); 187 wait_on_page_locked(page);
181 kmap(page); 188 kmap(page);
@@ -207,8 +214,7 @@ static int afs_dir_open(struct inode *inode, struct file *file)
207 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags)) 214 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
208 return -ENOENT; 215 return -ENOENT;
209 216
210 _leave(" = 0"); 217 return afs_open(inode, file);
211 return 0;
212} 218}
213 219
214/* 220/*
@@ -311,7 +317,7 @@ static int afs_dir_iterate_block(unsigned *fpos,
311 * iterate through the data blob that lists the contents of an AFS directory 317 * iterate through the data blob that lists the contents of an AFS directory
312 */ 318 */
313static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, 319static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
314 filldir_t filldir) 320 filldir_t filldir, struct key *key)
315{ 321{
316 union afs_dir_block *dblock; 322 union afs_dir_block *dblock;
317 struct afs_dir_page *dbuf; 323 struct afs_dir_page *dbuf;
@@ -336,7 +342,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
336 blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1); 342 blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1);
337 343
338 /* fetch the appropriate page from the directory */ 344 /* fetch the appropriate page from the directory */
339 page = afs_dir_get_page(dir, blkoff / PAGE_SIZE); 345 page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key);
340 if (IS_ERR(page)) { 346 if (IS_ERR(page)) {
341 ret = PTR_ERR(page); 347 ret = PTR_ERR(page);
342 break; 348 break;
@@ -381,9 +387,11 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir)
381 _enter("{%Ld,{%lu}}", 387 _enter("{%Ld,{%lu}}",
382 file->f_pos, file->f_path.dentry->d_inode->i_ino); 388 file->f_pos, file->f_path.dentry->d_inode->i_ino);
383 389
390 ASSERT(file->private_data != NULL);
391
384 fpos = file->f_pos; 392 fpos = file->f_pos;
385 ret = afs_dir_iterate(file->f_path.dentry->d_inode, &fpos, 393 ret = afs_dir_iterate(file->f_path.dentry->d_inode, &fpos,
386 cookie, filldir); 394 cookie, filldir, file->private_data);
387 file->f_pos = fpos; 395 file->f_pos = fpos;
388 396
389 _leave(" = %d", ret); 397 _leave(" = %d", ret);
@@ -424,7 +432,7 @@ static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
424 * do a lookup in a directory 432 * do a lookup in a directory
425 */ 433 */
426static int afs_do_lookup(struct inode *dir, struct dentry *dentry, 434static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
427 struct afs_fid *fid) 435 struct afs_fid *fid, struct key *key)
428{ 436{
429 struct afs_dir_lookup_cookie cookie; 437 struct afs_dir_lookup_cookie cookie;
430 struct afs_super_info *as; 438 struct afs_super_info *as;
@@ -442,7 +450,8 @@ static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
442 cookie.found = 0; 450 cookie.found = 0;
443 451
444 fpos = 0; 452 fpos = 0;
445 ret = afs_dir_iterate(dir, &fpos, &cookie, afs_dir_lookup_filldir); 453 ret = afs_dir_iterate(dir, &fpos, &cookie, afs_dir_lookup_filldir,
454 key);
446 if (ret < 0) { 455 if (ret < 0) {
447 _leave(" = %d [iter]", ret); 456 _leave(" = %d [iter]", ret);
448 return ret; 457 return ret;
@@ -468,6 +477,7 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
468 struct afs_vnode *vnode; 477 struct afs_vnode *vnode;
469 struct afs_fid fid; 478 struct afs_fid fid;
470 struct inode *inode; 479 struct inode *inode;
480 struct key *key;
471 int ret; 481 int ret;
472 482
473 _enter("{%lu},%p{%s}", dir->i_ino, dentry, dentry->d_name.name); 483 _enter("{%lu},%p{%s}", dir->i_ino, dentry, dentry->d_name.name);
@@ -483,14 +493,22 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
483 return ERR_PTR(-ESTALE); 493 return ERR_PTR(-ESTALE);
484 } 494 }
485 495
486 ret = afs_do_lookup(dir, dentry, &fid); 496 key = afs_request_key(vnode->volume->cell);
497 if (IS_ERR(key)) {
498 _leave(" = %ld [key]", PTR_ERR(key));
499 return ERR_PTR(PTR_ERR(key));
500 }
501
502 ret = afs_do_lookup(dir, dentry, &fid, key);
487 if (ret < 0) { 503 if (ret < 0) {
504 key_put(key);
488 _leave(" = %d [do]", ret); 505 _leave(" = %d [do]", ret);
489 return ERR_PTR(ret); 506 return ERR_PTR(ret);
490 } 507 }
491 508
492 /* instantiate the dentry */ 509 /* instantiate the dentry */
493 inode = afs_iget(dir->i_sb, &fid); 510 inode = afs_iget(dir->i_sb, key, &fid);
511 key_put(key);
494 if (IS_ERR(inode)) { 512 if (IS_ERR(inode)) {
495 _leave(" = %ld", PTR_ERR(inode)); 513 _leave(" = %ld", PTR_ERR(inode));
496 return ERR_PTR(PTR_ERR(inode)); 514 return ERR_PTR(PTR_ERR(inode));
@@ -559,6 +577,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
559 struct afs_fid fid; 577 struct afs_fid fid;
560 struct dentry *parent; 578 struct dentry *parent;
561 struct inode *inode, *dir; 579 struct inode *inode, *dir;
580 struct key *key;
562 int ret; 581 int ret;
563 582
564 vnode = AFS_FS_I(dentry->d_inode); 583 vnode = AFS_FS_I(dentry->d_inode);
@@ -566,6 +585,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
566 _enter("{sb=%p n=%s fl=%lx},", 585 _enter("{sb=%p n=%s fl=%lx},",
567 dentry->d_sb, dentry->d_name.name, vnode->flags); 586 dentry->d_sb, dentry->d_name.name, vnode->flags);
568 587
588 key = afs_request_key(vnode->volume->cell);
589 if (IS_ERR(key))
590 key = NULL;
591
569 /* lock down the parent dentry so we can peer at it */ 592 /* lock down the parent dentry so we can peer at it */
570 parent = dget_parent(dentry); 593 parent = dget_parent(dentry);
571 594
@@ -595,7 +618,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
595 _debug("dir modified"); 618 _debug("dir modified");
596 619
597 /* search the directory for this vnode */ 620 /* search the directory for this vnode */
598 ret = afs_do_lookup(dir, dentry, &fid); 621 ret = afs_do_lookup(dir, dentry, &fid, key);
599 if (ret == -ENOENT) { 622 if (ret == -ENOENT) {
600 _debug("%s: dirent not found", dentry->d_name.name); 623 _debug("%s: dirent not found", dentry->d_name.name);
601 goto not_found; 624 goto not_found;
@@ -637,7 +660,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
637 test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) { 660 test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) {
638 _debug("%s: changed", dentry->d_name.name); 661 _debug("%s: changed", dentry->d_name.name);
639 set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); 662 set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
640 if (afs_vnode_fetch_status(vnode) < 0) { 663 if (afs_vnode_fetch_status(vnode, NULL, key) < 0) {
641 mutex_unlock(&vnode->cb_broken_lock); 664 mutex_unlock(&vnode->cb_broken_lock);
642 goto out_bad; 665 goto out_bad;
643 } 666 }
@@ -667,6 +690,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
667 690
668out_valid: 691out_valid:
669 dput(parent); 692 dput(parent);
693 key_put(key);
670 _leave(" = 1 [valid]"); 694 _leave(" = 1 [valid]");
671 return 1; 695 return 1;
672 696
@@ -688,6 +712,7 @@ out_bad:
688 shrink_dcache_parent(dentry); 712 shrink_dcache_parent(dentry);
689 d_drop(dentry); 713 d_drop(dentry);
690 dput(parent); 714 dput(parent);
715 key_put(key);
691 716
692 _leave(" = 0 [bad]"); 717 _leave(" = 0 [bad]");
693 return 0; 718 return 0;