diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-25 11:57:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-25 11:57:47 -0400 |
commit | 7ed7fe5e82c9fc8473974fbd7389d169b8f17c77 (patch) | |
tree | ff6ff57c88c887133f1585473e7d74981d0dc88c /fs/namei.c | |
parent | a4083c9271e0a697278e089f2c0b9a95363ada0a (diff) | |
parent | a02f76c34d7d6d30b63ac64a8b34dea68593e8da (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
[PATCH] get stack footprint of pathname resolution back to relative sanity
[PATCH] double iput() on failure exit in hugetlb
[PATCH] double dput() on failure exit in tiny-shmem
[PATCH] fix up new filp allocators
[PATCH] check for null vfsmount in dentry_open()
[PATCH] reiserfs: eliminate private use of struct file in xattr
[PATCH] sanitize hppfs
hppfs pass vfsmount to dentry_open()
[PATCH] restore export of do_kern_mount()
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/fs/namei.c b/fs/namei.c index 6b7a0eef4090..8cf9bb9c2fc0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -106,7 +106,7 @@ | |||
106 | * any extra contention... | 106 | * any extra contention... |
107 | */ | 107 | */ |
108 | 108 | ||
109 | static int link_path_walk(const char *name, struct nameidata *nd); | 109 | static int __link_path_walk(const char *name, struct nameidata *nd); |
110 | 110 | ||
111 | /* In order to reduce some races, while at the same time doing additional | 111 | /* In order to reduce some races, while at the same time doing additional |
112 | * checking and hopefully speeding things up, we copy filenames to the | 112 | * checking and hopefully speeding things up, we copy filenames to the |
@@ -563,6 +563,37 @@ walk_init_root(const char *name, struct nameidata *nd) | |||
563 | return 1; | 563 | return 1; |
564 | } | 564 | } |
565 | 565 | ||
566 | /* | ||
567 | * Wrapper to retry pathname resolution whenever the underlying | ||
568 | * file system returns an ESTALE. | ||
569 | * | ||
570 | * Retry the whole path once, forcing real lookup requests | ||
571 | * instead of relying on the dcache. | ||
572 | */ | ||
573 | static __always_inline int link_path_walk(const char *name, struct nameidata *nd) | ||
574 | { | ||
575 | struct path save = nd->path; | ||
576 | int result; | ||
577 | |||
578 | /* make sure the stuff we saved doesn't go away */ | ||
579 | dget(save.dentry); | ||
580 | mntget(save.mnt); | ||
581 | |||
582 | result = __link_path_walk(name, nd); | ||
583 | if (result == -ESTALE) { | ||
584 | /* nd->path had been dropped */ | ||
585 | nd->path = save; | ||
586 | dget(nd->path.dentry); | ||
587 | mntget(nd->path.mnt); | ||
588 | nd->flags |= LOOKUP_REVAL; | ||
589 | result = __link_path_walk(name, nd); | ||
590 | } | ||
591 | |||
592 | path_put(&save); | ||
593 | |||
594 | return result; | ||
595 | } | ||
596 | |||
566 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) | 597 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) |
567 | { | 598 | { |
568 | int res = 0; | 599 | int res = 0; |
@@ -1020,36 +1051,6 @@ return_err: | |||
1020 | return err; | 1051 | return err; |
1021 | } | 1052 | } |
1022 | 1053 | ||
1023 | /* | ||
1024 | * Wrapper to retry pathname resolution whenever the underlying | ||
1025 | * file system returns an ESTALE. | ||
1026 | * | ||
1027 | * Retry the whole path once, forcing real lookup requests | ||
1028 | * instead of relying on the dcache. | ||
1029 | */ | ||
1030 | static int link_path_walk(const char *name, struct nameidata *nd) | ||
1031 | { | ||
1032 | struct nameidata save = *nd; | ||
1033 | int result; | ||
1034 | |||
1035 | /* make sure the stuff we saved doesn't go away */ | ||
1036 | dget(save.path.dentry); | ||
1037 | mntget(save.path.mnt); | ||
1038 | |||
1039 | result = __link_path_walk(name, nd); | ||
1040 | if (result == -ESTALE) { | ||
1041 | *nd = save; | ||
1042 | dget(nd->path.dentry); | ||
1043 | mntget(nd->path.mnt); | ||
1044 | nd->flags |= LOOKUP_REVAL; | ||
1045 | result = __link_path_walk(name, nd); | ||
1046 | } | ||
1047 | |||
1048 | path_put(&save.path); | ||
1049 | |||
1050 | return result; | ||
1051 | } | ||
1052 | |||
1053 | static int path_walk(const char *name, struct nameidata *nd) | 1054 | static int path_walk(const char *name, struct nameidata *nd) |
1054 | { | 1055 | { |
1055 | current->total_link_count = 0; | 1056 | current->total_link_count = 0; |