diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-08-13 15:38:37 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-12-16 12:16:45 -0500 |
commit | 6e6b1bd1e739faf4fa259fc0d8bfcadea2493222 (patch) | |
tree | de20d84d0051852c4ff5b6200ab8c9bd9e932b75 /fs/namei.c | |
parent | 2dd6d1f41852bbb1f66d66b3634ddfdaeddcf9bc (diff) |
Kill cached_lookup() and real_lookup()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 153 |
1 files changed, 66 insertions, 87 deletions
diff --git a/fs/namei.c b/fs/namei.c index b2b22f244180..020bb082d0b9 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -412,26 +412,6 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
412 | } | 412 | } |
413 | 413 | ||
414 | /* | 414 | /* |
415 | * Internal lookup() using the new generic dcache. | ||
416 | * SMP-safe | ||
417 | */ | ||
418 | static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, struct nameidata *nd) | ||
419 | { | ||
420 | struct dentry * dentry = __d_lookup(parent, name); | ||
421 | |||
422 | /* lockess __d_lookup may fail due to concurrent d_move() | ||
423 | * in some unrelated directory, so try with d_lookup | ||
424 | */ | ||
425 | if (!dentry) | ||
426 | dentry = d_lookup(parent, name); | ||
427 | |||
428 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) | ||
429 | dentry = do_revalidate(dentry, nd); | ||
430 | |||
431 | return dentry; | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * Short-cut version of permission(), for calling by | 415 | * Short-cut version of permission(), for calling by |
436 | * path_walk(), when dcache lock is held. Combines parts | 416 | * path_walk(), when dcache lock is held. Combines parts |
437 | * of permission() and generic_permission(), and tests ONLY for | 417 | * of permission() and generic_permission(), and tests ONLY for |
@@ -463,70 +443,6 @@ ok: | |||
463 | return security_inode_permission(inode, MAY_EXEC); | 443 | return security_inode_permission(inode, MAY_EXEC); |
464 | } | 444 | } |
465 | 445 | ||
466 | /* | ||
467 | * This is called when everything else fails, and we actually have | ||
468 | * to go to the low-level filesystem to find out what we should do.. | ||
469 | * | ||
470 | * We get the directory semaphore, and after getting that we also | ||
471 | * make sure that nobody added the entry to the dcache in the meantime.. | ||
472 | * SMP-safe | ||
473 | */ | ||
474 | static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, struct nameidata *nd) | ||
475 | { | ||
476 | struct dentry * result; | ||
477 | struct inode *dir = parent->d_inode; | ||
478 | |||
479 | mutex_lock(&dir->i_mutex); | ||
480 | /* | ||
481 | * First re-do the cached lookup just in case it was created | ||
482 | * while we waited for the directory semaphore.. | ||
483 | * | ||
484 | * FIXME! This could use version numbering or similar to | ||
485 | * avoid unnecessary cache lookups. | ||
486 | * | ||
487 | * The "dcache_lock" is purely to protect the RCU list walker | ||
488 | * from concurrent renames at this point (we mustn't get false | ||
489 | * negatives from the RCU list walk here, unlike the optimistic | ||
490 | * fast walk). | ||
491 | * | ||
492 | * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup | ||
493 | */ | ||
494 | result = d_lookup(parent, name); | ||
495 | if (!result) { | ||
496 | struct dentry *dentry; | ||
497 | |||
498 | /* Don't create child dentry for a dead directory. */ | ||
499 | result = ERR_PTR(-ENOENT); | ||
500 | if (IS_DEADDIR(dir)) | ||
501 | goto out_unlock; | ||
502 | |||
503 | dentry = d_alloc(parent, name); | ||
504 | result = ERR_PTR(-ENOMEM); | ||
505 | if (dentry) { | ||
506 | result = dir->i_op->lookup(dir, dentry, nd); | ||
507 | if (result) | ||
508 | dput(dentry); | ||
509 | else | ||
510 | result = dentry; | ||
511 | } | ||
512 | out_unlock: | ||
513 | mutex_unlock(&dir->i_mutex); | ||
514 | return result; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * Uhhuh! Nasty case: the cache was re-populated while | ||
519 | * we waited on the semaphore. Need to revalidate. | ||
520 | */ | ||
521 | mutex_unlock(&dir->i_mutex); | ||
522 | if (result->d_op && result->d_op->d_revalidate) { | ||
523 | result = do_revalidate(result, nd); | ||
524 | if (!result) | ||
525 | result = ERR_PTR(-ENOENT); | ||
526 | } | ||
527 | return result; | ||
528 | } | ||
529 | |||
530 | static __always_inline void set_root(struct nameidata *nd) | 446 | static __always_inline void set_root(struct nameidata *nd) |
531 | { | 447 | { |
532 | if (!nd->root.mnt) { | 448 | if (!nd->root.mnt) { |
@@ -767,7 +683,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
767 | struct path *path) | 683 | struct path *path) |
768 | { | 684 | { |
769 | struct vfsmount *mnt = nd->path.mnt; | 685 | struct vfsmount *mnt = nd->path.mnt; |
770 | struct dentry *dentry; | 686 | struct dentry *dentry, *parent; |
687 | struct inode *dir; | ||
771 | /* | 688 | /* |
772 | * See if the low-level filesystem might want | 689 | * See if the low-level filesystem might want |
773 | * to use its own hash.. | 690 | * to use its own hash.. |
@@ -790,7 +707,59 @@ done: | |||
790 | return 0; | 707 | return 0; |
791 | 708 | ||
792 | need_lookup: | 709 | need_lookup: |
793 | dentry = real_lookup(nd->path.dentry, name, nd); | 710 | parent = nd->path.dentry; |
711 | dir = parent->d_inode; | ||
712 | |||
713 | mutex_lock(&dir->i_mutex); | ||
714 | /* | ||
715 | * First re-do the cached lookup just in case it was created | ||
716 | * while we waited for the directory semaphore.. | ||
717 | * | ||
718 | * FIXME! This could use version numbering or similar to | ||
719 | * avoid unnecessary cache lookups. | ||
720 | * | ||
721 | * The "dcache_lock" is purely to protect the RCU list walker | ||
722 | * from concurrent renames at this point (we mustn't get false | ||
723 | * negatives from the RCU list walk here, unlike the optimistic | ||
724 | * fast walk). | ||
725 | * | ||
726 | * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup | ||
727 | */ | ||
728 | dentry = d_lookup(parent, name); | ||
729 | if (!dentry) { | ||
730 | struct dentry *new; | ||
731 | |||
732 | /* Don't create child dentry for a dead directory. */ | ||
733 | dentry = ERR_PTR(-ENOENT); | ||
734 | if (IS_DEADDIR(dir)) | ||
735 | goto out_unlock; | ||
736 | |||
737 | new = d_alloc(parent, name); | ||
738 | dentry = ERR_PTR(-ENOMEM); | ||
739 | if (new) { | ||
740 | dentry = dir->i_op->lookup(dir, new, nd); | ||
741 | if (dentry) | ||
742 | dput(new); | ||
743 | else | ||
744 | dentry = new; | ||
745 | } | ||
746 | out_unlock: | ||
747 | mutex_unlock(&dir->i_mutex); | ||
748 | if (IS_ERR(dentry)) | ||
749 | goto fail; | ||
750 | goto done; | ||
751 | } | ||
752 | |||
753 | /* | ||
754 | * Uhhuh! Nasty case: the cache was re-populated while | ||
755 | * we waited on the semaphore. Need to revalidate. | ||
756 | */ | ||
757 | mutex_unlock(&dir->i_mutex); | ||
758 | if (dentry->d_op && dentry->d_op->d_revalidate) { | ||
759 | dentry = do_revalidate(dentry, nd); | ||
760 | if (!dentry) | ||
761 | dentry = ERR_PTR(-ENOENT); | ||
762 | } | ||
794 | if (IS_ERR(dentry)) | 763 | if (IS_ERR(dentry)) |
795 | goto fail; | 764 | goto fail; |
796 | goto done; | 765 | goto done; |
@@ -1144,7 +1113,17 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1144 | goto out; | 1113 | goto out; |
1145 | } | 1114 | } |
1146 | 1115 | ||
1147 | dentry = cached_lookup(base, name, nd); | 1116 | dentry = __d_lookup(base, name); |
1117 | |||
1118 | /* lockess __d_lookup may fail due to concurrent d_move() | ||
1119 | * in some unrelated directory, so try with d_lookup | ||
1120 | */ | ||
1121 | if (!dentry) | ||
1122 | dentry = d_lookup(base, name); | ||
1123 | |||
1124 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) | ||
1125 | dentry = do_revalidate(dentry, nd); | ||
1126 | |||
1148 | if (!dentry) { | 1127 | if (!dentry) { |
1149 | struct dentry *new; | 1128 | struct dentry *new; |
1150 | 1129 | ||