diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2009-08-08 17:41:57 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2009-12-16 12:16:43 -0500 |
commit | 6de88d72927dc85297b3075024487313c4ba3a2e (patch) | |
tree | 278609d97c5635bb3922634b274689739fbf09d6 /fs/namei.c | |
parent | 258fa99905f704afed1a43f195bc5235a56fb895 (diff) |
kill __link_path_walk()/link_path_walk() distinction
put retry logics into path_walk() and do_filp_open()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/fs/namei.c b/fs/namei.c index 30c61c298b4c..89e380583ab8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -108,8 +108,6 @@ | |||
108 | * any extra contention... | 108 | * any extra contention... |
109 | */ | 109 | */ |
110 | 110 | ||
111 | static int __link_path_walk(const char *name, struct nameidata *nd); | ||
112 | |||
113 | /* 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 |
114 | * checking and hopefully speeding things up, we copy filenames to the | 112 | * checking and hopefully speeding things up, we copy filenames to the |
115 | * kernel data space before using them.. | 113 | * kernel data space before using them.. |
@@ -529,35 +527,6 @@ out_unlock: | |||
529 | return result; | 527 | return result; |
530 | } | 528 | } |
531 | 529 | ||
532 | /* | ||
533 | * Wrapper to retry pathname resolution whenever the underlying | ||
534 | * file system returns an ESTALE. | ||
535 | * | ||
536 | * Retry the whole path once, forcing real lookup requests | ||
537 | * instead of relying on the dcache. | ||
538 | */ | ||
539 | static __always_inline int link_path_walk(const char *name, struct nameidata *nd) | ||
540 | { | ||
541 | struct path save = nd->path; | ||
542 | int result; | ||
543 | |||
544 | /* make sure the stuff we saved doesn't go away */ | ||
545 | path_get(&save); | ||
546 | |||
547 | result = __link_path_walk(name, nd); | ||
548 | if (result == -ESTALE) { | ||
549 | /* nd->path had been dropped */ | ||
550 | nd->path = save; | ||
551 | path_get(&nd->path); | ||
552 | nd->flags |= LOOKUP_REVAL; | ||
553 | result = __link_path_walk(name, nd); | ||
554 | } | ||
555 | |||
556 | path_put(&save); | ||
557 | |||
558 | return result; | ||
559 | } | ||
560 | |||
561 | static __always_inline void set_root(struct nameidata *nd) | 530 | static __always_inline void set_root(struct nameidata *nd) |
562 | { | 531 | { |
563 | if (!nd->root.mnt) { | 532 | if (!nd->root.mnt) { |
@@ -569,6 +538,8 @@ static __always_inline void set_root(struct nameidata *nd) | |||
569 | } | 538 | } |
570 | } | 539 | } |
571 | 540 | ||
541 | static int link_path_walk(const char *, struct nameidata *); | ||
542 | |||
572 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) | 543 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) |
573 | { | 544 | { |
574 | int res = 0; | 545 | int res = 0; |
@@ -834,7 +805,7 @@ fail: | |||
834 | * Returns 0 and nd will have valid dentry and mnt on success. | 805 | * Returns 0 and nd will have valid dentry and mnt on success. |
835 | * Returns error and drops reference to input namei data on failure. | 806 | * Returns error and drops reference to input namei data on failure. |
836 | */ | 807 | */ |
837 | static int __link_path_walk(const char *name, struct nameidata *nd) | 808 | static int link_path_walk(const char *name, struct nameidata *nd) |
838 | { | 809 | { |
839 | struct path next; | 810 | struct path next; |
840 | struct inode *inode; | 811 | struct inode *inode; |
@@ -1016,8 +987,27 @@ return_err: | |||
1016 | 987 | ||
1017 | static int path_walk(const char *name, struct nameidata *nd) | 988 | static int path_walk(const char *name, struct nameidata *nd) |
1018 | { | 989 | { |
990 | struct path save = nd->path; | ||
991 | int result; | ||
992 | |||
1019 | current->total_link_count = 0; | 993 | current->total_link_count = 0; |
1020 | return link_path_walk(name, nd); | 994 | |
995 | /* make sure the stuff we saved doesn't go away */ | ||
996 | path_get(&save); | ||
997 | |||
998 | result = link_path_walk(name, nd); | ||
999 | if (result == -ESTALE) { | ||
1000 | /* nd->path had been dropped */ | ||
1001 | current->total_link_count = 0; | ||
1002 | nd->path = save; | ||
1003 | path_get(&nd->path); | ||
1004 | nd->flags |= LOOKUP_REVAL; | ||
1005 | result = link_path_walk(name, nd); | ||
1006 | } | ||
1007 | |||
1008 | path_put(&save); | ||
1009 | |||
1010 | return result; | ||
1021 | } | 1011 | } |
1022 | 1012 | ||
1023 | static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd) | 1013 | static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd) |
@@ -1649,7 +1639,7 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
1649 | struct file *filp; | 1639 | struct file *filp; |
1650 | struct nameidata nd; | 1640 | struct nameidata nd; |
1651 | int error; | 1641 | int error; |
1652 | struct path path; | 1642 | struct path path, save; |
1653 | struct dentry *dir; | 1643 | struct dentry *dir; |
1654 | int count = 0; | 1644 | int count = 0; |
1655 | int will_write; | 1645 | int will_write; |
@@ -1862,7 +1852,17 @@ do_link: | |||
1862 | error = security_inode_follow_link(path.dentry, &nd); | 1852 | error = security_inode_follow_link(path.dentry, &nd); |
1863 | if (error) | 1853 | if (error) |
1864 | goto exit_dput; | 1854 | goto exit_dput; |
1855 | save = nd.path; | ||
1856 | path_get(&save); | ||
1865 | error = __do_follow_link(&path, &nd); | 1857 | error = __do_follow_link(&path, &nd); |
1858 | if (error == -ESTALE) { | ||
1859 | /* nd.path had been dropped */ | ||
1860 | nd.path = save; | ||
1861 | path_get(&nd.path); | ||
1862 | nd.flags |= LOOKUP_REVAL; | ||
1863 | error = __do_follow_link(&path, &nd); | ||
1864 | } | ||
1865 | path_put(&save); | ||
1866 | path_put(&path); | 1866 | path_put(&path); |
1867 | if (error) { | 1867 | if (error) { |
1868 | /* Does someone understand code flow here? Or it is only | 1868 | /* Does someone understand code flow here? Or it is only |